Skip to content

Commit 6def304

Browse files
committed
Return ErrorOr from getSection.
This also improves the logic of what is an error: * getSection(uint_32): only return an error if the index is out of bounds. The index 0 corresponds to a perfectly valid entry. * getSection(Elf_Sym): Returns null for symbols that normally don't have sections and error for out of bound indexes. In many places this just moves the report_fatal_error up the stack, but those can then be fixed in smaller patches. llvm-svn: 241156
1 parent 6ae400d commit 6def304

File tree

9 files changed

+144
-75
lines changed

9 files changed

+144
-75
lines changed

llvm/include/llvm/Object/ELF.h

+34-20
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ class ELFFile {
357357
uintX_t getStringTableIndex() const;
358358
ELF::Elf64_Word getExtendedSymbolTableIndex(const Elf_Sym *symb) const;
359359
const Elf_Ehdr *getHeader() const { return Header; }
360-
const Elf_Shdr *getSection(const Elf_Sym *symb) const;
361-
const Elf_Shdr *getSection(uint32_t Index) const;
360+
ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *symb) const;
361+
ErrorOr<const Elf_Shdr *> getSection(uint32_t Index) const;
362362
const Elf_Sym *getSymbol(uint32_t index) const;
363363

364364
ErrorOr<StringRef> getStaticSymbolName(const Elf_Sym *Symb) const;
@@ -465,11 +465,12 @@ ELFFile<ELFT>::getExtendedSymbolTableIndex(const Elf_Sym *symb) const {
465465
}
466466

467467
template <class ELFT>
468-
const typename ELFFile<ELFT>::Elf_Shdr *
468+
ErrorOr<const typename ELFFile<ELFT>::Elf_Shdr *>
469469
ELFFile<ELFT>::getSection(const Elf_Sym *symb) const {
470-
if (symb->st_shndx == ELF::SHN_XINDEX)
470+
uint32_t Index = symb->st_shndx;
471+
if (Index == ELF::SHN_XINDEX)
471472
return getSection(ExtendedSymbolTable.lookup(symb));
472-
if (symb->st_shndx >= ELF::SHN_LORESERVE)
473+
if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
473474
return nullptr;
474475
return getSection(symb->st_shndx);
475476
}
@@ -532,7 +533,10 @@ std::pair<const typename ELFFile<ELFT>::Elf_Shdr *,
532533
ELFFile<ELFT>::getRelocationSymbol(const Elf_Shdr *Sec, const RelT *Rel) const {
533534
if (!Sec->sh_link)
534535
return std::make_pair(nullptr, nullptr);
535-
const Elf_Shdr *SymTable = getSection(Sec->sh_link);
536+
ErrorOr<const Elf_Shdr *> SymTableOrErr = getSection(Sec->sh_link);
537+
if (std::error_code EC = SymTableOrErr.getError())
538+
report_fatal_error(EC.message());
539+
const Elf_Shdr *SymTable = *SymTableOrErr;
536540
return std::make_pair(
537541
SymTable, getEntry<Elf_Sym>(SymTable, Rel->getSymbol(isMips64EL())));
538542
}
@@ -615,7 +619,10 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
615619
return;
616620
}
617621
dot_symtab_sec = &Sec;
618-
ErrorOr<StringRef> SymtabOrErr = getStringTable(getSection(Sec.sh_link));
622+
ErrorOr<const Elf_Shdr *> SectionOrErr = getSection(Sec.sh_link);
623+
if ((EC = SectionOrErr.getError()))
624+
return;
625+
ErrorOr<StringRef> SymtabOrErr = getStringTable(*SectionOrErr);
619626
if ((EC = SymtabOrErr.getError()))
620627
return;
621628
DotStrtab = *SymtabOrErr;
@@ -629,7 +636,10 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
629636
DynSymRegion.Addr = base() + Sec.sh_offset;
630637
DynSymRegion.Size = Sec.sh_size;
631638
DynSymRegion.EntSize = Sec.sh_entsize;
632-
const Elf_Shdr *DynStr = getSection(Sec.sh_link);
639+
ErrorOr<const Elf_Shdr *> DynStrOrErr = getSection(Sec.sh_link);
640+
if ((EC = DynStrOrErr.getError()))
641+
return;
642+
const Elf_Shdr *DynStr = *DynStrOrErr;
633643
DynStrRegion.Addr = base() + DynStr->sh_offset;
634644
DynStrRegion.Size = DynStr->sh_size;
635645
DynStrRegion.EntSize = DynStr->sh_entsize;
@@ -673,8 +683,11 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
673683
}
674684

675685
// Get string table sections.
676-
ErrorOr<StringRef> SymtabOrErr =
677-
getStringTable(getSection(getStringTableIndex()));
686+
ErrorOr<const Elf_Shdr *> StrTabSecOrErr = getSection(getStringTableIndex());
687+
if ((EC = StrTabSecOrErr.getError()))
688+
return;
689+
690+
ErrorOr<StringRef> SymtabOrErr = getStringTable(*StrTabSecOrErr);
678691
if ((EC = SymtabOrErr.getError()))
679692
return;
680693
DotShstrtab = *SymtabOrErr;
@@ -825,7 +838,10 @@ StringRef ELFFile<ELFT>::getLoadName() const {
825838
template <class ELFT>
826839
template <typename T>
827840
const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const {
828-
return getEntry<T>(getSection(Section), Entry);
841+
ErrorOr<const Elf_Shdr *> Sec = getSection(Section);
842+
if (std::error_code EC = Sec.getError())
843+
report_fatal_error(EC.message());
844+
return getEntry<T>(*Sec, Entry);
829845
}
830846

831847
template <class ELFT>
@@ -837,17 +853,15 @@ const T *ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
837853
}
838854

839855
template <class ELFT>
840-
const typename ELFFile<ELFT>::Elf_Shdr *
841-
ELFFile<ELFT>::getSection(uint32_t index) const {
842-
if (index == 0)
843-
return nullptr;
844-
if (!SectionHeaderTable || index >= getNumSections())
845-
// FIXME: Proper error handling.
846-
report_fatal_error("Invalid section index!");
856+
ErrorOr<const typename ELFFile<ELFT>::Elf_Shdr *>
857+
ELFFile<ELFT>::getSection(uint32_t Index) const {
858+
assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
859+
if (Index >= getNumSections())
860+
return object_error::invalid_section_index;
847861

848862
return reinterpret_cast<const Elf_Shdr *>(
849-
reinterpret_cast<const char *>(SectionHeaderTable)
850-
+ (index * Header->e_shentsize));
863+
reinterpret_cast<const char *>(SectionHeaderTable) +
864+
(Index * Header->e_shentsize));
851865
}
852866

853867
template <class ELFT>

llvm/include/llvm/Object/ELFObjectFile.h

+31-14
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,10 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
241241

242242
/// \brief Get the relocation section that contains \a Rel.
243243
const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
244-
return EF.getSection(Rel.d.a);
244+
ErrorOr<const Elf_Shdr *> Sec = EF.getSection(Rel.d.a);
245+
if (std::error_code EC = Sec.getError())
246+
report_fatal_error(EC.message());
247+
return *Sec;
245248
}
246249

247250
const Elf_Rel *getRel(DataRefImpl Rel) const;
@@ -406,8 +409,11 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
406409
const Elf_Ehdr *Header = EF.getHeader();
407410

408411
if (Header->e_type == ELF::ET_REL) {
409-
const typename ELFFile<ELFT>::Elf_Shdr * Section = EF.getSection(ESym);
410-
if (Section != nullptr)
412+
ErrorOr<const Elf_Shdr *> SectionOrErr = EF.getSection(ESym);
413+
if (std::error_code EC = SectionOrErr.getError())
414+
return EC;
415+
const Elf_Shdr *Section = *SectionOrErr;
416+
if (Section)
411417
Result += Section->sh_addr;
412418
}
413419

@@ -511,14 +517,17 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
511517
template <class ELFT>
512518
section_iterator
513519
ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym) const {
514-
const Elf_Shdr *ESec = EF.getSection(ESym);
520+
ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym);
521+
if (std::error_code EC = ESecOrErr.getError())
522+
report_fatal_error(EC.message());
523+
524+
const Elf_Shdr *ESec = *ESecOrErr;
515525
if (!ESec)
516526
return section_end();
517-
else {
518-
DataRefImpl Sec;
519-
Sec.p = reinterpret_cast<intptr_t>(ESec);
520-
return section_iterator(SectionRef(Sec, this));
521-
}
527+
528+
DataRefImpl Sec;
529+
Sec.p = reinterpret_cast<intptr_t>(ESec);
530+
return section_iterator(SectionRef(Sec, this));
522531
}
523532

524533
template <class ELFT>
@@ -629,8 +638,10 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
629638
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
630639
return section_end();
631640

632-
const Elf_Shdr *R = EF.getSection(EShdr->sh_info);
633-
return section_iterator(SectionRef(toDRI(R), this));
641+
ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info);
642+
if (std::error_code EC = R.getError())
643+
report_fatal_error(EC.message());
644+
return section_iterator(SectionRef(toDRI(*R), this));
634645
}
635646

636647
// Relocations
@@ -651,7 +662,10 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
651662
if (!symbolIdx)
652663
return symbol_end();
653664

654-
const Elf_Shdr *SymSec = EF.getSection(sec->sh_link);
665+
ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(sec->sh_link);
666+
if (std::error_code EC = SymSecOrErr.getError())
667+
report_fatal_error(EC.message());
668+
const Elf_Shdr *SymSec = *SymSecOrErr;
655669

656670
DataRefImpl SymbolData;
657671
switch (SymSec->sh_type) {
@@ -676,8 +690,11 @@ ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel) const {
676690

677691
if (Header->e_type == ELF::ET_REL) {
678692
const Elf_Shdr *RelocationSec = getRelSection(Rel);
679-
const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info);
680-
return ROffset + RelocatedSec->sh_addr;
693+
ErrorOr<const Elf_Shdr *> RelocatedSec =
694+
EF.getSection(RelocationSec->sh_info);
695+
if (std::error_code EC = RelocatedSec.getError())
696+
return EC;
697+
return ROffset + (*RelocatedSec)->sh_addr;
681698
}
682699
return ROffset;
683700
}

llvm/include/llvm/Object/Error.h

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ enum class object_error {
2828
parse_failed,
2929
unexpected_eof,
3030
string_table_non_null_end,
31+
invalid_section_index,
3132
bitcode_section_not_found,
3233
macho_small_load_command,
3334
macho_load_segment_too_many_sections,

llvm/lib/Object/Error.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ std::string _object_error_category::message(int EV) const {
4343
return "The end of the file was unexpectedly encountered";
4444
case object_error::string_table_non_null_end:
4545
return "String table must end with a null terminator";
46+
case object_error::invalid_section_index:
47+
return "Invalid section index";
4648
case object_error::bitcode_section_not_found:
4749
return "Bitcode section not found in object file";
4850
case object_error::macho_small_load_command:

llvm/test/Object/invalid.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ INVALID-SYM-SIZE: Invalid symbol size
4040

4141
RUN: not llvm-readobj -t %p/Inputs/invalid-section-index.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-INDEX %s
4242

43-
INVALID-SECTION-INDEX: Invalid section index!
43+
INVALID-SECTION-INDEX: Invalid section index
4444

4545
RUN: not llvm-readobj -s %p/Inputs/invalid-section-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-SIZE %s
4646
INVALID-SECTION-SIZE: Invalid section header size

llvm/tools/llvm-objdump/llvm-objdump.cpp

+18-8
Original file line numberDiff line numberDiff line change
@@ -319,20 +319,28 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
319319
typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
320320
const ELFFile<ELFT> &EF = *Obj->getELFFile();
321321

322-
const Elf_Shdr *sec = EF.getSection(Rel.d.a);
323-
const Elf_Shdr *SymTab = EF.getSection(sec->sh_link);
322+
ErrorOr<const Elf_Shdr *> SecOrErr = EF.getSection(Rel.d.a);
323+
if (std::error_code EC = SecOrErr.getError())
324+
return EC;
325+
const Elf_Shdr *Sec = *SecOrErr;
326+
ErrorOr<const Elf_Shdr *> SymTabOrErr = EF.getSection(Sec->sh_link);
327+
if (std::error_code EC = SymTabOrErr.getError())
328+
return EC;
329+
const Elf_Shdr *SymTab = *SymTabOrErr;
324330
assert(SymTab->sh_type == ELF::SHT_SYMTAB ||
325331
SymTab->sh_type == ELF::SHT_DYNSYM);
326-
const Elf_Shdr *StrTabSec = EF.getSection(SymTab->sh_link);
327-
ErrorOr<StringRef> StrTabOrErr = EF.getStringTable(StrTabSec);
332+
ErrorOr<const Elf_Shdr *> StrTabSec = EF.getSection(SymTab->sh_link);
333+
if (std::error_code EC = StrTabSec.getError())
334+
return EC;
335+
ErrorOr<StringRef> StrTabOrErr = EF.getStringTable(*StrTabSec);
328336
if (std::error_code EC = StrTabOrErr.getError())
329337
return EC;
330338
StringRef StrTab = *StrTabOrErr;
331339
uint8_t type;
332340
StringRef res;
333341
int64_t addend = 0;
334342
uint16_t symbol_index = 0;
335-
switch (sec->sh_type) {
343+
switch (Sec->sh_type) {
336344
default:
337345
return object_error::parse_failed;
338346
case ELF::SHT_REL: {
@@ -349,11 +357,13 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
349357
}
350358
}
351359
const Elf_Sym *symb =
352-
EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index);
360+
EF.template getEntry<Elf_Sym>(Sec->sh_link, symbol_index);
353361
StringRef Target;
354-
const Elf_Shdr *SymSec = EF.getSection(symb);
362+
ErrorOr<const Elf_Shdr *> SymSec = EF.getSection(symb);
363+
if (std::error_code EC = SymSec.getError())
364+
return EC;
355365
if (symb->getType() == ELF::STT_SECTION) {
356-
ErrorOr<StringRef> SecName = EF.getSectionName(SymSec);
366+
ErrorOr<StringRef> SecName = EF.getSectionName(*SymSec);
357367
if (std::error_code EC = SecName.getError())
358368
return EC;
359369
Target = *SecName;

llvm/tools/llvm-readobj/ARMEHABIPrinter.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,10 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
377377
std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol =
378378
ELF->getRelocationSymbol(&Sec, &RelA);
379379

380-
return ELF->getSection(Symbol.second);
380+
ErrorOr<const Elf_Shdr *> Ret = ELF->getSection(Symbol.second);
381+
if (std::error_code EC = Ret.getError())
382+
report_fatal_error(EC.message());
383+
return *Ret;
381384
}
382385
}
383386
}

llvm/tools/llvm-readobj/ELFDumper.cpp

+19-11
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
162162
else {
163163
if (SectionIndex == SHN_XINDEX)
164164
SectionIndex = Obj.getExtendedSymbolTableIndex(&*Symbol);
165-
const typename ELFO::Elf_Shdr *Sec = Obj.getSection(SectionIndex);
166-
SectionName = errorOrDefault(Obj.getSectionName(Sec));
165+
ErrorOr<const typename ELFO::Elf_Shdr *> Sec = Obj.getSection(SectionIndex);
166+
if (!error(Sec.getError()))
167+
SectionName = errorOrDefault(Obj.getSectionName(*Sec));
167168
}
168169
}
169170

@@ -644,7 +645,10 @@ void ELFDumper<ELFT>::printSections() {
644645
if (opts::SectionSymbols) {
645646
ListScope D(W, "Symbols");
646647
for (const typename ELFO::Elf_Sym &Sym : Obj->symbols()) {
647-
if (Obj->getSection(&Sym) == &Sec)
648+
ErrorOr<const Elf_Shdr *> SymSec = Obj->getSection(&Sym);
649+
if (!SymSec)
650+
continue;
651+
if (*SymSec == &Sec)
648652
printSymbol(&Sym, false);
649653
}
650654
}
@@ -746,16 +750,20 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec,
746750
std::pair<const Elf_Shdr *, const Elf_Sym *> Sym =
747751
Obj->getRelocationSymbol(Sec, &Rel);
748752
if (Sym.second && Sym.second->getType() == ELF::STT_SECTION) {
749-
const Elf_Shdr *Sec = Obj->getSection(Sym.second);
750-
ErrorOr<StringRef> SecName = Obj->getSectionName(Sec);
751-
if (SecName)
752-
TargetName = SecName.get();
753+
ErrorOr<const Elf_Shdr *> Sec = Obj->getSection(Sym.second);
754+
if (!error(Sec.getError())) {
755+
ErrorOr<StringRef> SecName = Obj->getSectionName(*Sec);
756+
if (SecName)
757+
TargetName = SecName.get();
758+
}
753759
} else if (Sym.first) {
754760
const Elf_Shdr *SymTable = Sym.first;
755-
const Elf_Shdr *StrTableSec = Obj->getSection(SymTable->sh_link);
756-
ErrorOr<StringRef> StrTableOrErr = Obj->getStringTable(StrTableSec);
757-
if (!error(StrTableOrErr.getError()))
758-
TargetName = errorOrDefault(Sym.second->getName(*StrTableOrErr));
761+
ErrorOr<const Elf_Shdr *> StrTableSec = Obj->getSection(SymTable->sh_link);
762+
if (!error(StrTableSec.getError())) {
763+
ErrorOr<StringRef> StrTableOrErr = Obj->getStringTable(*StrTableSec);
764+
if (!error(StrTableOrErr.getError()))
765+
TargetName = errorOrDefault(Sym.second->getName(*StrTableOrErr));
766+
}
759767
}
760768

761769
if (opts::ExpandRelocs) {

0 commit comments

Comments
 (0)