mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Add the code and test cases for 32-bit Intel to llvm-objdump’s Mach-O symbolizer.
llvm-svn: 221211
This commit is contained in:
parent
f34b00f529
commit
8bfb36ce4f
@ -322,6 +322,8 @@ public:
|
||||
const MachO::any_relocation_info &RE) const;
|
||||
uint32_t getScatteredRelocationValue(
|
||||
const MachO::any_relocation_info &RE) const;
|
||||
uint32_t getScatteredRelocationType(
|
||||
const MachO::any_relocation_info &RE) const;
|
||||
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const;
|
||||
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const;
|
||||
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const;
|
||||
|
@ -2150,6 +2150,11 @@ uint32_t MachOObjectFile::getScatteredRelocationValue(
|
||||
return RE.r_word1;
|
||||
}
|
||||
|
||||
uint32_t MachOObjectFile::getScatteredRelocationType(
|
||||
const MachO::any_relocation_info &RE) const {
|
||||
return (RE.r_word0 >> 24) & 0xf;
|
||||
}
|
||||
|
||||
unsigned MachOObjectFile::getAnyRelocationAddress(
|
||||
const MachO::any_relocation_info &RE) const {
|
||||
if (isRelocationScattered(RE))
|
||||
|
BIN
test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386
Executable file
BIN
test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386
Executable file
Binary file not shown.
BIN
test/tools/llvm-objdump/X86/Inputs/hello.obj.macho-i386
Normal file
BIN
test/tools/llvm-objdump/X86/Inputs/hello.obj.macho-i386
Normal file
Binary file not shown.
@ -4,6 +4,9 @@
|
||||
// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/ObjC.exe.macho-x86_64 | FileCheck %s -check-prefix=ObjC-EXE
|
||||
// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/hello_cpp.exe.macho-x86_64 | FileCheck %s -check-prefix=CXX-EXE
|
||||
|
||||
// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/hello.obj.macho-i386 | FileCheck %s -check-prefix=i386-OBJ
|
||||
// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/hello.exe.macho-i386 | FileCheck %s -check-prefix=i386-EXE
|
||||
|
||||
OBJ: 0000000000000008 leaq L_.str(%rip), %rax ## literal pool for: "Hello world\n"
|
||||
OBJ: 0000000000000026 callq _printf
|
||||
|
||||
@ -29,3 +32,7 @@ CXX-EXE: 00000001000014cb callq __ZNSt3__116__pad_and_outputIcNS_11char_traitsIc
|
||||
|
||||
// FIXME: Demangler depends on host's <cxxabi.h>.
|
||||
// std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char)
|
||||
|
||||
i386-OBJ: 0000002f calll _printf
|
||||
|
||||
i386-EXE: 00001f6f calll 0x1f84 ## symbol stub for: _printf
|
||||
|
@ -0,0 +1,10 @@
|
||||
# RUN: llvm-mc < %s -triple x86_64-apple-darwin -filetype=obj | llvm-objdump -m -d - | FileCheck %s
|
||||
|
||||
nop
|
||||
x:
|
||||
leal x-y(%eax), %ebx
|
||||
.data
|
||||
y:
|
||||
.quad 0
|
||||
|
||||
# CHECK: leal x-y(%eax), %ebx
|
@ -248,6 +248,21 @@ struct DisassembleInfo {
|
||||
BindTable *bindtable;
|
||||
};
|
||||
|
||||
// GuessSymbolName is passed the address of what might be a symbol and a
|
||||
// pointer to the DisassembleInfo struct. It returns the name of a symbol
|
||||
// with that address or nullptr if no symbol is found with that address.
|
||||
static const char *GuessSymbolName(uint64_t value,
|
||||
struct DisassembleInfo *info) {
|
||||
const char *SymbolName = nullptr;
|
||||
// A DenseMap can't lookup up some values.
|
||||
if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
|
||||
StringRef name = info->AddrMap->lookup(value);
|
||||
if (!name.empty())
|
||||
SymbolName = name.data();
|
||||
}
|
||||
return SymbolName;
|
||||
}
|
||||
|
||||
// SymbolizerGetOpInfo() is the operand information call back function.
|
||||
// This is called to get the symbolic information for operand(s) of an
|
||||
// instruction when it is being done. This routine does this from
|
||||
@ -281,6 +296,83 @@ int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
|
||||
|
||||
unsigned int Arch = info->O->getArch();
|
||||
if (Arch == Triple::x86) {
|
||||
if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
|
||||
return 0;
|
||||
// First search the section's relocation entries (if any) for an entry
|
||||
// for this section offset.
|
||||
uint32_t sect_addr = info->S.getAddress();
|
||||
uint32_t sect_offset = (Pc + Offset) - sect_addr;
|
||||
bool reloc_found = false;
|
||||
DataRefImpl Rel;
|
||||
MachO::any_relocation_info RE;
|
||||
bool isExtern = false;
|
||||
SymbolRef Symbol;
|
||||
bool r_scattered = false;
|
||||
uint32_t r_value, pair_r_value, r_type;
|
||||
for (const RelocationRef &Reloc : info->S.relocations()) {
|
||||
uint64_t RelocOffset;
|
||||
Reloc.getOffset(RelocOffset);
|
||||
if (RelocOffset == sect_offset) {
|
||||
Rel = Reloc.getRawDataRefImpl();
|
||||
RE = info->O->getRelocation(Rel);
|
||||
r_scattered = info->O->isRelocationScattered(RE);
|
||||
if (r_scattered) {
|
||||
r_value = info->O->getScatteredRelocationValue(RE);
|
||||
r_type = info->O->getScatteredRelocationType(RE);
|
||||
if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
|
||||
r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
|
||||
DataRefImpl RelNext = Rel;
|
||||
info->O->moveRelocationNext(RelNext);
|
||||
MachO::any_relocation_info RENext;
|
||||
RENext = info->O->getRelocation(RelNext);
|
||||
if (info->O->isRelocationScattered(RENext))
|
||||
pair_r_value = info->O->getPlainRelocationSymbolNum(RENext);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
isExtern = info->O->getPlainRelocationExternal(RE);
|
||||
if (isExtern) {
|
||||
symbol_iterator RelocSym = Reloc.getSymbol();
|
||||
Symbol = *RelocSym;
|
||||
}
|
||||
}
|
||||
reloc_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (reloc_found && isExtern) {
|
||||
StringRef SymName;
|
||||
Symbol.getName(SymName);
|
||||
const char *name = SymName.data();
|
||||
op_info->AddSymbol.Present = 1;
|
||||
op_info->AddSymbol.Name = name;
|
||||
// For i386 extern relocation entries the value in the instruction is
|
||||
// the offset from the symbol, and value is already set in op_info->Value.
|
||||
return 1;
|
||||
}
|
||||
if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
|
||||
r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
|
||||
const char *add = GuessSymbolName(r_value, info);
|
||||
const char *sub = GuessSymbolName(pair_r_value, info);
|
||||
uint32_t offset = value - (r_value - pair_r_value);
|
||||
op_info->AddSymbol.Present = 1;
|
||||
if (add != nullptr)
|
||||
op_info->AddSymbol.Name = add;
|
||||
else
|
||||
op_info->AddSymbol.Value = r_value;
|
||||
op_info->SubtractSymbol.Present = 1;
|
||||
if (sub != nullptr)
|
||||
op_info->SubtractSymbol.Name = sub;
|
||||
else
|
||||
op_info->SubtractSymbol.Value = pair_r_value;
|
||||
op_info->Value = offset;
|
||||
return 1;
|
||||
}
|
||||
// TODO:
|
||||
// Second search the external relocation entries of a fully linked image
|
||||
// (if any) for an entry that matches this segment offset.
|
||||
// uint32_t seg_offset = (Pc + Offset);
|
||||
return 0;
|
||||
} else if (Arch == Triple::x86_64) {
|
||||
if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
|
||||
@ -716,13 +808,7 @@ const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
|
||||
//
|
||||
// NOTE: need add passing the ReferenceValue to this routine. Then that code
|
||||
// would simply be this:
|
||||
//
|
||||
// if (ReferenceValue != 0xffffffffffffffffLLU &&
|
||||
// ReferenceValue != 0xfffffffffffffffeLLU) {
|
||||
// StringRef name = info->AddrMap->lookup(ReferenceValue);
|
||||
// if (!name.empty())
|
||||
// SymbolName = name.data();
|
||||
// }
|
||||
// SymbolName = GuessSymbolName(ReferenceValue, info);
|
||||
|
||||
return SymbolName;
|
||||
}
|
||||
@ -1071,13 +1157,7 @@ const char *SymbolizerSymbolLookUp(void *DisInfo, uint64_t ReferenceValue,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *SymbolName = nullptr;
|
||||
if (ReferenceValue != 0xffffffffffffffffULL &&
|
||||
ReferenceValue != 0xfffffffffffffffeULL) {
|
||||
StringRef name = info->AddrMap->lookup(ReferenceValue);
|
||||
if (!name.empty())
|
||||
SymbolName = name.data();
|
||||
}
|
||||
const char *SymbolName = GuessSymbolName(ReferenceValue, info);
|
||||
|
||||
if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
|
||||
*ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
|
||||
|
Loading…
Reference in New Issue
Block a user