Skip to content

Commit

Permalink
support LLVM36 disassembly
Browse files Browse the repository at this point in the history
llvm36 has a bug where it ignores the Address offset when computing the memory location to disassemble. this commit works around that change in LLVM in a way that will work on any version of llvm
  • Loading branch information
vtjnash committed Mar 1, 2015
1 parent 949f202 commit 1d0b067
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 35 deletions.
1 change: 1 addition & 0 deletions deps/checksums/llvm-3.6.0.src.tar.xz/md5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f1e14e949f8df3047c59816c55278cec
1 change: 1 addition & 0 deletions deps/checksums/llvm-3.6.0.src.tar.xz/sha512
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ca492b7d86333f05930dc849c7a8beff981da51ca174cd844650b516d0a592a2c3837d5a8a9b62713c0f29292b845f27ef0ec361809e325c6b60cbbcd3f20357
19 changes: 10 additions & 9 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -820,15 +820,16 @@ void jl_extern_c(jl_function_t *f, jl_value_t *rt, jl_value_t *argt, char *name)
// --- native code info, and dump function to IR and ASM ---
extern void RegisterJuliaJITEventListener();

extern int jl_get_llvmf_info(size_t fptr, uint64_t *symsize,
extern int jl_get_llvmf_info(uint64_t fptr, uint64_t *symsize, uint64_t *slide,
#ifdef USE_MCJIT
const object::ObjectFile **object);
const object::ObjectFile **object
#else
std::vector<JITEvent_EmittedFunctionDetails::LineStart> *lines);
std::vector<JITEvent_EmittedFunctionDetails::LineStart> *lines
#endif
);

extern "C"
void jl_dump_function_asm(const char *Fptr, size_t Fsize,
void jl_dump_function_asm(uintptr_t Fptr, size_t Fsize, size_t slide,
#ifdef USE_MCJIT
const object::ObjectFile *objectfile,
#else
Expand All @@ -846,17 +847,17 @@ const jl_value_t *jl_dump_llvmf(void *f, bool dumpasm)
llvmf->print(stream);
}
else {
uint64_t symsize;
uint64_t symsize, slide;
#ifdef USE_MCJIT
size_t fptr = (size_t)jl_ExecutionEngine->getFunctionAddress(llvmf->getName());
uint64_t fptr = jl_ExecutionEngine->getFunctionAddress(llvmf->getName());
const object::ObjectFile *object;
#else
size_t fptr = (size_t)jl_ExecutionEngine->getPointerToFunction(llvmf);
uint64_t fptr = (uintptr_t)jl_ExecutionEngine->getPointerToFunction(llvmf);
std::vector<JITEvent_EmittedFunctionDetails::LineStart> object;
#endif
assert(fptr != 0);
if (jl_get_llvmf_info(fptr, &symsize, &object))
jl_dump_function_asm((char *)fptr, symsize, object, fstream);
if (jl_get_llvmf_info(fptr, &symsize, &slide, &object))
jl_dump_function_asm(fptr, symsize, slide, object, fstream);
else
jl_printf(JL_STDERR, "Warning: Unable to find function pointer\n");
fstream.flush();
Expand Down
31 changes: 22 additions & 9 deletions src/debuginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ struct FuncInfo {
struct ObjectInfo {
const object::ObjectFile* object;
size_t size;
#ifdef LLVM36
size_t slide;
#endif
#ifdef _OS_DARWIN_
const char *name;
#endif
Expand Down Expand Up @@ -208,16 +211,21 @@ class JuliaJITEventListener: public JITEventListener
#ifdef LLVM36
object::section_iterator Section = obj.section_begin();
object::section_iterator EndSection = obj.section_end();
uint64_t SectionAddr = 0;
StringRef sName;
#else
object::section_iterator Section = obj.begin_sections();
object::section_iterator EndSection = obj.end_sections();
bool isText;
#endif
#ifndef _OS_LINUX_
StringRef sName;
#endif
#endif

#ifdef _OS_WINDOWS_
#ifndef LLVM36
uint64_t SectionAddr = 0;
#endif
uint64_t SectionSize = 0;
uint64_t SectionAddrCheck = 0; // assert that all of the Sections are at the same location
#endif
Expand Down Expand Up @@ -296,13 +304,14 @@ class JuliaJITEventListener: public JITEventListener
if (Section == EndSection) continue;
#if defined(LLVM36)
if (!Section->isText()) continue;
Section->getName(sName);
SectionAddr = L.getSectionLoadAddress(sName);
Addr += SectionAddr;
#else
if (Section->isText(isText) || !isText) continue;
#endif
#ifdef _OS_DARWIN_
#if defined(LLVM36)
Section->getName(sName);
Addr += L.getSectionLoadAddress(sName);
sym_iter.getName(sName);
if (sName[0] == '_') {
sName = sName.substr(1);
Expand All @@ -319,9 +328,6 @@ class JuliaJITEventListener: public JITEventListener
#elif defined(_OS_WINDOWS_)
#if defined(LLVM36)
SectionSize = Section->getSize();
Section->getName(sName);
SectionAddr = L.getSectionLoadAddress(sName);
Addr += SectionAddr;
#else
Section->getAddress(SectionAddr);
Section->getSize(SectionSize);
Expand All @@ -345,6 +351,9 @@ class JuliaJITEventListener: public JITEventListener
obj.getObjectFile();
#endif
ObjectInfo tmp = {objfile, (size_t)Size
#ifdef LLVM36
,SectionAddr
#endif
#ifdef _OS_DARWIN_
,strndup(sName.data(), sName.size())
#endif
Expand Down Expand Up @@ -709,6 +718,7 @@ void jl_getFunctionInfo(const char **name, size_t *line, const char **filename,
#else
#ifdef LLVM36
DIContext *context = DIContext::getDWARFContext(*it->second.object);
pointer -= (*it).second.slide;
#else
DIContext *context = DIContext::getDWARFContext(const_cast<object::ObjectFile*>(it->second.object));
#endif
Expand Down Expand Up @@ -775,12 +785,13 @@ void jl_getFunctionInfo(const char **name, size_t *line, const char **filename,
jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);
}

int jl_get_llvmf_info(size_t fptr, uint64_t *symsize,
int jl_get_llvmf_info(uint64_t fptr, uint64_t *symsize, uint64_t *slide,
#ifdef USE_MCJIT
const object::ObjectFile **object)
const object::ObjectFile **object
#else
std::vector<JITEvent_EmittedFunctionDetails::LineStart> *lines)
std::vector<JITEvent_EmittedFunctionDetails::LineStart> *lines
#endif
)
{
#ifndef USE_MCJIT
std::map<size_t, FuncInfo, revcomp> &fmap = jl_jit_events->getMap();
Expand All @@ -789,6 +800,7 @@ int jl_get_llvmf_info(size_t fptr, uint64_t *symsize,
if (fit != fmap.end()) {
*symsize = fit->second.lengthAdr;
*lines = fit->second.lines;
*slide = 0;
return 1;
}
return 0;
Expand All @@ -799,6 +811,7 @@ int jl_get_llvmf_info(size_t fptr, uint64_t *symsize,
if (fit != objmap.end()) {
*symsize = fit->second.size;
*object = fit->second.object;
*slide = fit->second.slide;
return 1;
}
return 0;
Expand Down
48 changes: 31 additions & 17 deletions src/disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class FuncMCView : public MemoryObject {
// ArrayRef-like accessors:
const char operator[] (const size_t idx) const { return Fptr[idx]; }
uint64_t size() const { return Fsize; }
const uint8_t *data() const { return (const uint8_t*)Fptr; }
FuncMCView slice(unsigned N) const { return FuncMCView(Fptr+N, Fsize-N); }
};
#endif

Expand All @@ -125,17 +127,28 @@ class SymbolTable {
MCContext& Ctx;
const FuncMCView &MemObj;
int Pass;
uint64_t ip; // virtual instruction pointer of the current instruction
public:
SymbolTable(MCContext &Ctx, const FuncMCView &MemObj):
Ctx(Ctx), MemObj(MemObj) {}
Ctx(Ctx), MemObj(MemObj), ip(0) {}
const FuncMCView &getMemoryObject() const { return MemObj; }
void setPass(int Pass) { this->Pass = Pass; }
int getPass() const { return Pass; }
void insertAddress(uint64_t addr);
// void createSymbol(const char *name, uint64_t addr);
void createSymbols();
const char *lookupSymbol(uint64_t addr);
void setIP(uint64_t addr);
uint64_t getIP() const;
};
void SymbolTable::setIP(uint64_t addr)
{
ip = addr;
}
uint64_t SymbolTable::getIP() const
{
return ip;
}
// Insert an address
void SymbolTable::insertAddress(uint64_t addr)
{
Expand All @@ -152,7 +165,7 @@ void SymbolTable::createSymbols()
{
for (TableType::iterator isymb = Table.begin(), esymb = Table.end();
isymb != esymb; ++isymb) {
uint64_t addr = isymb->first;
uint64_t addr = isymb->first - ip;
std::ostringstream name;
name << "L" << addr;
MCSymbol *symb = Ctx.GetOrCreateSymbol(StringRef(name.str()));
Expand All @@ -177,7 +190,7 @@ const char *SymbolLookup(void *DisInfo,
SymbolTable *SymTab = (SymbolTable*)DisInfo;
if (SymTab->getPass() != 0) {
if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
uint64_t addr = ReferenceValue;
uint64_t addr = ReferenceValue + SymTab->getIP();
const char *symbolName = SymTab->lookupSymbol(addr);
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
*ReferenceName = NULL;
Expand All @@ -197,6 +210,7 @@ int OpInfoLookup(void *DisInfo, uint64_t PC,
int TagType, void *TagBuf)
{
SymbolTable *SymTab = (SymbolTable*)DisInfo;
PC += SymTab->getIP() - (uint64_t)(uintptr_t)SymTab->getMemoryObject().data(); // add offset from MemoryObject base
if (TagType != 1)
return 0; // Unknown data format
LLVMOpInfo1 *info = (LLVMOpInfo1*)TagBuf;
Expand Down Expand Up @@ -231,7 +245,7 @@ int OpInfoLookup(void *DisInfo, uint64_t PC,
} // namespace

extern "C"
void jl_dump_function_asm(const char *Fptr, size_t Fsize,
void jl_dump_function_asm(uintptr_t Fptr, size_t Fsize, size_t slide,
#ifndef USE_MCJIT
std::vector<JITEvent_EmittedFunctionDetails::LineStart> lineinfo,
#else
Expand Down Expand Up @@ -308,7 +322,7 @@ void jl_dump_function_asm(const char *Fptr, size_t Fsize,
return;
}

unsigned OutputAsmVariant = 1;
unsigned OutputAsmVariant = 1; // GCC or ATT-style asm
bool ShowEncoding = false;
bool ShowInst = false;

Expand Down Expand Up @@ -351,7 +365,7 @@ void jl_dump_function_asm(const char *Fptr, size_t Fsize,
#ifdef LLVM36
ArrayRef<uint8_t> memoryObject(const_cast<uint8_t*>((const uint8_t*)Fptr),Fsize);
#else
FuncMCView memoryObject(Fptr, Fsize);
FuncMCView memoryObject((const uint8_t*)Fptr, Fsize);
#endif
SymbolTable DisInfo(Ctx, memoryObject);

Expand All @@ -363,7 +377,7 @@ void jl_dump_function_asm(const char *Fptr, size_t Fsize,
DIContext *di_ctx = DIContext::getDWARFContext(const_cast<object::ObjectFile*>(objectfile));
#endif
if (di_ctx == NULL) return;
DILineInfoTable lineinfo = di_ctx->getLineInfoForAddressRange((size_t)Fptr, Fsize);
DILineInfoTable lineinfo = di_ctx->getLineInfoForAddressRange(Fptr-slide, Fsize);
#else
typedef std::vector<JITEvent_EmittedFunctionDetails::LineStart> LInfoVec;
#endif
Expand Down Expand Up @@ -431,14 +445,12 @@ void jl_dump_function_asm(const char *Fptr, size_t Fsize,
#endif

uint64_t Index = 0;
uint64_t absAddr = 0;
uint64_t insSize = 0;

// Do the disassembly
for (Index = 0, absAddr = (uint64_t)Fptr;
Index < Fsize; Index += insSize, absAddr += insSize) {
for (Index = 0; Index < Fsize; Index += insSize) {

if (nextLineAddr != (uint64_t)-1 && absAddr == nextLineAddr) {
if (nextLineAddr != (uint64_t)-1 && Index + Fptr - slide == nextLineAddr) {
#ifdef USE_MCJIT
#ifdef LLVM35
if (pass != 0)
Expand All @@ -454,22 +466,23 @@ void jl_dump_function_asm(const char *Fptr, size_t Fsize,
nextLineAddr = (*++lineIter).Address;
#endif
}
DisInfo.setIP(Fptr+Index);
if (pass != 0) {
// Uncomment this to output addresses for all instructions
// stream << Index << ": ";
const char *symbolName = DisInfo.lookupSymbol(Index);
const char *symbolName = DisInfo.lookupSymbol(Fptr+Index);
if (symbolName)
stream << symbolName << ":";
}

MCInst Inst;
MCDisassembler::DecodeStatus S;
S = DisAsm->getInstruction(Inst, insSize, memoryObject, Index,
S = DisAsm->getInstruction(Inst, insSize, memoryObject.slice(Index), 0,
/*REMOVE*/ nulls(), nulls());
switch (S) {
case MCDisassembler::Fail:
if (pass != 0)
SrcMgr.PrintMessage(SMLoc::getFromPointer(Fptr + Index),
SrcMgr.PrintMessage(SMLoc::getFromPointer((const char*)(Fptr + Index)),
SourceMgr::DK_Warning,
"invalid instruction encoding");
if (insSize == 0)
Expand All @@ -478,7 +491,7 @@ void jl_dump_function_asm(const char *Fptr, size_t Fsize,

case MCDisassembler::SoftFail:
if (pass != 0)
SrcMgr.PrintMessage(SMLoc::getFromPointer(Fptr + Index),
SrcMgr.PrintMessage(SMLoc::getFromPointer((const char*)(Fptr + Index)),
SourceMgr::DK_Warning,
"potentially undefined instruction encoding");
// Fall through
Expand All @@ -489,9 +502,9 @@ void jl_dump_function_asm(const char *Fptr, size_t Fsize,
if (MCIA->isBranch(Inst)) {
uint64_t addr;
#ifdef LLVM34
if (MCIA->evaluateBranch(Inst, Index, insSize, addr))
if (MCIA->evaluateBranch(Inst, Fptr+Index, insSize, addr))
#else
if ((addr = MCIA->evaluateBranch(Inst, Index, insSize)) != (uint64_t)-1)
if ((addr = MCIA->evaluateBranch(Inst, Fptr+Index, insSize)) != (uint64_t)-1)
#endif
DisInfo.insertAddress(addr);
}
Expand All @@ -508,6 +521,7 @@ void jl_dump_function_asm(const char *Fptr, size_t Fsize,
}
}

DisInfo.setIP(Fptr);
if (pass == 0)
DisInfo.createSymbols();
}
Expand Down

0 comments on commit 1d0b067

Please sign in to comment.