Implement getRelocationAddress for MachO and ET_REL elf files.

With that, fix the symbolizer to work with any ELF file.

llvm-svn: 205588
This commit is contained in:
Rafael Espindola 2014-04-03 23:54:35 +00:00
parent 1f708ccc84
commit c4dd200975
6 changed files with 44 additions and 37 deletions

View File

@ -555,10 +555,17 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
template <class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
uint64_t &Result) const {
assert((EF.getHeader()->e_type == ELF::ET_EXEC ||
EF.getHeader()->e_type == ELF::ET_DYN) &&
"Only executable and shared objects files have relocation addresses");
Result = getROffset(Rel);
uint64_t ROffset = getROffset(Rel);
const Elf_Ehdr *Header = EF.getHeader();
if (Header->e_type == ELF::ET_REL) {
const Elf_Shdr *RelocationSec = getRelSection(Rel);
const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info);
Result = ROffset + RelocatedSec->sh_addr;
} else {
Result = ROffset;
}
return object_error::success;
}

View File

@ -257,40 +257,12 @@ void MCObjectSymbolizer::buildSectionList() {
void MCObjectSymbolizer::buildRelocationByAddrMap() {
for (const SectionRef &Section : Obj->sections()) {
section_iterator RelSecI = Section.getRelocatedSection();
if (RelSecI == Obj->section_end())
continue;
uint64_t StartAddr; RelSecI->getAddress(StartAddr);
uint64_t Size; RelSecI->getSize(Size);
bool RequiredForExec;
RelSecI->isRequiredForExecution(RequiredForExec);
if (RequiredForExec == false || Size == 0)
continue;
for (const RelocationRef &Reloc : Section.relocations()) {
// FIXME: libObject is inconsistent regarding error handling. The
// overwhelming majority of methods always return object_error::success,
// and assert for simple errors.. Here, ELFObjectFile::getRelocationOffset
// asserts when the file type isn't ET_REL.
// This workaround handles x86-64 elf, the only one that has a relocinfo.
uint64_t Offset;
if (Obj->isELF()) {
const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj);
if (ELFObj == 0)
break;
if (ELFObj->getELFFile()->getHeader()->e_type == ELF::ET_REL) {
Reloc.getOffset(Offset);
Offset += StartAddr;
} else {
Reloc.getAddress(Offset);
}
} else {
Reloc.getOffset(Offset);
Offset += StartAddr;
}
uint64_t Address;
Reloc.getAddress(Address);
// At a specific address, only keep the first relocation.
if (AddrToReloc.find(Offset) == AddrToReloc.end())
AddrToReloc[Offset] = Reloc;
if (AddrToReloc.find(Address) == AddrToReloc.end())
AddrToReloc[Address] = Reloc;
}
}
}

View File

@ -784,7 +784,15 @@ void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
error_code
MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
MachO::any_relocation_info RE = getRelocation(Rel);
uint64_t Offset = getAnyRelocationAddress(RE);
DataRefImpl Sec;
Sec.d.a = Rel.d.a;
uint64_t SecAddress;
getSectionAddress(Sec, SecAddress);
Res = SecAddress + Offset;
return object_error::success;
}
error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,

Binary file not shown.

Binary file not shown.

View File

@ -46,3 +46,23 @@ MACHO-STUBS-x86-64: 1faa: e8 09 00 00 00
MACHO-STUBS-x86-64: 1faf: 8b 44 24 04 movl 4(%rsp), %eax
MACHO-STUBS-x86-64: 1fb3: 48 83 c4 08 addq $8, %rsp
MACHO-STUBS-x86-64: 1fb7: c3 ret
RUN: llvm-objdump -d -symbolize %p/../Inputs/relocation-relocatable.elf-i386 \
RUN: | FileCheck %s -check-prefix ELF-i386-REL
ELF-i386-REL: Disassembly of section .text:
ELF-i386-REL-NEXT: f:
ELF-i386-REL-NEXT: 0: e9 fc ff ff ff jmp h
ELF-i386-REL: g:
ELF-i386-REL-NEXT: 5: e9 fc ff ff ff jmp f
RUN: llvm-objdump -d -symbolize %p/../Inputs/relocation-dynamic.elf-i386 \
RUN: | FileCheck %s -check-prefix ELF-i386-DYN
ELF-i386-DYN: Disassembly of section .text:
ELF-i386-DYN-NEXT: f:
ELF-i386-DYN-NEXT: 1a4: e9 fc ff ff ff jmp h
ELF-i386-DYN: g:
ELF-i386-DYN-NEXT: 1a9: e9 fc ff ff ff jmp f