mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
Move to llvm-objdump a large amount of code to that is only used there.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238898 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cbf5311a34
commit
8c7a0fd91a
@ -647,10 +647,6 @@ protected:
|
|||||||
std::error_code
|
std::error_code
|
||||||
getRelocationTypeName(DataRefImpl Rel,
|
getRelocationTypeName(DataRefImpl Rel,
|
||||||
SmallVectorImpl<char> &Result) const override;
|
SmallVectorImpl<char> &Result) const override;
|
||||||
std::error_code
|
|
||||||
getRelocationValueString(DataRefImpl Rel,
|
|
||||||
SmallVectorImpl<char> &Result) const override;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
|
COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
|
||||||
basic_symbol_iterator symbol_begin_impl() const override;
|
basic_symbol_iterator symbol_begin_impl() const override;
|
||||||
|
@ -118,9 +118,6 @@ protected:
|
|||||||
std::error_code
|
std::error_code
|
||||||
getRelocationTypeName(DataRefImpl Rel,
|
getRelocationTypeName(DataRefImpl Rel,
|
||||||
SmallVectorImpl<char> &Result) const override;
|
SmallVectorImpl<char> &Result) const override;
|
||||||
std::error_code
|
|
||||||
getRelocationValueString(DataRefImpl Rel,
|
|
||||||
SmallVectorImpl<char> &Result) const override;
|
|
||||||
|
|
||||||
uint64_t getROffset(DataRefImpl Rel) const;
|
uint64_t getROffset(DataRefImpl Rel) const;
|
||||||
StringRef getRelocationTypeName(uint32_t Type) const;
|
StringRef getRelocationTypeName(uint32_t Type) const;
|
||||||
@ -707,87 +704,6 @@ ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
std::error_code ELFObjectFile<ELFT>::getRelocationValueString(
|
|
||||||
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
|
|
||||||
const Elf_Shdr *sec = getRelSection(Rel);
|
|
||||||
uint8_t type;
|
|
||||||
StringRef res;
|
|
||||||
int64_t addend = 0;
|
|
||||||
uint16_t symbol_index = 0;
|
|
||||||
switch (sec->sh_type) {
|
|
||||||
default:
|
|
||||||
return object_error::parse_failed;
|
|
||||||
case ELF::SHT_REL: {
|
|
||||||
type = getRel(Rel)->getType(EF.isMips64EL());
|
|
||||||
symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL());
|
|
||||||
// TODO: Read implicit addend from section data.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ELF::SHT_RELA: {
|
|
||||||
type = getRela(Rel)->getType(EF.isMips64EL());
|
|
||||||
symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL());
|
|
||||||
addend = getRela(Rel)->r_addend;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const Elf_Sym *symb =
|
|
||||||
EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index);
|
|
||||||
ErrorOr<StringRef> SymName =
|
|
||||||
EF.getSymbolName(EF.getSection(sec->sh_link), symb);
|
|
||||||
if (!SymName)
|
|
||||||
return SymName.getError();
|
|
||||||
switch (EF.getHeader()->e_machine) {
|
|
||||||
case ELF::EM_X86_64:
|
|
||||||
switch (type) {
|
|
||||||
case ELF::R_X86_64_PC8:
|
|
||||||
case ELF::R_X86_64_PC16:
|
|
||||||
case ELF::R_X86_64_PC32: {
|
|
||||||
std::string fmtbuf;
|
|
||||||
raw_string_ostream fmt(fmtbuf);
|
|
||||||
fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P";
|
|
||||||
fmt.flush();
|
|
||||||
Result.append(fmtbuf.begin(), fmtbuf.end());
|
|
||||||
} break;
|
|
||||||
case ELF::R_X86_64_8:
|
|
||||||
case ELF::R_X86_64_16:
|
|
||||||
case ELF::R_X86_64_32:
|
|
||||||
case ELF::R_X86_64_32S:
|
|
||||||
case ELF::R_X86_64_64: {
|
|
||||||
std::string fmtbuf;
|
|
||||||
raw_string_ostream fmt(fmtbuf);
|
|
||||||
fmt << *SymName << (addend < 0 ? "" : "+") << addend;
|
|
||||||
fmt.flush();
|
|
||||||
Result.append(fmtbuf.begin(), fmtbuf.end());
|
|
||||||
} break;
|
|
||||||
default:
|
|
||||||
res = "Unknown";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ELF::EM_AARCH64: {
|
|
||||||
std::string fmtbuf;
|
|
||||||
raw_string_ostream fmt(fmtbuf);
|
|
||||||
fmt << *SymName;
|
|
||||||
if (addend != 0)
|
|
||||||
fmt << (addend < 0 ? "" : "+") << addend;
|
|
||||||
fmt.flush();
|
|
||||||
Result.append(fmtbuf.begin(), fmtbuf.end());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ELF::EM_386:
|
|
||||||
case ELF::EM_ARM:
|
|
||||||
case ELF::EM_HEXAGON:
|
|
||||||
case ELF::EM_MIPS:
|
|
||||||
res = *SymName;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res = "Unknown";
|
|
||||||
}
|
|
||||||
if (Result.empty())
|
|
||||||
Result.append(res.begin(), res.end());
|
|
||||||
return object_error::success;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
const typename ELFFile<ELFT>::Elf_Sym *
|
const typename ELFFile<ELFT>::Elf_Sym *
|
||||||
ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
|
ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
|
||||||
|
@ -240,9 +240,6 @@ public:
|
|||||||
std::error_code
|
std::error_code
|
||||||
getRelocationTypeName(DataRefImpl Rel,
|
getRelocationTypeName(DataRefImpl Rel,
|
||||||
SmallVectorImpl<char> &Result) const override;
|
SmallVectorImpl<char> &Result) const override;
|
||||||
std::error_code
|
|
||||||
getRelocationValueString(DataRefImpl Rel,
|
|
||||||
SmallVectorImpl<char> &Result) const override;
|
|
||||||
std::error_code getRelocationHidden(DataRefImpl Rel,
|
std::error_code getRelocationHidden(DataRefImpl Rel,
|
||||||
bool &Result) const override;
|
bool &Result) const override;
|
||||||
uint8_t getRelocationLength(DataRefImpl Rel) const;
|
uint8_t getRelocationLength(DataRefImpl Rel) const;
|
||||||
|
@ -66,11 +66,6 @@ public:
|
|||||||
/// This is for display purposes only.
|
/// This is for display purposes only.
|
||||||
std::error_code getTypeName(SmallVectorImpl<char> &Result) const;
|
std::error_code getTypeName(SmallVectorImpl<char> &Result) const;
|
||||||
|
|
||||||
/// @brief Get a string that represents the calculation of the value of this
|
|
||||||
/// relocation.
|
|
||||||
///
|
|
||||||
/// This is for display purposes only.
|
|
||||||
std::error_code getValueString(SmallVectorImpl<char> &Result) const;
|
|
||||||
|
|
||||||
DataRefImpl getRawDataRefImpl() const;
|
DataRefImpl getRawDataRefImpl() const;
|
||||||
const ObjectFile *getObjectFile() const;
|
const ObjectFile *getObjectFile() const;
|
||||||
@ -252,9 +247,6 @@ protected:
|
|||||||
virtual std::error_code
|
virtual std::error_code
|
||||||
getRelocationTypeName(DataRefImpl Rel,
|
getRelocationTypeName(DataRefImpl Rel,
|
||||||
SmallVectorImpl<char> &Result) const = 0;
|
SmallVectorImpl<char> &Result) const = 0;
|
||||||
virtual std::error_code
|
|
||||||
getRelocationValueString(DataRefImpl Rel,
|
|
||||||
SmallVectorImpl<char> &Result) const = 0;
|
|
||||||
virtual std::error_code getRelocationHidden(DataRefImpl Rel,
|
virtual std::error_code getRelocationHidden(DataRefImpl Rel,
|
||||||
bool &Result) const {
|
bool &Result) const {
|
||||||
Result = false;
|
Result = false;
|
||||||
@ -480,11 +472,6 @@ RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
|
|||||||
return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
|
return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::error_code
|
|
||||||
RelocationRef::getValueString(SmallVectorImpl<char> &Result) const {
|
|
||||||
return OwningObject->getRelocationValueString(RelocationPimpl, Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::error_code RelocationRef::getHidden(bool &Result) const {
|
inline std::error_code RelocationRef::getHidden(bool &Result) const {
|
||||||
return OwningObject->getRelocationHidden(RelocationPimpl, Result);
|
return OwningObject->getRelocationHidden(RelocationPimpl, Result);
|
||||||
}
|
}
|
||||||
|
@ -1114,22 +1114,6 @@ COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
|
|||||||
|
|
||||||
#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
|
#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
|
||||||
|
|
||||||
std::error_code
|
|
||||||
COFFObjectFile::getRelocationValueString(DataRefImpl Rel,
|
|
||||||
SmallVectorImpl<char> &Result) const {
|
|
||||||
const coff_relocation *Reloc = toRel(Rel);
|
|
||||||
DataRefImpl Sym;
|
|
||||||
ErrorOr<COFFSymbolRef> Symb = getSymbol(Reloc->SymbolTableIndex);
|
|
||||||
if (std::error_code EC = Symb.getError())
|
|
||||||
return EC;
|
|
||||||
Sym.p = reinterpret_cast<uintptr_t>(Symb->getRawPtr());
|
|
||||||
StringRef SymName;
|
|
||||||
if (std::error_code EC = getSymbolName(Sym, SymName))
|
|
||||||
return EC;
|
|
||||||
Result.append(SymName.begin(), SymName.end());
|
|
||||||
return object_error::success;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool COFFObjectFile::isRelocatableObject() const {
|
bool COFFObjectFile::isRelocatableObject() const {
|
||||||
return !DataDirectory;
|
return !DataDirectory;
|
||||||
}
|
}
|
||||||
|
@ -128,70 +128,6 @@ static unsigned getCPUType(const MachOObjectFile *O) {
|
|||||||
return O->getHeader().cputype;
|
return O->getHeader().cputype;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printRelocationTargetName(const MachOObjectFile *O,
|
|
||||||
const MachO::any_relocation_info &RE,
|
|
||||||
raw_string_ostream &fmt) {
|
|
||||||
bool IsScattered = O->isRelocationScattered(RE);
|
|
||||||
|
|
||||||
// Target of a scattered relocation is an address. In the interest of
|
|
||||||
// generating pretty output, scan through the symbol table looking for a
|
|
||||||
// symbol that aligns with that address. If we find one, print it.
|
|
||||||
// Otherwise, we just print the hex address of the target.
|
|
||||||
if (IsScattered) {
|
|
||||||
uint32_t Val = O->getPlainRelocationSymbolNum(RE);
|
|
||||||
|
|
||||||
for (const SymbolRef &Symbol : O->symbols()) {
|
|
||||||
std::error_code ec;
|
|
||||||
uint64_t Addr;
|
|
||||||
StringRef Name;
|
|
||||||
|
|
||||||
if ((ec = Symbol.getAddress(Addr)))
|
|
||||||
report_fatal_error(ec.message());
|
|
||||||
if (Addr != Val)
|
|
||||||
continue;
|
|
||||||
if ((ec = Symbol.getName(Name)))
|
|
||||||
report_fatal_error(ec.message());
|
|
||||||
fmt << Name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we couldn't find a symbol that this relocation refers to, try
|
|
||||||
// to find a section beginning instead.
|
|
||||||
for (const SectionRef &Section : O->sections()) {
|
|
||||||
std::error_code ec;
|
|
||||||
|
|
||||||
StringRef Name;
|
|
||||||
uint64_t Addr = Section.getAddress();
|
|
||||||
if (Addr != Val)
|
|
||||||
continue;
|
|
||||||
if ((ec = Section.getName(Name)))
|
|
||||||
report_fatal_error(ec.message());
|
|
||||||
fmt << Name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt << format("0x%x", Val);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef S;
|
|
||||||
bool isExtern = O->getPlainRelocationExternal(RE);
|
|
||||||
uint64_t Val = O->getPlainRelocationSymbolNum(RE);
|
|
||||||
|
|
||||||
if (isExtern) {
|
|
||||||
symbol_iterator SI = O->symbol_begin();
|
|
||||||
advance(SI, Val);
|
|
||||||
SI->getName(S);
|
|
||||||
} else {
|
|
||||||
section_iterator SI = O->section_begin();
|
|
||||||
// Adjust for the fact that sections are 1-indexed.
|
|
||||||
advance(SI, Val - 1);
|
|
||||||
SI->getName(S);
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt << S;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
|
getPlainRelocationAddress(const MachO::any_relocation_info &RE) {
|
||||||
return RE.r_word0;
|
return RE.r_word0;
|
||||||
@ -794,182 +730,6 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
|
|||||||
return object_error::success;
|
return object_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code
|
|
||||||
MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
|
|
||||||
SmallVectorImpl<char> &Result) const {
|
|
||||||
MachO::any_relocation_info RE = getRelocation(Rel);
|
|
||||||
|
|
||||||
unsigned Arch = this->getArch();
|
|
||||||
|
|
||||||
std::string fmtbuf;
|
|
||||||
raw_string_ostream fmt(fmtbuf);
|
|
||||||
unsigned Type = this->getAnyRelocationType(RE);
|
|
||||||
bool IsPCRel = this->getAnyRelocationPCRel(RE);
|
|
||||||
|
|
||||||
// Determine any addends that should be displayed with the relocation.
|
|
||||||
// These require decoding the relocation type, which is triple-specific.
|
|
||||||
|
|
||||||
// X86_64 has entirely custom relocation types.
|
|
||||||
if (Arch == Triple::x86_64) {
|
|
||||||
bool isPCRel = getAnyRelocationPCRel(RE);
|
|
||||||
|
|
||||||
switch (Type) {
|
|
||||||
case MachO::X86_64_RELOC_GOT_LOAD:
|
|
||||||
case MachO::X86_64_RELOC_GOT: {
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
fmt << "@GOT";
|
|
||||||
if (isPCRel) fmt << "PCREL";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MachO::X86_64_RELOC_SUBTRACTOR: {
|
|
||||||
DataRefImpl RelNext = Rel;
|
|
||||||
moveRelocationNext(RelNext);
|
|
||||||
MachO::any_relocation_info RENext = getRelocation(RelNext);
|
|
||||||
|
|
||||||
// X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
|
|
||||||
// X86_64_RELOC_UNSIGNED.
|
|
||||||
// NOTE: Scattered relocations don't exist on x86_64.
|
|
||||||
unsigned RType = getAnyRelocationType(RENext);
|
|
||||||
if (RType != MachO::X86_64_RELOC_UNSIGNED)
|
|
||||||
report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
|
|
||||||
"X86_64_RELOC_SUBTRACTOR.");
|
|
||||||
|
|
||||||
// The X86_64_RELOC_UNSIGNED contains the minuend symbol;
|
|
||||||
// X86_64_RELOC_SUBTRACTOR contains the subtrahend.
|
|
||||||
printRelocationTargetName(this, RENext, fmt);
|
|
||||||
fmt << "-";
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MachO::X86_64_RELOC_TLV:
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
fmt << "@TLV";
|
|
||||||
if (isPCRel) fmt << "P";
|
|
||||||
break;
|
|
||||||
case MachO::X86_64_RELOC_SIGNED_1:
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
fmt << "-1";
|
|
||||||
break;
|
|
||||||
case MachO::X86_64_RELOC_SIGNED_2:
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
fmt << "-2";
|
|
||||||
break;
|
|
||||||
case MachO::X86_64_RELOC_SIGNED_4:
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
fmt << "-4";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// X86 and ARM share some relocation types in common.
|
|
||||||
} else if (Arch == Triple::x86 || Arch == Triple::arm ||
|
|
||||||
Arch == Triple::ppc) {
|
|
||||||
// Generic relocation types...
|
|
||||||
switch (Type) {
|
|
||||||
case MachO::GENERIC_RELOC_PAIR: // prints no info
|
|
||||||
return object_error::success;
|
|
||||||
case MachO::GENERIC_RELOC_SECTDIFF: {
|
|
||||||
DataRefImpl RelNext = Rel;
|
|
||||||
moveRelocationNext(RelNext);
|
|
||||||
MachO::any_relocation_info RENext = getRelocation(RelNext);
|
|
||||||
|
|
||||||
// X86 sect diff's must be followed by a relocation of type
|
|
||||||
// GENERIC_RELOC_PAIR.
|
|
||||||
unsigned RType = getAnyRelocationType(RENext);
|
|
||||||
|
|
||||||
if (RType != MachO::GENERIC_RELOC_PAIR)
|
|
||||||
report_fatal_error("Expected GENERIC_RELOC_PAIR after "
|
|
||||||
"GENERIC_RELOC_SECTDIFF.");
|
|
||||||
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
fmt << "-";
|
|
||||||
printRelocationTargetName(this, RENext, fmt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Arch == Triple::x86 || Arch == Triple::ppc) {
|
|
||||||
switch (Type) {
|
|
||||||
case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
|
|
||||||
DataRefImpl RelNext = Rel;
|
|
||||||
moveRelocationNext(RelNext);
|
|
||||||
MachO::any_relocation_info RENext = getRelocation(RelNext);
|
|
||||||
|
|
||||||
// X86 sect diff's must be followed by a relocation of type
|
|
||||||
// GENERIC_RELOC_PAIR.
|
|
||||||
unsigned RType = getAnyRelocationType(RENext);
|
|
||||||
if (RType != MachO::GENERIC_RELOC_PAIR)
|
|
||||||
report_fatal_error("Expected GENERIC_RELOC_PAIR after "
|
|
||||||
"GENERIC_RELOC_LOCAL_SECTDIFF.");
|
|
||||||
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
fmt << "-";
|
|
||||||
printRelocationTargetName(this, RENext, fmt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MachO::GENERIC_RELOC_TLV: {
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
fmt << "@TLV";
|
|
||||||
if (IsPCRel) fmt << "P";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
}
|
|
||||||
} else { // ARM-specific relocations
|
|
||||||
switch (Type) {
|
|
||||||
case MachO::ARM_RELOC_HALF:
|
|
||||||
case MachO::ARM_RELOC_HALF_SECTDIFF: {
|
|
||||||
// Half relocations steal a bit from the length field to encode
|
|
||||||
// whether this is an upper16 or a lower16 relocation.
|
|
||||||
bool isUpper = getAnyRelocationLength(RE) >> 1;
|
|
||||||
|
|
||||||
if (isUpper)
|
|
||||||
fmt << ":upper16:(";
|
|
||||||
else
|
|
||||||
fmt << ":lower16:(";
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
|
|
||||||
DataRefImpl RelNext = Rel;
|
|
||||||
moveRelocationNext(RelNext);
|
|
||||||
MachO::any_relocation_info RENext = getRelocation(RelNext);
|
|
||||||
|
|
||||||
// ARM half relocs must be followed by a relocation of type
|
|
||||||
// ARM_RELOC_PAIR.
|
|
||||||
unsigned RType = getAnyRelocationType(RENext);
|
|
||||||
if (RType != MachO::ARM_RELOC_PAIR)
|
|
||||||
report_fatal_error("Expected ARM_RELOC_PAIR after "
|
|
||||||
"ARM_RELOC_HALF");
|
|
||||||
|
|
||||||
// NOTE: The half of the target virtual address is stashed in the
|
|
||||||
// address field of the secondary relocation, but we can't reverse
|
|
||||||
// engineer the constant offset from it without decoding the movw/movt
|
|
||||||
// instruction to find the other half in its immediate field.
|
|
||||||
|
|
||||||
// ARM_RELOC_HALF_SECTDIFF encodes the second section in the
|
|
||||||
// symbol/section pointer of the follow-on relocation.
|
|
||||||
if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
|
|
||||||
fmt << "-";
|
|
||||||
printRelocationTargetName(this, RENext, fmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt << ")";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
printRelocationTargetName(this, RE, fmt);
|
|
||||||
|
|
||||||
fmt.flush();
|
|
||||||
Result.append(fmtbuf.begin(), fmtbuf.end());
|
|
||||||
return object_error::success;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
|
std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
|
||||||
bool &Result) const {
|
bool &Result) const {
|
||||||
unsigned Arch = getArch();
|
unsigned Arch = getArch();
|
||||||
|
@ -230,12 +230,6 @@ const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
|
|||||||
|
|
||||||
// NOTE: Caller takes ownership of returned string.
|
// NOTE: Caller takes ownership of returned string.
|
||||||
const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
|
const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
|
||||||
SmallVector<char, 0> ret;
|
return strdup("");
|
||||||
if (std::error_code ec = (*unwrap(RI))->getValueString(ret))
|
|
||||||
report_fatal_error(ec.message());
|
|
||||||
|
|
||||||
char *str = static_cast<char*>(malloc(ret.size()));
|
|
||||||
std::copy(ret.begin(), ret.end(), str);
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "llvm/MC/MCRelocationInfo.h"
|
#include "llvm/MC/MCRelocationInfo.h"
|
||||||
#include "llvm/MC/MCSubtargetInfo.h"
|
#include "llvm/MC/MCSubtargetInfo.h"
|
||||||
#include "llvm/Object/Archive.h"
|
#include "llvm/Object/Archive.h"
|
||||||
|
#include "llvm/Object/ELFObjectFile.h"
|
||||||
#include "llvm/Object/COFF.h"
|
#include "llvm/Object/COFF.h"
|
||||||
#include "llvm/Object/MachO.h"
|
#include "llvm/Object/MachO.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
@ -281,6 +282,384 @@ PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
static const typename ELFObjectFile<ELFT>::Elf_Rel *
|
||||||
|
getRel(const ELFFile<ELFT> &EF, DataRefImpl Rel) {
|
||||||
|
typedef typename ELFObjectFile<ELFT>::Elf_Rel Elf_Rel;
|
||||||
|
return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
static const typename ELFObjectFile<ELFT>::Elf_Rela *
|
||||||
|
getRela(const ELFFile<ELFT> &EF, DataRefImpl Rela) {
|
||||||
|
typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
|
||||||
|
return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ELFT>
|
||||||
|
static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
|
||||||
|
DataRefImpl Rel,
|
||||||
|
SmallVectorImpl<char> &Result) {
|
||||||
|
typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
|
||||||
|
typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
|
||||||
|
const ELFFile<ELFT> &EF = *Obj->getELFFile();
|
||||||
|
|
||||||
|
const Elf_Shdr *sec = EF.getSection(Rel.d.a);
|
||||||
|
uint8_t type;
|
||||||
|
StringRef res;
|
||||||
|
int64_t addend = 0;
|
||||||
|
uint16_t symbol_index = 0;
|
||||||
|
switch (sec->sh_type) {
|
||||||
|
default:
|
||||||
|
return object_error::parse_failed;
|
||||||
|
case ELF::SHT_REL: {
|
||||||
|
type = getRel(EF, Rel)->getType(EF.isMips64EL());
|
||||||
|
symbol_index = getRel(EF, Rel)->getSymbol(EF.isMips64EL());
|
||||||
|
// TODO: Read implicit addend from section data.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ELF::SHT_RELA: {
|
||||||
|
type = getRela(EF, Rel)->getType(EF.isMips64EL());
|
||||||
|
symbol_index = getRela(EF, Rel)->getSymbol(EF.isMips64EL());
|
||||||
|
addend = getRela(EF, Rel)->r_addend;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const Elf_Sym *symb =
|
||||||
|
EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index);
|
||||||
|
ErrorOr<StringRef> SymName =
|
||||||
|
EF.getSymbolName(EF.getSection(sec->sh_link), symb);
|
||||||
|
if (!SymName)
|
||||||
|
return SymName.getError();
|
||||||
|
switch (EF.getHeader()->e_machine) {
|
||||||
|
case ELF::EM_X86_64:
|
||||||
|
switch (type) {
|
||||||
|
case ELF::R_X86_64_PC8:
|
||||||
|
case ELF::R_X86_64_PC16:
|
||||||
|
case ELF::R_X86_64_PC32: {
|
||||||
|
std::string fmtbuf;
|
||||||
|
raw_string_ostream fmt(fmtbuf);
|
||||||
|
fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P";
|
||||||
|
fmt.flush();
|
||||||
|
Result.append(fmtbuf.begin(), fmtbuf.end());
|
||||||
|
} break;
|
||||||
|
case ELF::R_X86_64_8:
|
||||||
|
case ELF::R_X86_64_16:
|
||||||
|
case ELF::R_X86_64_32:
|
||||||
|
case ELF::R_X86_64_32S:
|
||||||
|
case ELF::R_X86_64_64: {
|
||||||
|
std::string fmtbuf;
|
||||||
|
raw_string_ostream fmt(fmtbuf);
|
||||||
|
fmt << *SymName << (addend < 0 ? "" : "+") << addend;
|
||||||
|
fmt.flush();
|
||||||
|
Result.append(fmtbuf.begin(), fmtbuf.end());
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
res = "Unknown";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ELF::EM_AARCH64: {
|
||||||
|
std::string fmtbuf;
|
||||||
|
raw_string_ostream fmt(fmtbuf);
|
||||||
|
fmt << *SymName;
|
||||||
|
if (addend != 0)
|
||||||
|
fmt << (addend < 0 ? "" : "+") << addend;
|
||||||
|
fmt.flush();
|
||||||
|
Result.append(fmtbuf.begin(), fmtbuf.end());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ELF::EM_386:
|
||||||
|
case ELF::EM_ARM:
|
||||||
|
case ELF::EM_HEXAGON:
|
||||||
|
case ELF::EM_MIPS:
|
||||||
|
res = *SymName;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = "Unknown";
|
||||||
|
}
|
||||||
|
if (Result.empty())
|
||||||
|
Result.append(res.begin(), res.end());
|
||||||
|
return object_error::success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::error_code getRelocationValueString(const ELFObjectFileBase *Obj,
|
||||||
|
const RelocationRef &RelRef,
|
||||||
|
SmallVectorImpl<char> &Result) {
|
||||||
|
DataRefImpl Rel = RelRef.getRawDataRefImpl();
|
||||||
|
if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
|
||||||
|
return getRelocationValueString(ELF32LE, Rel, Result);
|
||||||
|
if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
|
||||||
|
return getRelocationValueString(ELF64LE, Rel, Result);
|
||||||
|
if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
|
||||||
|
return getRelocationValueString(ELF32BE, Rel, Result);
|
||||||
|
auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
|
||||||
|
return getRelocationValueString(ELF64BE, Rel, Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::error_code getRelocationValueString(const COFFObjectFile *Obj,
|
||||||
|
const RelocationRef &Rel,
|
||||||
|
SmallVectorImpl<char> &Result) {
|
||||||
|
symbol_iterator SymI = Rel.getSymbol();
|
||||||
|
StringRef SymName;
|
||||||
|
if (std::error_code EC = SymI->getName(SymName))
|
||||||
|
return EC;
|
||||||
|
Result.append(SymName.begin(), SymName.end());
|
||||||
|
return object_error::success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printRelocationTargetName(const MachOObjectFile *O,
|
||||||
|
const MachO::any_relocation_info &RE,
|
||||||
|
raw_string_ostream &fmt) {
|
||||||
|
bool IsScattered = O->isRelocationScattered(RE);
|
||||||
|
|
||||||
|
// Target of a scattered relocation is an address. In the interest of
|
||||||
|
// generating pretty output, scan through the symbol table looking for a
|
||||||
|
// symbol that aligns with that address. If we find one, print it.
|
||||||
|
// Otherwise, we just print the hex address of the target.
|
||||||
|
if (IsScattered) {
|
||||||
|
uint32_t Val = O->getPlainRelocationSymbolNum(RE);
|
||||||
|
|
||||||
|
for (const SymbolRef &Symbol : O->symbols()) {
|
||||||
|
std::error_code ec;
|
||||||
|
uint64_t Addr;
|
||||||
|
StringRef Name;
|
||||||
|
|
||||||
|
if ((ec = Symbol.getAddress(Addr)))
|
||||||
|
report_fatal_error(ec.message());
|
||||||
|
if (Addr != Val)
|
||||||
|
continue;
|
||||||
|
if ((ec = Symbol.getName(Name)))
|
||||||
|
report_fatal_error(ec.message());
|
||||||
|
fmt << Name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we couldn't find a symbol that this relocation refers to, try
|
||||||
|
// to find a section beginning instead.
|
||||||
|
for (const SectionRef &Section : O->sections()) {
|
||||||
|
std::error_code ec;
|
||||||
|
|
||||||
|
StringRef Name;
|
||||||
|
uint64_t Addr = Section.getAddress();
|
||||||
|
if (Addr != Val)
|
||||||
|
continue;
|
||||||
|
if ((ec = Section.getName(Name)))
|
||||||
|
report_fatal_error(ec.message());
|
||||||
|
fmt << Name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt << format("0x%x", Val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef S;
|
||||||
|
bool isExtern = O->getPlainRelocationExternal(RE);
|
||||||
|
uint64_t Val = O->getPlainRelocationSymbolNum(RE);
|
||||||
|
|
||||||
|
if (isExtern) {
|
||||||
|
symbol_iterator SI = O->symbol_begin();
|
||||||
|
advance(SI, Val);
|
||||||
|
SI->getName(S);
|
||||||
|
} else {
|
||||||
|
section_iterator SI = O->section_begin();
|
||||||
|
// Adjust for the fact that sections are 1-indexed.
|
||||||
|
advance(SI, Val - 1);
|
||||||
|
SI->getName(S);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt << S;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
|
||||||
|
const RelocationRef &RelRef,
|
||||||
|
SmallVectorImpl<char> &Result) {
|
||||||
|
DataRefImpl Rel = RelRef.getRawDataRefImpl();
|
||||||
|
MachO::any_relocation_info RE = Obj->getRelocation(Rel);
|
||||||
|
|
||||||
|
unsigned Arch = Obj->getArch();
|
||||||
|
|
||||||
|
std::string fmtbuf;
|
||||||
|
raw_string_ostream fmt(fmtbuf);
|
||||||
|
unsigned Type = Obj->getAnyRelocationType(RE);
|
||||||
|
bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
|
||||||
|
|
||||||
|
// Determine any addends that should be displayed with the relocation.
|
||||||
|
// These require decoding the relocation type, which is triple-specific.
|
||||||
|
|
||||||
|
// X86_64 has entirely custom relocation types.
|
||||||
|
if (Arch == Triple::x86_64) {
|
||||||
|
bool isPCRel = Obj->getAnyRelocationPCRel(RE);
|
||||||
|
|
||||||
|
switch (Type) {
|
||||||
|
case MachO::X86_64_RELOC_GOT_LOAD:
|
||||||
|
case MachO::X86_64_RELOC_GOT: {
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
fmt << "@GOT";
|
||||||
|
if (isPCRel)
|
||||||
|
fmt << "PCREL";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MachO::X86_64_RELOC_SUBTRACTOR: {
|
||||||
|
DataRefImpl RelNext = Rel;
|
||||||
|
Obj->moveRelocationNext(RelNext);
|
||||||
|
MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
|
||||||
|
|
||||||
|
// X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
|
||||||
|
// X86_64_RELOC_UNSIGNED.
|
||||||
|
// NOTE: Scattered relocations don't exist on x86_64.
|
||||||
|
unsigned RType = Obj->getAnyRelocationType(RENext);
|
||||||
|
if (RType != MachO::X86_64_RELOC_UNSIGNED)
|
||||||
|
report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
|
||||||
|
"X86_64_RELOC_SUBTRACTOR.");
|
||||||
|
|
||||||
|
// The X86_64_RELOC_UNSIGNED contains the minuend symbol;
|
||||||
|
// X86_64_RELOC_SUBTRACTOR contains the subtrahend.
|
||||||
|
printRelocationTargetName(Obj, RENext, fmt);
|
||||||
|
fmt << "-";
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MachO::X86_64_RELOC_TLV:
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
fmt << "@TLV";
|
||||||
|
if (isPCRel)
|
||||||
|
fmt << "P";
|
||||||
|
break;
|
||||||
|
case MachO::X86_64_RELOC_SIGNED_1:
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
fmt << "-1";
|
||||||
|
break;
|
||||||
|
case MachO::X86_64_RELOC_SIGNED_2:
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
fmt << "-2";
|
||||||
|
break;
|
||||||
|
case MachO::X86_64_RELOC_SIGNED_4:
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
fmt << "-4";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// X86 and ARM share some relocation types in common.
|
||||||
|
} else if (Arch == Triple::x86 || Arch == Triple::arm ||
|
||||||
|
Arch == Triple::ppc) {
|
||||||
|
// Generic relocation types...
|
||||||
|
switch (Type) {
|
||||||
|
case MachO::GENERIC_RELOC_PAIR: // prints no info
|
||||||
|
return object_error::success;
|
||||||
|
case MachO::GENERIC_RELOC_SECTDIFF: {
|
||||||
|
DataRefImpl RelNext = Rel;
|
||||||
|
Obj->moveRelocationNext(RelNext);
|
||||||
|
MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
|
||||||
|
|
||||||
|
// X86 sect diff's must be followed by a relocation of type
|
||||||
|
// GENERIC_RELOC_PAIR.
|
||||||
|
unsigned RType = Obj->getAnyRelocationType(RENext);
|
||||||
|
|
||||||
|
if (RType != MachO::GENERIC_RELOC_PAIR)
|
||||||
|
report_fatal_error("Expected GENERIC_RELOC_PAIR after "
|
||||||
|
"GENERIC_RELOC_SECTDIFF.");
|
||||||
|
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
fmt << "-";
|
||||||
|
printRelocationTargetName(Obj, RENext, fmt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Arch == Triple::x86 || Arch == Triple::ppc) {
|
||||||
|
switch (Type) {
|
||||||
|
case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
|
||||||
|
DataRefImpl RelNext = Rel;
|
||||||
|
Obj->moveRelocationNext(RelNext);
|
||||||
|
MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
|
||||||
|
|
||||||
|
// X86 sect diff's must be followed by a relocation of type
|
||||||
|
// GENERIC_RELOC_PAIR.
|
||||||
|
unsigned RType = Obj->getAnyRelocationType(RENext);
|
||||||
|
if (RType != MachO::GENERIC_RELOC_PAIR)
|
||||||
|
report_fatal_error("Expected GENERIC_RELOC_PAIR after "
|
||||||
|
"GENERIC_RELOC_LOCAL_SECTDIFF.");
|
||||||
|
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
fmt << "-";
|
||||||
|
printRelocationTargetName(Obj, RENext, fmt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MachO::GENERIC_RELOC_TLV: {
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
fmt << "@TLV";
|
||||||
|
if (IsPCRel)
|
||||||
|
fmt << "P";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
}
|
||||||
|
} else { // ARM-specific relocations
|
||||||
|
switch (Type) {
|
||||||
|
case MachO::ARM_RELOC_HALF:
|
||||||
|
case MachO::ARM_RELOC_HALF_SECTDIFF: {
|
||||||
|
// Half relocations steal a bit from the length field to encode
|
||||||
|
// whether this is an upper16 or a lower16 relocation.
|
||||||
|
bool isUpper = Obj->getAnyRelocationLength(RE) >> 1;
|
||||||
|
|
||||||
|
if (isUpper)
|
||||||
|
fmt << ":upper16:(";
|
||||||
|
else
|
||||||
|
fmt << ":lower16:(";
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
|
||||||
|
DataRefImpl RelNext = Rel;
|
||||||
|
Obj->moveRelocationNext(RelNext);
|
||||||
|
MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
|
||||||
|
|
||||||
|
// ARM half relocs must be followed by a relocation of type
|
||||||
|
// ARM_RELOC_PAIR.
|
||||||
|
unsigned RType = Obj->getAnyRelocationType(RENext);
|
||||||
|
if (RType != MachO::ARM_RELOC_PAIR)
|
||||||
|
report_fatal_error("Expected ARM_RELOC_PAIR after "
|
||||||
|
"ARM_RELOC_HALF");
|
||||||
|
|
||||||
|
// NOTE: The half of the target virtual address is stashed in the
|
||||||
|
// address field of the secondary relocation, but we can't reverse
|
||||||
|
// engineer the constant offset from it without decoding the movw/movt
|
||||||
|
// instruction to find the other half in its immediate field.
|
||||||
|
|
||||||
|
// ARM_RELOC_HALF_SECTDIFF encodes the second section in the
|
||||||
|
// symbol/section pointer of the follow-on relocation.
|
||||||
|
if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
|
||||||
|
fmt << "-";
|
||||||
|
printRelocationTargetName(Obj, RENext, fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt << ")";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: { printRelocationTargetName(Obj, RE, fmt); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
printRelocationTargetName(Obj, RE, fmt);
|
||||||
|
|
||||||
|
fmt.flush();
|
||||||
|
Result.append(fmtbuf.begin(), fmtbuf.end());
|
||||||
|
return object_error::success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::error_code getRelocationValueString(const RelocationRef &Rel,
|
||||||
|
SmallVectorImpl<char> &Result) {
|
||||||
|
const ObjectFile *Obj = Rel.getObjectFile();
|
||||||
|
if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
|
||||||
|
return getRelocationValueString(ELF, Rel, Result);
|
||||||
|
if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
|
||||||
|
return getRelocationValueString(COFF, Rel, Result);
|
||||||
|
auto *MachO = cast<MachOObjectFile>(Obj);
|
||||||
|
return getRelocationValueString(MachO, Rel, Result);
|
||||||
|
}
|
||||||
|
|
||||||
static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
||||||
const Target *TheTarget = getTarget(Obj);
|
const Target *TheTarget = getTarget(Obj);
|
||||||
// getTarget() will have already issued a diagnostic if necessary, so
|
// getTarget() will have already issued a diagnostic if necessary, so
|
||||||
@ -491,8 +870,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
|||||||
// Stop when rel_cur's address is past the current instruction.
|
// Stop when rel_cur's address is past the current instruction.
|
||||||
if (addr >= Index + Size) break;
|
if (addr >= Index + Size) break;
|
||||||
if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
|
if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
|
||||||
if (error(rel_cur->getValueString(val))) goto skip_print_rel;
|
if (error(getRelocationValueString(*rel_cur, val)))
|
||||||
|
goto skip_print_rel;
|
||||||
outs() << format(Fmt.data(), SectionAddr + addr) << name
|
outs() << format(Fmt.data(), SectionAddr + addr) << name
|
||||||
<< "\t" << val << "\n";
|
<< "\t" << val << "\n";
|
||||||
|
|
||||||
@ -532,7 +911,7 @@ void llvm::PrintRelocations(const ObjectFile *Obj) {
|
|||||||
continue;
|
continue;
|
||||||
if (error(Reloc.getOffset(address)))
|
if (error(Reloc.getOffset(address)))
|
||||||
continue;
|
continue;
|
||||||
if (error(Reloc.getValueString(valuestr)))
|
if (error(getRelocationValueString(Reloc, valuestr)))
|
||||||
continue;
|
continue;
|
||||||
outs() << format(Fmt.data(), address) << " " << relocname << " "
|
outs() << format(Fmt.data(), address) << " " << relocname << " "
|
||||||
<< valuestr << "\n";
|
<< valuestr << "\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user