mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
llvm-dwarfdump: Add support for some COFF relocations
DWARF in COFF utilizes several relocations. Implement support for them in RelocVisitor to support llvm-dwarfdump. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219280 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2929da99a9
commit
3d371bd84b
@ -47,6 +47,8 @@ public:
|
||||
|
||||
virtual std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
|
||||
bool &IsDefault) const = 0;
|
||||
|
||||
static inline bool classof(const Binary *v) { return v->isELF(); }
|
||||
};
|
||||
|
||||
template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define LLVM_OBJECT_RELOCVISITOR_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Object/COFF.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@ -46,8 +47,23 @@ public:
|
||||
// TODO: Should handle multiple applied relocations via either passing in the
|
||||
// previously computed value or just count paired relocations as a single
|
||||
// visit.
|
||||
RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
|
||||
uint64_t Value = 0) {
|
||||
RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) {
|
||||
if (isa<ELFObjectFileBase>(ObjToVisit))
|
||||
return visitELF(RelocType, R, Value);
|
||||
if (isa<COFFObjectFile>(ObjToVisit))
|
||||
return visitCOFF(RelocType, R, Value);
|
||||
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
|
||||
bool error() { return HasError; }
|
||||
|
||||
private:
|
||||
ObjectFile &ObjToVisit;
|
||||
bool HasError;
|
||||
|
||||
RelocToApply visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
|
||||
if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
|
||||
switch (ObjToVisit.getArch()) {
|
||||
case Triple::x86_64:
|
||||
@ -57,7 +73,7 @@ public:
|
||||
case llvm::ELF::R_X86_64_64:
|
||||
return visitELF_X86_64_64(R, Value);
|
||||
case llvm::ELF::R_X86_64_PC32:
|
||||
return visitELF_X86_64_PC32(R, Value, SecAddr);
|
||||
return visitELF_X86_64_PC32(R, Value);
|
||||
case llvm::ELF::R_X86_64_32:
|
||||
return visitELF_X86_64_32(R, Value);
|
||||
case llvm::ELF::R_X86_64_32S:
|
||||
@ -133,7 +149,7 @@ public:
|
||||
case llvm::ELF::R_386_32:
|
||||
return visitELF_386_32(R, Value);
|
||||
case llvm::ELF::R_386_PC32:
|
||||
return visitELF_386_PC32(R, Value, SecAddr);
|
||||
return visitELF_386_PC32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
@ -182,13 +198,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool error() { return HasError; }
|
||||
RelocToApply visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
|
||||
switch (ObjToVisit.getArch()) {
|
||||
case Triple::x86:
|
||||
switch (RelocType) {
|
||||
case COFF::IMAGE_REL_I386_SECREL:
|
||||
return visitCOFF_I386_SECREL(R, Value);
|
||||
case COFF::IMAGE_REL_I386_DIR32:
|
||||
return visitCOFF_I386_DIR32(R, Value);
|
||||
}
|
||||
break;
|
||||
case Triple::x86_64:
|
||||
switch (RelocType) {
|
||||
case COFF::IMAGE_REL_AMD64_SECREL:
|
||||
return visitCOFF_AMD64_SECREL(R, Value);
|
||||
case COFF::IMAGE_REL_AMD64_ADDR64:
|
||||
return visitCOFF_AMD64_ADDR64(R, Value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
|
||||
private:
|
||||
ObjectFile &ObjToVisit;
|
||||
bool HasError;
|
||||
|
||||
int64_t getAddend32LE(RelocationRef R) {
|
||||
int64_t getELFAddend32LE(RelocationRef R) {
|
||||
const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile());
|
||||
DataRefImpl DRI = R.getRawDataRefImpl();
|
||||
int64_t Addend;
|
||||
@ -196,7 +229,7 @@ private:
|
||||
return Addend;
|
||||
}
|
||||
|
||||
int64_t getAddend64LE(RelocationRef R) {
|
||||
int64_t getELFAddend64LE(RelocationRef R) {
|
||||
const ELF64LEObjectFile *Obj = cast<ELF64LEObjectFile>(R.getObjectFile());
|
||||
DataRefImpl DRI = R.getRawDataRefImpl();
|
||||
int64_t Addend;
|
||||
@ -204,7 +237,7 @@ private:
|
||||
return Addend;
|
||||
}
|
||||
|
||||
int64_t getAddend32BE(RelocationRef R) {
|
||||
int64_t getELFAddend32BE(RelocationRef R) {
|
||||
const ELF32BEObjectFile *Obj = cast<ELF32BEObjectFile>(R.getObjectFile());
|
||||
DataRefImpl DRI = R.getRawDataRefImpl();
|
||||
int64_t Addend;
|
||||
@ -212,7 +245,7 @@ private:
|
||||
return Addend;
|
||||
}
|
||||
|
||||
int64_t getAddend64BE(RelocationRef R) {
|
||||
int64_t getELFAddend64BE(RelocationRef R) {
|
||||
const ELF64BEObjectFile *Obj = cast<ELF64BEObjectFile>(R.getObjectFile());
|
||||
DataRefImpl DRI = R.getRawDataRefImpl();
|
||||
int64_t Addend;
|
||||
@ -229,13 +262,12 @@ private:
|
||||
// Ideally the Addend here will be the addend in the data for
|
||||
// the relocation. It's not actually the case for Rel relocations.
|
||||
RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getAddend32LE(R);
|
||||
int64_t Addend = getELFAddend32LE(R);
|
||||
return RelocToApply(Value + Addend, 4);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value,
|
||||
uint64_t SecAddr) {
|
||||
int64_t Addend = getAddend32LE(R);
|
||||
RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getELFAddend32LE(R);
|
||||
uint64_t Address;
|
||||
R.getOffset(Address);
|
||||
return RelocToApply(Value + Addend - Address, 4);
|
||||
@ -246,23 +278,22 @@ private:
|
||||
return RelocToApply(0, 0);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getAddend64LE(R);
|
||||
int64_t Addend = getELFAddend64LE(R);
|
||||
return RelocToApply(Value + Addend, 8);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value,
|
||||
uint64_t SecAddr) {
|
||||
int64_t Addend = getAddend64LE(R);
|
||||
RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getELFAddend64LE(R);
|
||||
uint64_t Address;
|
||||
R.getOffset(Address);
|
||||
return RelocToApply(Value + Addend - Address, 4);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getAddend64LE(R);
|
||||
int64_t Addend = getELFAddend64LE(R);
|
||||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getAddend64LE(R);
|
||||
int64_t Addend = getELFAddend64LE(R);
|
||||
int32_t Res = (Value + Addend) & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
@ -282,7 +313,7 @@ private:
|
||||
|
||||
/// PPC32 ELF
|
||||
RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getAddend32BE(R);
|
||||
int64_t Addend = getELFAddend32BE(R);
|
||||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
@ -323,7 +354,7 @@ private:
|
||||
|
||||
// SystemZ ELF
|
||||
RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getAddend64BE(R);
|
||||
int64_t Addend = getELFAddend64BE(R);
|
||||
int64_t Res = Value + Addend;
|
||||
|
||||
// Overflow check allows for both signed and unsigned interpretation.
|
||||
@ -334,22 +365,22 @@ private:
|
||||
}
|
||||
|
||||
RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getAddend64BE(R);
|
||||
int64_t Addend = getELFAddend64BE(R);
|
||||
return RelocToApply(Value + Addend, 8);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) {
|
||||
int32_t Addend = getAddend32BE(R);
|
||||
int32_t Addend = getELFAddend32BE(R);
|
||||
return RelocToApply(Value + Addend, 4);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) {
|
||||
int32_t Addend = getAddend64BE(R);
|
||||
int32_t Addend = getELFAddend64BE(R);
|
||||
return RelocToApply(Value + Addend, 4);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getAddend64BE(R);
|
||||
int64_t Addend = getELFAddend64BE(R);
|
||||
return RelocToApply(Value + Addend, 8);
|
||||
}
|
||||
|
||||
@ -365,6 +396,23 @@ private:
|
||||
return RelocToApply(static_cast<uint32_t>(Res), 4);
|
||||
}
|
||||
|
||||
/// I386 COFF
|
||||
RelocToApply visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) {
|
||||
return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
|
||||
}
|
||||
|
||||
RelocToApply visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) {
|
||||
return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
|
||||
}
|
||||
|
||||
/// AMD64 COFF
|
||||
RelocToApply visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) {
|
||||
return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
|
||||
}
|
||||
|
||||
RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) {
|
||||
return RelocToApply(Value, /*Width=*/8);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -620,15 +620,12 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile &Obj)
|
||||
uint64_t Type;
|
||||
Reloc.getType(Type);
|
||||
uint64_t SymAddr = 0;
|
||||
// ELF relocations may need the symbol address
|
||||
if (Obj.isELF()) {
|
||||
object::symbol_iterator Sym = Reloc.getSymbol();
|
||||
object::symbol_iterator Sym = Reloc.getSymbol();
|
||||
if (Sym != Obj.symbol_end())
|
||||
Sym->getAddress(SymAddr);
|
||||
}
|
||||
|
||||
object::RelocVisitor V(Obj);
|
||||
// The section address is always 0 for debug sections.
|
||||
object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
|
||||
object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
|
||||
if (V.error()) {
|
||||
SmallString<32> Name;
|
||||
std::error_code ec(Reloc.getTypeName(Name));
|
||||
|
@ -2,6 +2,10 @@
|
||||
; RUN: llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple i386-none-linux | \
|
||||
; RUN: llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple x86_64-none-mingw32 | \
|
||||
; RUN: llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s -mtriple i386-none-mingw32 | \
|
||||
; RUN: llvm-dwarfdump - 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK-NOT: failed to compute relocation
|
||||
|
||||
@ -13,5 +17,5 @@
|
||||
!1 = metadata !{metadata !"empty.c", metadata !"/a"}
|
||||
!2 = metadata !{}
|
||||
!3 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
|
||||
!4 = metadata !{i32 2, metadata !"Debug Info Version", i32 1}
|
||||
!4 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
|
||||
!5 = metadata !{metadata !"clang version 3.6.0 "}
|
||||
|
Loading…
x
Reference in New Issue
Block a user