Add RelocVisitor support for MachO

This commit adds partial support for MachO relocations to RelocVisitor.
A simple test case is added to show that relocations are indeed being
applied and that using llvm-dwarfdump on MachO files no longer errors.
Correctness is not yet tested, due to an unrelated bug in DebugInfo,
which will be fixed with appropriate testcase in a followup commit.

Differential Revision: http://reviews.llvm.org/D8148

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238663 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Keno Fischer 2015-05-30 19:44:53 +00:00
parent 27420dd231
commit dbdf667725
7 changed files with 51 additions and 2 deletions

View File

@ -246,6 +246,7 @@ public:
SmallVectorImpl<char> &Result) const override;
std::error_code getRelocationHidden(DataRefImpl Rel,
bool &Result) const override;
uint8_t getRelocationLength(DataRefImpl Rel) const;
// MachO specific.
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;

View File

@ -19,9 +19,11 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/MachO.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
@ -52,6 +54,8 @@ public:
return visitELF(RelocType, R, Value);
if (isa<COFFObjectFile>(ObjToVisit))
return visitCOFF(RelocType, R, Value);
if (isa<MachOObjectFile>(ObjToVisit))
return visitMachO(RelocType, R, Value);
HasError = true;
return RelocToApply();
@ -221,6 +225,20 @@ private:
return RelocToApply();
}
RelocToApply visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) {
switch (ObjToVisit.getArch()) {
default: break;
case Triple::x86_64:
switch (RelocType) {
default: break;
case MachO::X86_64_RELOC_UNSIGNED:
return visitMACHO_X86_64_UNSIGNED(R, Value);
}
}
HasError = true;
return RelocToApply();
}
int64_t getELFAddend32LE(RelocationRef R) {
const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile());
DataRefImpl DRI = R.getRawDataRefImpl();
@ -252,6 +270,12 @@ private:
Obj->getRelocationAddend(DRI, Addend);
return Addend;
}
uint8_t getLengthMachO64(RelocationRef R) {
const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObjectFile());
return Obj->getRelocationLength(R.getRawDataRefImpl());
}
/// Operations
/// 386-ELF
@ -413,6 +437,13 @@ private:
RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) {
return RelocToApply(Value, /*Width=*/8);
}
// X86_64 MachO
RelocToApply visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) {
uint8_t Length = getLengthMachO64(R);
Length = 1<<Length;
return RelocToApply(Value, Length);
}
};
}

View File

@ -1004,6 +1004,11 @@ std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
return object_error::success;
}
uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const {
MachO::any_relocation_info RE = getRelocation(Rel);
return getAnyRelocationLength(RE);
}
//
// guessLibraryShortName() is passed a name of a dynamic library and returns a
// guess on what the short name is. Then name is returned as a substring of the

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,7 @@
# Check that relocations get applied
RUN: llvm-dwarfdump %p/Inputs/test-simple-macho.o | FileCheck %s
RUN: llvm-dwarfdump %p/Inputs/test-multiple-macho.o | FileCheck %s
RUN: llvm-rtdyld -printline %p/Inputs/test-multiple-macho.o | FileCheck %s
RUN: llvm-rtdyld -printobjline %p/Inputs/test-multiple-macho.o | FileCheck %s
CHECK-NOT: error: failed to compute relocation: X86_64_RELOC_UNSIGNED

View File

@ -47,6 +47,7 @@ InputFileList(cl::Positional, cl::ZeroOrMore,
enum ActionType {
AC_Execute,
AC_PrintObjectLineInfo,
AC_PrintLineInfo,
AC_PrintDebugLineInfo,
AC_Verify
@ -61,6 +62,8 @@ Action(cl::desc("Action to perform:"),
"Load, link, and print line information for each function."),
clEnumValN(AC_PrintDebugLineInfo, "printdebugline",
"Load, link, and print line information for each function using the debug object"),
clEnumValN(AC_PrintObjectLineInfo, "printobjline",
"Like -printlineinfo but does not load the object first"),
clEnumValN(AC_Verify, "verify",
"Load, link and verify the resulting memory image."),
clEnumValEnd));
@ -622,9 +625,11 @@ int main(int argc, char **argv) {
case AC_Execute:
return executeInput();
case AC_PrintDebugLineInfo:
return printLineInfoForInput(true,true);
return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */ true);
case AC_PrintLineInfo:
return printLineInfoForInput(true,false);
return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */false);
case AC_PrintObjectLineInfo:
return printLineInfoForInput(/* LoadObjects */false,/* UseDebugObj */false);
case AC_Verify:
return linkAndVerify();
}