mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[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
This commit is contained in:
parent
7b931c8b77
commit
9459104c4d
@ -288,7 +288,8 @@ protected:
|
||||
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
|
||||
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
|
||||
std::vector<SectionRef> dynamic_relocation_sections() const override;
|
||||
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
|
||||
Expected<section_iterator>
|
||||
getRelocatedSection(DataRefImpl Sec) const override;
|
||||
|
||||
void moveRelocationNext(DataRefImpl &Rel) const override;
|
||||
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
|
||||
@ -841,7 +842,7 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
section_iterator
|
||||
Expected<section_iterator>
|
||||
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
|
||||
if (EF.getHeader()->e_type != ELF::ET_REL)
|
||||
return section_end();
|
||||
@ -851,10 +852,10 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
|
||||
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
|
||||
return section_end();
|
||||
|
||||
auto R = EF.getSection(EShdr->sh_info);
|
||||
if (!R)
|
||||
report_fatal_error(errorToErrorCode(R.takeError()).message());
|
||||
return section_iterator(SectionRef(toDRI(*R), this));
|
||||
Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
return section_iterator(SectionRef(toDRI(*SecOrErr), this));
|
||||
}
|
||||
|
||||
// Relocations
|
||||
|
@ -130,7 +130,7 @@ public:
|
||||
iterator_range<relocation_iterator> relocations() const {
|
||||
return make_range(relocation_begin(), relocation_end());
|
||||
}
|
||||
section_iterator getRelocatedSection() const;
|
||||
Expected<section_iterator> getRelocatedSection() const;
|
||||
|
||||
DataRefImpl getRawDataRefImpl() const;
|
||||
const ObjectFile *getObject() const;
|
||||
@ -272,7 +272,7 @@ protected:
|
||||
virtual bool isBerkeleyData(DataRefImpl Sec) const;
|
||||
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
|
||||
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
|
||||
virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
|
||||
virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
|
||||
|
||||
// Same as above for RelocationRef.
|
||||
friend class RelocationRef;
|
||||
@ -501,7 +501,7 @@ inline relocation_iterator SectionRef::relocation_end() const {
|
||||
return OwningObject->section_rel_end(SectionPimpl);
|
||||
}
|
||||
|
||||
inline section_iterator SectionRef::getRelocatedSection() const {
|
||||
inline Expected<section_iterator> SectionRef::getRelocatedSection() const {
|
||||
return OwningObject->getRelocatedSection(SectionPimpl);
|
||||
}
|
||||
|
||||
|
@ -1527,10 +1527,19 @@ public:
|
||||
continue;
|
||||
|
||||
StringRef Data;
|
||||
section_iterator RelocatedSection = Section.getRelocatedSection();
|
||||
Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
|
||||
if (!SecOrErr) {
|
||||
ErrorPolicy EP = HandleError(createError(
|
||||
"failed to get relocated section: ", SecOrErr.takeError()));
|
||||
if (EP == ErrorPolicy::Halt)
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to obtain an already relocated version of this section.
|
||||
// Else use the unrelocated section from the object file. We'll have to
|
||||
// apply relocations ourselves later.
|
||||
section_iterator RelocatedSection = *SecOrErr;
|
||||
if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
|
||||
Expected<StringRef> E = Section.getContents();
|
||||
if (E)
|
||||
|
@ -348,8 +348,12 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
|
||||
for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
|
||||
SI != SE; ++SI) {
|
||||
StubMap Stubs;
|
||||
section_iterator RelocatedSection = SI->getRelocatedSection();
|
||||
|
||||
Expected<section_iterator> RelSecOrErr = SI->getRelocatedSection();
|
||||
if (!RelSecOrErr)
|
||||
return RelSecOrErr.takeError();
|
||||
|
||||
section_iterator RelocatedSection = *RelSecOrErr;
|
||||
if (RelocatedSection == SE)
|
||||
continue;
|
||||
|
||||
@ -648,7 +652,12 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj,
|
||||
unsigned StubBufSize = 0;
|
||||
for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
|
||||
SI != SE; ++SI) {
|
||||
section_iterator RelSecI = SI->getRelocatedSection();
|
||||
|
||||
Expected<section_iterator> RelSecOrErr = SI->getRelocatedSection();
|
||||
if (!RelSecOrErr)
|
||||
report_fatal_error(toString(RelSecOrErr.takeError()));
|
||||
|
||||
section_iterator RelSecI = *RelSecOrErr;
|
||||
if (!(RelSecI == Section))
|
||||
continue;
|
||||
|
||||
|
@ -606,7 +606,12 @@ Error RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,
|
||||
// .opd entries
|
||||
for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
|
||||
si != se; ++si) {
|
||||
section_iterator RelSecI = si->getRelocatedSection();
|
||||
|
||||
Expected<section_iterator> RelSecOrErr = si->getRelocatedSection();
|
||||
if (!RelSecOrErr)
|
||||
report_fatal_error(toString(RelSecOrErr.takeError()));
|
||||
|
||||
section_iterator RelSecI = *RelSecOrErr;
|
||||
if (RelSecI == Obj.section_end())
|
||||
continue;
|
||||
|
||||
@ -1871,7 +1876,12 @@ Error RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
|
||||
for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
|
||||
SI != SE; ++SI) {
|
||||
if (SI->relocation_begin() != SI->relocation_end()) {
|
||||
section_iterator RelocatedSection = SI->getRelocatedSection();
|
||||
Expected<section_iterator> RelSecOrErr = SI->getRelocatedSection();
|
||||
if (!RelSecOrErr)
|
||||
return make_error<RuntimeDyldError>(
|
||||
toString(RelSecOrErr.takeError()));
|
||||
|
||||
section_iterator RelocatedSection = *RelSecOrErr;
|
||||
ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
|
||||
assert (i != SectionMap.end());
|
||||
SectionToGOTMap[i->second] = GOTSectionID;
|
||||
|
@ -84,7 +84,8 @@ bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {
|
||||
return isSectionData(Sec);
|
||||
}
|
||||
|
||||
section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
|
||||
Expected<section_iterator>
|
||||
ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
|
||||
return section_iterator(SectionRef(Sec, this));
|
||||
}
|
||||
|
||||
|
20
test/tools/llvm-cxxdump/broken-reloc-sec.test
Normal file
20
test/tools/llvm-cxxdump/broken-reloc-sec.test
Normal file
@ -0,0 +1,20 @@
|
||||
## Check we report an error when trying to dump an object
|
||||
## which has a relocation section that has a broken sh_info
|
||||
## field, which is larger than the number of sections.
|
||||
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: not llvm-cxxdump %t 2>&1 | FileCheck %s
|
||||
# CHECK: error: reading file: invalid section index: 255
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .rela.foo
|
||||
Type: SHT_RELA
|
||||
Link: 0
|
||||
Info: 0xFF
|
||||
Relocations: []
|
20
test/tools/llvm-dwarfdump/elf-broken-reloc-target.yaml
Normal file
20
test/tools/llvm-dwarfdump/elf-broken-reloc-target.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
## Check we report an error if the relocated section identified by the
|
||||
## sh_info field of a relocation section is invalid.
|
||||
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-dwarfdump %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR
|
||||
|
||||
# ERR: error: failed to get relocated section: invalid section index: 255
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .rela.debug_info
|
||||
Type: SHT_RELA
|
||||
Link: 0
|
||||
Info: 0xFF
|
||||
Relocations: []
|
@ -1,8 +1,8 @@
|
||||
## Show that --disassemble + --reloc prints relocations inline and does not dump
|
||||
## the relocation sections.
|
||||
|
||||
# RUN: yaml2obj %s -o %t.o
|
||||
# RUN: llvm-objdump %t.o -d -r | FileCheck %s --implicit-check-not="RELOCATION RECORDS"
|
||||
# RUN: yaml2obj %s --docnum=1 -o %t1.o
|
||||
# RUN: llvm-objdump %t1.o -d -r | FileCheck %s --implicit-check-not="RELOCATION RECORDS"
|
||||
|
||||
# CHECK: 0: e8 00 00 00 00 callq 0 <.text+0x5>
|
||||
# CHECK-NEXT: 0000000000000001: R_X86_64_PC32 foo-4
|
||||
@ -40,3 +40,24 @@ Sections:
|
||||
Symbols:
|
||||
- Name: foo
|
||||
- Name: bar
|
||||
|
||||
## Check we report an error if the relocated section identified by the
|
||||
## sh_info field of a relocation section is invalid.
|
||||
|
||||
# RUN: yaml2obj %s --docnum=2 -o %t2.o
|
||||
# RUN: not llvm-objdump %t2.o --disassemble --reloc 2>&1 | FileCheck %s -DFILE=%t2.o --check-prefix=ERR
|
||||
|
||||
# ERR: error: '[[FILE]]': section (1): failed to get a relocated section: invalid section index: 255
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .rela.debug_info
|
||||
Type: SHT_RELA
|
||||
Link: 0
|
||||
Info: 0xFF
|
||||
Relocations: []
|
||||
|
@ -74,8 +74,8 @@ Symbols:
|
||||
## Check we report an error if the relocated section identified by the
|
||||
## sh_info field of a relocation section is invalid.
|
||||
# RUN: yaml2obj --docnum=2 %s > %t2
|
||||
# RUN: not llvm-objdump --reloc %t2 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# ERR: LLVM ERROR: Invalid data was encountered while parsing the file
|
||||
# RUN: not llvm-objdump --reloc %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=ERR
|
||||
# ERR: error: '[[FILE]]': section (1): unable to get a relocation target: invalid section index: 255
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
@ -86,7 +86,7 @@ FileHeader:
|
||||
Sections:
|
||||
- Name: .rela.foo
|
||||
Type: SHT_RELA
|
||||
Info: 0x255
|
||||
Info: 0xFF
|
||||
Relocations:
|
||||
- Offset: 0x1
|
||||
Type: R_X86_64_NONE
|
||||
|
@ -641,3 +641,26 @@ Sections:
|
||||
Relocations:
|
||||
- Offset: 0
|
||||
Type: R_X86_64_64
|
||||
|
||||
## Check we report an error when dumping stack sizes if the relocated section
|
||||
## identified by the sh_info field is invalid. Here sh_info value is larger than
|
||||
## the number of sections.
|
||||
|
||||
# RUN: yaml2obj --docnum=13 %s > %t18
|
||||
# RUN: not llvm-readelf --stack-sizes %t18 2>&1 | FileCheck %s -DFILE=%t18 --check-prefix=INVALID-TARGET
|
||||
# RUN: not llvm-readobj --stack-sizes %t18 2>&1 | FileCheck %s -DFILE=%t18 --check-prefix=INVALID-TARGET
|
||||
|
||||
# INVALID-TARGET: error: '[[FILE]]': .rela.stack_sizes: failed to get a relocated section: invalid section index: 255
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2MSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .rela.stack_sizes
|
||||
Type: SHT_RELA
|
||||
Link: 0
|
||||
Info: 0xFF
|
||||
Relocations: []
|
||||
|
@ -174,7 +174,11 @@ static void dumpCXXData(const ObjectFile *Obj) {
|
||||
|
||||
SectionRelocMap.clear();
|
||||
for (const SectionRef &Section : Obj->sections()) {
|
||||
section_iterator Sec2 = Section.getRelocatedSection();
|
||||
Expected<section_iterator> ErrOrSec = Section.getRelocatedSection();
|
||||
if (!ErrOrSec)
|
||||
error(ErrOrSec.takeError());
|
||||
|
||||
section_iterator Sec2 = *ErrOrSec;
|
||||
if (Sec2 != Obj->section_end())
|
||||
SectionRelocMap[*Sec2].push_back(Section);
|
||||
}
|
||||
|
@ -993,8 +993,17 @@ static size_t countSkippableZeroBytes(ArrayRef<uint8_t> Buf) {
|
||||
static std::map<SectionRef, std::vector<RelocationRef>>
|
||||
getRelocsMap(object::ObjectFile const &Obj) {
|
||||
std::map<SectionRef, std::vector<RelocationRef>> Ret;
|
||||
uint64_t I = (uint64_t)-1;
|
||||
for (SectionRef Sec : Obj.sections()) {
|
||||
section_iterator Relocated = Sec.getRelocatedSection();
|
||||
++I;
|
||||
Expected<section_iterator> RelocatedOrErr = Sec.getRelocatedSection();
|
||||
if (!RelocatedOrErr)
|
||||
reportError(Obj.getFileName(),
|
||||
"section (" + Twine(I) +
|
||||
"): failed to get a relocated section: " +
|
||||
toString(RelocatedOrErr.takeError()));
|
||||
|
||||
section_iterator Relocated = *RelocatedOrErr;
|
||||
if (Relocated == Obj.section_end() || !checkSectionFilter(*Relocated).Keep)
|
||||
continue;
|
||||
std::vector<RelocationRef> &V = Ret[*Relocated];
|
||||
@ -1606,11 +1615,17 @@ void printRelocations(const ObjectFile *Obj) {
|
||||
// sections. Usually, there is an only one relocation section for
|
||||
// each relocated section.
|
||||
MapVector<SectionRef, std::vector<SectionRef>> SecToRelSec;
|
||||
for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
|
||||
uint64_t Ndx;
|
||||
for (const SectionRef &Section : ToolSectionFilter(*Obj, &Ndx)) {
|
||||
if (Section.relocation_begin() == Section.relocation_end())
|
||||
continue;
|
||||
const SectionRef TargetSec = *Section.getRelocatedSection();
|
||||
SecToRelSec[TargetSec].push_back(Section);
|
||||
Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
|
||||
if (!SecOrErr)
|
||||
reportError(Obj->getFileName(),
|
||||
"section (" + Twine(Ndx) +
|
||||
"): unable to get a relocation target: " +
|
||||
toString(SecOrErr.takeError()));
|
||||
SecToRelSec[**SecOrErr].push_back(Section);
|
||||
}
|
||||
|
||||
for (std::pair<SectionRef, std::vector<SectionRef>> &P : SecToRelSec) {
|
||||
|
@ -4894,8 +4894,16 @@ void DumpStyle<ELFT>::printRelocatableStackSizes(
|
||||
if (SectionType != ELF::SHT_RELA && SectionType != ELF::SHT_REL)
|
||||
continue;
|
||||
|
||||
SectionRef Contents = *Sec.getRelocatedSection();
|
||||
const Elf_Shdr *ContentsSec = Obj->getSection(Contents.getRawDataRefImpl());
|
||||
Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection();
|
||||
if (!RelSecOrErr)
|
||||
reportError(createStringError(object_error::parse_failed,
|
||||
"%s: failed to get a relocated section: %s",
|
||||
SectionName.data(),
|
||||
toString(RelSecOrErr.takeError()).c_str()),
|
||||
Obj->getFileName());
|
||||
|
||||
const Elf_Shdr *ContentsSec =
|
||||
Obj->getSection((*RelSecOrErr)->getRawDataRefImpl());
|
||||
Expected<StringRef> ContentsSectionNameOrErr =
|
||||
EF->getSectionName(ContentsSec);
|
||||
if (!ContentsSectionNameOrErr) {
|
||||
|
Loading…
Reference in New Issue
Block a user