mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[ELF] getRelocatedSection: remove the check for ET_REL object file
getRelocatedSection interface should not check that the object file is relocatable, as executable files may have relocations preserved with `--emit-relocs` linker flag. The relocations are useful in context of post-link binary analysis for function reference identification. For example, BOLT relies on relocations to perform function reordering. Reviewed By: MaskRay, jhenderson Differential Revision: https://reviews.llvm.org/D102296
This commit is contained in:
parent
9e8b1c8ad9
commit
af66a21d42
@ -975,9 +975,6 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
|
||||
template <class ELFT>
|
||||
Expected<section_iterator>
|
||||
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
|
||||
if (EF.getHeader().e_type != ELF::ET_REL)
|
||||
return section_end();
|
||||
|
||||
const Elf_Shdr *EShdr = getSection(Sec);
|
||||
uintX_t Type = EShdr->sh_type;
|
||||
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
|
||||
|
@ -132,6 +132,9 @@ public:
|
||||
iterator_range<relocation_iterator> relocations() const {
|
||||
return make_range(relocation_begin(), relocation_end());
|
||||
}
|
||||
|
||||
/// Returns the related section if this section contains relocations. The
|
||||
/// returned section may or may not have applied its relocations.
|
||||
Expected<section_iterator> getRelocatedSection() const;
|
||||
|
||||
DataRefImpl getRawDataRefImpl() const;
|
||||
|
@ -1687,7 +1687,8 @@ public:
|
||||
// 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;
|
||||
section_iterator RelocatedSection =
|
||||
Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end();
|
||||
if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
|
||||
Expected<StringRef> E = Section.getContents();
|
||||
if (E)
|
||||
|
@ -440,7 +440,7 @@ SubtargetFeatures XCOFFObjectFile::getFeatures() const {
|
||||
|
||||
bool XCOFFObjectFile::isRelocatableObject() const {
|
||||
if (is64Bit())
|
||||
report_fatal_error("64-bit support not implemented yet");
|
||||
return !(fileHeader64()->Flags & NoRelMask);
|
||||
return !(fileHeader32()->Flags & NoRelMask);
|
||||
}
|
||||
|
||||
|
@ -590,3 +590,68 @@ Sections:
|
||||
DoCheck(OverLimitNumBlocks,
|
||||
"ULEB128 value at offset 0x8 exceeds UINT32_MAX (0x100000000)");
|
||||
}
|
||||
|
||||
// Test for ObjectFile::getRelocatedSection: check that it returns a relocated
|
||||
// section for executable and relocatable files.
|
||||
TEST(ELFObjectFileTest, ExecutableWithRelocs) {
|
||||
StringRef HeaderString(R"(
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
)");
|
||||
StringRef ContentsString(R"(
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
- Name: .rela.text
|
||||
Type: SHT_RELA
|
||||
Flags: [ SHF_INFO_LINK ]
|
||||
Info: .text
|
||||
)");
|
||||
|
||||
auto DoCheck = [&](StringRef YamlString) {
|
||||
SmallString<0> Storage;
|
||||
Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
|
||||
toBinary<ELF64LE>(Storage, YamlString);
|
||||
ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
|
||||
const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;
|
||||
|
||||
bool FoundRela;
|
||||
|
||||
for (SectionRef Sec : Obj.sections()) {
|
||||
Expected<StringRef> SecNameOrErr = Sec.getName();
|
||||
ASSERT_THAT_EXPECTED(SecNameOrErr, Succeeded());
|
||||
StringRef SecName = *SecNameOrErr;
|
||||
if (SecName != ".rela.text")
|
||||
continue;
|
||||
FoundRela = true;
|
||||
Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection();
|
||||
ASSERT_THAT_EXPECTED(RelSecOrErr, Succeeded());
|
||||
section_iterator RelSec = *RelSecOrErr;
|
||||
ASSERT_NE(RelSec, Obj.section_end());
|
||||
Expected<StringRef> TextSecNameOrErr = RelSec->getName();
|
||||
ASSERT_THAT_EXPECTED(TextSecNameOrErr, Succeeded());
|
||||
StringRef TextSecName = *TextSecNameOrErr;
|
||||
EXPECT_EQ(TextSecName, ".text");
|
||||
}
|
||||
ASSERT_TRUE(FoundRela);
|
||||
};
|
||||
|
||||
// Check ET_EXEC file (`ld --emit-relocs` use-case).
|
||||
SmallString<128> ExecFileYamlString(HeaderString);
|
||||
ExecFileYamlString += R"(
|
||||
Type: ET_EXEC
|
||||
)";
|
||||
ExecFileYamlString += ContentsString;
|
||||
DoCheck(ExecFileYamlString);
|
||||
|
||||
// Check ET_REL file.
|
||||
SmallString<128> RelocatableFileYamlString(HeaderString);
|
||||
RelocatableFileYamlString += R"(
|
||||
Type: ET_REL
|
||||
)";
|
||||
RelocatableFileYamlString += ContentsString;
|
||||
DoCheck(RelocatableFileYamlString);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user