Skip to content

Commit 2bf01dc

Browse files
author
George Rimar
committed
[llvm/Object] - Make ELFObjectFile::getRelocatedSection return Expected<section_iterator>
It returns just a section_iterator currently and have a report_fatal_error call inside. This change adds a way to return errors and handle them on caller sides. The patch also changes/improves current users and adds test cases. Differential revision: https://reviews.llvm.org/D69167 llvm-svn: 375408
1 parent bac5f6b commit 2bf01dc

File tree

14 files changed

+168
-27
lines changed

14 files changed

+168
-27
lines changed

llvm/include/llvm/Object/ELFObjectFile.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,8 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
288288
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
289289
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
290290
std::vector<SectionRef> dynamic_relocation_sections() const override;
291-
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
291+
Expected<section_iterator>
292+
getRelocatedSection(DataRefImpl Sec) const override;
292293

293294
void moveRelocationNext(DataRefImpl &Rel) const override;
294295
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
@@ -841,7 +842,7 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
841842
}
842843

843844
template <class ELFT>
844-
section_iterator
845+
Expected<section_iterator>
845846
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
846847
if (EF.getHeader()->e_type != ELF::ET_REL)
847848
return section_end();
@@ -851,10 +852,10 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
851852
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
852853
return section_end();
853854

854-
auto R = EF.getSection(EShdr->sh_info);
855-
if (!R)
856-
report_fatal_error(errorToErrorCode(R.takeError()).message());
857-
return section_iterator(SectionRef(toDRI(*R), this));
855+
Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
856+
if (!SecOrErr)
857+
return SecOrErr.takeError();
858+
return section_iterator(SectionRef(toDRI(*SecOrErr), this));
858859
}
859860

860861
// Relocations

llvm/include/llvm/Object/ObjectFile.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class SectionRef {
130130
iterator_range<relocation_iterator> relocations() const {
131131
return make_range(relocation_begin(), relocation_end());
132132
}
133-
section_iterator getRelocatedSection() const;
133+
Expected<section_iterator> getRelocatedSection() const;
134134

135135
DataRefImpl getRawDataRefImpl() const;
136136
const ObjectFile *getObject() const;
@@ -272,7 +272,7 @@ class ObjectFile : public SymbolicFile {
272272
virtual bool isBerkeleyData(DataRefImpl Sec) const;
273273
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
274274
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
275-
virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
275+
virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
276276

277277
// Same as above for RelocationRef.
278278
friend class RelocationRef;
@@ -501,7 +501,7 @@ inline relocation_iterator SectionRef::relocation_end() const {
501501
return OwningObject->section_rel_end(SectionPimpl);
502502
}
503503

504-
inline section_iterator SectionRef::getRelocatedSection() const {
504+
inline Expected<section_iterator> SectionRef::getRelocatedSection() const {
505505
return OwningObject->getRelocatedSection(SectionPimpl);
506506
}
507507

llvm/lib/DebugInfo/DWARF/DWARFContext.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -1527,10 +1527,19 @@ class DWARFObjInMemory final : public DWARFObject {
15271527
continue;
15281528

15291529
StringRef Data;
1530-
section_iterator RelocatedSection = Section.getRelocatedSection();
1530+
Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
1531+
if (!SecOrErr) {
1532+
ErrorPolicy EP = HandleError(createError(
1533+
"failed to get relocated section: ", SecOrErr.takeError()));
1534+
if (EP == ErrorPolicy::Halt)
1535+
return;
1536+
continue;
1537+
}
1538+
15311539
// Try to obtain an already relocated version of this section.
15321540
// Else use the unrelocated section from the object file. We'll have to
15331541
// apply relocations ourselves later.
1542+
section_iterator RelocatedSection = *SecOrErr;
15341543
if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
15351544
Expected<StringRef> E = Section.getContents();
15361545
if (E)

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,12 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
348348
for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
349349
SI != SE; ++SI) {
350350
StubMap Stubs;
351-
section_iterator RelocatedSection = SI->getRelocatedSection();
352351

352+
Expected<section_iterator> RelSecOrErr = SI->getRelocatedSection();
353+
if (!RelSecOrErr)
354+
return RelSecOrErr.takeError();
355+
356+
section_iterator RelocatedSection = *RelSecOrErr;
353357
if (RelocatedSection == SE)
354358
continue;
355359

@@ -648,7 +652,12 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj,
648652
unsigned StubBufSize = 0;
649653
for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
650654
SI != SE; ++SI) {
651-
section_iterator RelSecI = SI->getRelocatedSection();
655+
656+
Expected<section_iterator> RelSecOrErr = SI->getRelocatedSection();
657+
if (!RelSecOrErr)
658+
report_fatal_error(toString(RelSecOrErr.takeError()));
659+
660+
section_iterator RelSecI = *RelSecOrErr;
652661
if (!(RelSecI == Section))
653662
continue;
654663

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,12 @@ Error RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,
606606
// .opd entries
607607
for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
608608
si != se; ++si) {
609-
section_iterator RelSecI = si->getRelocatedSection();
609+
610+
Expected<section_iterator> RelSecOrErr = si->getRelocatedSection();
611+
if (!RelSecOrErr)
612+
report_fatal_error(toString(RelSecOrErr.takeError()));
613+
614+
section_iterator RelSecI = *RelSecOrErr;
610615
if (RelSecI == Obj.section_end())
611616
continue;
612617

@@ -1871,7 +1876,12 @@ Error RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
18711876
for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
18721877
SI != SE; ++SI) {
18731878
if (SI->relocation_begin() != SI->relocation_end()) {
1874-
section_iterator RelocatedSection = SI->getRelocatedSection();
1879+
Expected<section_iterator> RelSecOrErr = SI->getRelocatedSection();
1880+
if (!RelSecOrErr)
1881+
return make_error<RuntimeDyldError>(
1882+
toString(RelSecOrErr.takeError()));
1883+
1884+
section_iterator RelocatedSection = *RelSecOrErr;
18751885
ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
18761886
assert (i != SectionMap.end());
18771887
SectionToGOTMap[i->second] = GOTSectionID;

llvm/lib/Object/ObjectFile.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {
8484
return isSectionData(Sec);
8585
}
8686

87-
section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
87+
Expected<section_iterator>
88+
ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
8889
return section_iterator(SectionRef(Sec, this));
8990
}
9091

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Check we report an error when trying to dump an object
2+
## which has a relocation section that has a broken sh_info
3+
## field, which is larger than the number of sections.
4+
5+
# RUN: yaml2obj %s -o %t
6+
# RUN: not llvm-cxxdump %t 2>&1 | FileCheck %s
7+
# CHECK: error: reading file: invalid section index: 255
8+
9+
--- !ELF
10+
FileHeader:
11+
Class: ELFCLASS64
12+
Data: ELFDATA2LSB
13+
Type: ET_REL
14+
Machine: EM_X86_64
15+
Sections:
16+
- Name: .rela.foo
17+
Type: SHT_RELA
18+
Link: 0
19+
Info: 0xFF
20+
Relocations: []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Check we report an error if the relocated section identified by the
2+
## sh_info field of a relocation section is invalid.
3+
4+
# RUN: yaml2obj %s -o %t
5+
# RUN: llvm-dwarfdump %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR
6+
7+
# ERR: error: failed to get relocated section: invalid section index: 255
8+
9+
--- !ELF
10+
FileHeader:
11+
Class: ELFCLASS64
12+
Data: ELFDATA2LSB
13+
Type: ET_REL
14+
Machine: EM_X86_64
15+
Sections:
16+
- Name: .rela.debug_info
17+
Type: SHT_RELA
18+
Link: 0
19+
Info: 0xFF
20+
Relocations: []

llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs.test

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
## Show that --disassemble + --reloc prints relocations inline and does not dump
22
## the relocation sections.
33

4-
# RUN: yaml2obj %s -o %t.o
5-
# RUN: llvm-objdump %t.o -d -r | FileCheck %s --implicit-check-not="RELOCATION RECORDS"
4+
# RUN: yaml2obj %s --docnum=1 -o %t1.o
5+
# RUN: llvm-objdump %t1.o -d -r | FileCheck %s --implicit-check-not="RELOCATION RECORDS"
66

77
# CHECK: 0: e8 00 00 00 00 callq 0 <.text+0x5>
88
# CHECK-NEXT: 0000000000000001: R_X86_64_PC32 foo-4
@@ -40,3 +40,24 @@ Sections:
4040
Symbols:
4141
- Name: foo
4242
- Name: bar
43+
44+
## Check we report an error if the relocated section identified by the
45+
## sh_info field of a relocation section is invalid.
46+
47+
# RUN: yaml2obj %s --docnum=2 -o %t2.o
48+
# RUN: not llvm-objdump %t2.o --disassemble --reloc 2>&1 | FileCheck %s -DFILE=%t2.o --check-prefix=ERR
49+
50+
# ERR: error: '[[FILE]]': section (1): failed to get a relocated section: invalid section index: 255
51+
52+
--- !ELF
53+
FileHeader:
54+
Class: ELFCLASS64
55+
Data: ELFDATA2LSB
56+
Type: ET_REL
57+
Machine: EM_X86_64
58+
Sections:
59+
- Name: .rela.debug_info
60+
Type: SHT_RELA
61+
Link: 0
62+
Info: 0xFF
63+
Relocations: []

llvm/test/tools/llvm-objdump/relocations-elf.test

+3-3
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ Symbols:
7474
## Check we report an error if the relocated section identified by the
7575
## sh_info field of a relocation section is invalid.
7676
# RUN: yaml2obj --docnum=2 %s > %t2
77-
# RUN: not llvm-objdump --reloc %t2 2>&1 | FileCheck %s --check-prefix=ERR
78-
# ERR: LLVM ERROR: Invalid data was encountered while parsing the file
77+
# RUN: not llvm-objdump --reloc %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=ERR
78+
# ERR: error: '[[FILE]]': section (1): unable to get a relocation target: invalid section index: 255
7979

8080
--- !ELF
8181
FileHeader:
@@ -86,7 +86,7 @@ FileHeader:
8686
Sections:
8787
- Name: .rela.foo
8888
Type: SHT_RELA
89-
Info: 0x255
89+
Info: 0xFF
9090
Relocations:
9191
- Offset: 0x1
9292
Type: R_X86_64_NONE

llvm/test/tools/llvm-readobj/stack-sizes.test

+23
Original file line numberDiff line numberDiff line change
@@ -641,3 +641,26 @@ Sections:
641641
Relocations:
642642
- Offset: 0
643643
Type: R_X86_64_64
644+
645+
## Check we report an error when dumping stack sizes if the relocated section
646+
## identified by the sh_info field is invalid. Here sh_info value is larger than
647+
## the number of sections.
648+
649+
# RUN: yaml2obj --docnum=13 %s > %t18
650+
# RUN: not llvm-readelf --stack-sizes %t18 2>&1 | FileCheck %s -DFILE=%t18 --check-prefix=INVALID-TARGET
651+
# RUN: not llvm-readobj --stack-sizes %t18 2>&1 | FileCheck %s -DFILE=%t18 --check-prefix=INVALID-TARGET
652+
653+
# INVALID-TARGET: error: '[[FILE]]': .rela.stack_sizes: failed to get a relocated section: invalid section index: 255
654+
655+
--- !ELF
656+
FileHeader:
657+
Class: ELFCLASS32
658+
Data: ELFDATA2MSB
659+
Type: ET_REL
660+
Machine: EM_X86_64
661+
Sections:
662+
- Name: .rela.stack_sizes
663+
Type: SHT_RELA
664+
Link: 0
665+
Info: 0xFF
666+
Relocations: []

llvm/tools/llvm-cxxdump/llvm-cxxdump.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,11 @@ static void dumpCXXData(const ObjectFile *Obj) {
174174

175175
SectionRelocMap.clear();
176176
for (const SectionRef &Section : Obj->sections()) {
177-
section_iterator Sec2 = Section.getRelocatedSection();
177+
Expected<section_iterator> ErrOrSec = Section.getRelocatedSection();
178+
if (!ErrOrSec)
179+
error(ErrOrSec.takeError());
180+
181+
section_iterator Sec2 = *ErrOrSec;
178182
if (Sec2 != Obj->section_end())
179183
SectionRelocMap[*Sec2].push_back(Section);
180184
}

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

+19-4
Original file line numberDiff line numberDiff line change
@@ -993,8 +993,17 @@ static size_t countSkippableZeroBytes(ArrayRef<uint8_t> Buf) {
993993
static std::map<SectionRef, std::vector<RelocationRef>>
994994
getRelocsMap(object::ObjectFile const &Obj) {
995995
std::map<SectionRef, std::vector<RelocationRef>> Ret;
996+
uint64_t I = (uint64_t)-1;
996997
for (SectionRef Sec : Obj.sections()) {
997-
section_iterator Relocated = Sec.getRelocatedSection();
998+
++I;
999+
Expected<section_iterator> RelocatedOrErr = Sec.getRelocatedSection();
1000+
if (!RelocatedOrErr)
1001+
reportError(Obj.getFileName(),
1002+
"section (" + Twine(I) +
1003+
"): failed to get a relocated section: " +
1004+
toString(RelocatedOrErr.takeError()));
1005+
1006+
section_iterator Relocated = *RelocatedOrErr;
9981007
if (Relocated == Obj.section_end() || !checkSectionFilter(*Relocated).Keep)
9991008
continue;
10001009
std::vector<RelocationRef> &V = Ret[*Relocated];
@@ -1606,11 +1615,17 @@ void printRelocations(const ObjectFile *Obj) {
16061615
// sections. Usually, there is an only one relocation section for
16071616
// each relocated section.
16081617
MapVector<SectionRef, std::vector<SectionRef>> SecToRelSec;
1609-
for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1618+
uint64_t Ndx;
1619+
for (const SectionRef &Section : ToolSectionFilter(*Obj, &Ndx)) {
16101620
if (Section.relocation_begin() == Section.relocation_end())
16111621
continue;
1612-
const SectionRef TargetSec = *Section.getRelocatedSection();
1613-
SecToRelSec[TargetSec].push_back(Section);
1622+
Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
1623+
if (!SecOrErr)
1624+
reportError(Obj->getFileName(),
1625+
"section (" + Twine(Ndx) +
1626+
"): unable to get a relocation target: " +
1627+
toString(SecOrErr.takeError()));
1628+
SecToRelSec[**SecOrErr].push_back(Section);
16141629
}
16151630

16161631
for (std::pair<SectionRef, std::vector<SectionRef>> &P : SecToRelSec) {

llvm/tools/llvm-readobj/ELFDumper.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -4894,8 +4894,16 @@ void DumpStyle<ELFT>::printRelocatableStackSizes(
48944894
if (SectionType != ELF::SHT_RELA && SectionType != ELF::SHT_REL)
48954895
continue;
48964896

4897-
SectionRef Contents = *Sec.getRelocatedSection();
4898-
const Elf_Shdr *ContentsSec = Obj->getSection(Contents.getRawDataRefImpl());
4897+
Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection();
4898+
if (!RelSecOrErr)
4899+
reportError(createStringError(object_error::parse_failed,
4900+
"%s: failed to get a relocated section: %s",
4901+
SectionName.data(),
4902+
toString(RelSecOrErr.takeError()).c_str()),
4903+
Obj->getFileName());
4904+
4905+
const Elf_Shdr *ContentsSec =
4906+
Obj->getSection((*RelSecOrErr)->getRawDataRefImpl());
48994907
Expected<StringRef> ContentsSectionNameOrErr =
49004908
EF->getSectionName(ContentsSec);
49014909
if (!ContentsSectionNameOrErr) {

0 commit comments

Comments
 (0)