1
0
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:
Amir Ayupov 2021-06-07 13:17:00 -07:00 committed by Fangrui Song
parent 9e8b1c8ad9
commit af66a21d42
5 changed files with 71 additions and 5 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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);
}