<rdar://problem/11730263>

PC relative loads are missing disassembly comments when disassembled in a live process.

This issue was because some sections, like __TEXT and __DATA in libobjc.A.dylib, were being moved when they were put into the dyld shared cache. This could also affect any other system that slides sections individually.

The solution is to keep track of wether the bytes we will disassemble are from an executable file (file address), or from a live process (load address). We now do the right thing based off of this input in all cases.

llvm-svn: 178315
This commit is contained in:
Greg Clayton 2013-03-28 23:42:53 +00:00
parent a486a11dcf
commit 3faf47c462
9 changed files with 188 additions and 158 deletions

View File

@ -1246,8 +1246,6 @@ public:
bool bool
Append (void* bytes, lldb::offset_t length); Append (void* bytes, lldb::offset_t length);
protected:
lldb::offset_t lldb::offset_t
BytesLeft (lldb::offset_t offset) const BytesLeft (lldb::offset_t offset) const
{ {
@ -1257,6 +1255,8 @@ protected:
return 0; return 0;
} }
protected:
//------------------------------------------------------------------ //------------------------------------------------------------------
// Member variables // Member variables
//------------------------------------------------------------------ //------------------------------------------------------------------

View File

@ -273,7 +273,8 @@ public:
const Address &start, const Address &start,
const void *bytes, const void *bytes,
size_t length, size_t length,
uint32_t num_instructions = UINT32_MAX); uint32_t max_num_instructions,
bool data_from_file);
static bool static bool
Disassemble (Debugger &debugger, Disassemble (Debugger &debugger,
@ -356,19 +357,22 @@ public:
size_t size_t
ParseInstructions (const ExecutionContext *exe_ctx, ParseInstructions (const ExecutionContext *exe_ctx,
const AddressRange &range, const AddressRange &range,
Stream *error_strm_ptr); Stream *error_strm_ptr,
bool prefer_file_cache);
size_t size_t
ParseInstructions (const ExecutionContext *exe_ctx, ParseInstructions (const ExecutionContext *exe_ctx,
const Address &range, const Address &range,
uint32_t num_instructions); uint32_t num_instructions,
bool prefer_file_cache);
virtual size_t virtual size_t
DecodeInstructions (const Address &base_addr, DecodeInstructions (const Address &base_addr,
const DataExtractor& data, const DataExtractor& data,
lldb::offset_t data_offset, lldb::offset_t data_offset,
size_t num_instructions, size_t num_instructions,
bool append) = 0; bool append,
bool data_from_file) = 0;
InstructionList & InstructionList &
GetInstructionList (); GetInstructionList ();

View File

@ -2288,14 +2288,22 @@ SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const cha
DataBufferHeap data (target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0); DataBufferHeap data (target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
bool prefer_file_cache = false; bool prefer_file_cache = false;
lldb_private::Error error; lldb_private::Error error;
const size_t bytes_read = target_sp->ReadMemory(*addr_ptr, prefer_file_cache, data.GetBytes(), data.GetByteSize(), error); lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
const size_t bytes_read = target_sp->ReadMemory(*addr_ptr,
prefer_file_cache,
data.GetBytes(),
data.GetByteSize(),
error,
&load_addr);
const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(), sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
NULL, NULL,
flavor_string, flavor_string,
*addr_ptr, *addr_ptr,
data.GetBytes(), data.GetBytes(),
bytes_read, bytes_read,
count)); count,
data_from_file));
} }
} }
@ -2322,12 +2330,16 @@ SBTarget::GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flav
if (base_addr.get()) if (base_addr.get())
addr = *base_addr.get(); addr = *base_addr.get();
const bool data_from_file = true;
sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(), sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
NULL, NULL,
flavor_string, flavor_string,
addr, addr,
buf, buf,
size)); size,
UINT32_MAX,
data_from_file));
} }
return sb_instructions; return sb_instructions;

View File

@ -1328,13 +1328,18 @@ DataExtractor::Dump (Stream *s,
{ {
lldb::addr_t addr = base_addr + start_offset; lldb::addr_t addr = base_addr + start_offset;
lldb_private::Address so_addr; lldb_private::Address so_addr;
if (!target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) bool data_from_file = true;
if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
{
data_from_file = false;
}
else
{ {
if (target_sp->GetSectionLoadList().IsEmpty() || !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) if (target_sp->GetSectionLoadList().IsEmpty() || !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
so_addr.SetRawAddress(addr); so_addr.SetRawAddress(addr);
} }
size_t bytes_consumed = disassembler_sp->DecodeInstructions (so_addr, *this, start_offset, item_count, false); size_t bytes_consumed = disassembler_sp->DecodeInstructions (so_addr, *this, start_offset, item_count, false, data_from_file);
if (bytes_consumed) if (bytes_consumed)
{ {

View File

@ -250,7 +250,8 @@ Disassembler::DisassembleRange
if (disasm_sp) if (disasm_sp)
{ {
size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL); const bool prefer_file_cache = false;
size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
if (bytes_disassembled == 0) if (bytes_disassembled == 0)
disasm_sp.reset(); disasm_sp.reset();
} }
@ -259,32 +260,31 @@ Disassembler::DisassembleRange
} }
lldb::DisassemblerSP lldb::DisassemblerSP
Disassembler::DisassembleBytes Disassembler::DisassembleBytes (const ArchSpec &arch,
(
const ArchSpec &arch,
const char *plugin_name, const char *plugin_name,
const char *flavor, const char *flavor,
const Address &start, const Address &start,
const void *bytes, const void *src,
size_t length, size_t src_len,
uint32_t num_instructions uint32_t num_instructions,
) bool data_from_file)
{ {
lldb::DisassemblerSP disasm_sp; lldb::DisassemblerSP disasm_sp;
if (bytes) if (src)
{ {
disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name); disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
if (disasm_sp) if (disasm_sp)
{ {
DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize()); DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
(void)disasm_sp->DecodeInstructions (start, (void)disasm_sp->DecodeInstructions (start,
data, data,
0, 0,
num_instructions, num_instructions,
false); false,
data_from_file);
} }
} }
@ -316,8 +316,8 @@ Disassembler::Disassemble
AddressRange range; AddressRange range;
ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
range.SetByteSize (disasm_range.GetByteSize()); range.SetByteSize (disasm_range.GetByteSize());
const bool prefer_file_cache = false;
size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm); size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
if (bytes_disassembled == 0) if (bytes_disassembled == 0)
return false; return false;
@ -351,13 +351,19 @@ Disassembler::Disassemble
{ {
if (num_instructions > 0) if (num_instructions > 0)
{ {
lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(),
arch,
flavor,
plugin_name));
if (disasm_sp.get()) if (disasm_sp.get())
{ {
Address addr; Address addr;
ResolveAddress (exe_ctx, start_address, addr); ResolveAddress (exe_ctx, start_address, addr);
const bool prefer_file_cache = false;
size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, addr, num_instructions); size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
addr,
num_instructions,
prefer_file_cache);
if (bytes_disassembled == 0) if (bytes_disassembled == 0)
return false; return false;
return PrintInstructions (disasm_sp.get(), return PrintInstructions (disasm_sp.get(),
@ -1045,12 +1051,10 @@ InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Tar
} }
size_t size_t
Disassembler::ParseInstructions Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
(
const ExecutionContext *exe_ctx,
const AddressRange &range, const AddressRange &range,
Stream *error_strm_ptr Stream *error_strm_ptr,
) bool prefer_file_cache)
{ {
if (exe_ctx) if (exe_ctx)
{ {
@ -1063,12 +1067,13 @@ Disassembler::ParseInstructions
DataBufferSP data_sp(heap_buffer); DataBufferSP data_sp(heap_buffer);
Error error; Error error;
const bool prefer_file_cache = true; lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
prefer_file_cache, prefer_file_cache,
heap_buffer->GetBytes(), heap_buffer->GetBytes(),
heap_buffer->GetByteSize(), heap_buffer->GetByteSize(),
error); error,
&load_addr);
if (bytes_read > 0) if (bytes_read > 0)
{ {
@ -1077,7 +1082,8 @@ Disassembler::ParseInstructions
DataExtractor data (data_sp, DataExtractor data (data_sp,
m_arch.GetByteOrder(), m_arch.GetByteOrder(),
m_arch.GetAddressByteSize()); m_arch.GetAddressByteSize());
return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
} }
else if (error_strm_ptr) else if (error_strm_ptr)
{ {
@ -1096,12 +1102,10 @@ Disassembler::ParseInstructions
} }
size_t size_t
Disassembler::ParseInstructions Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
(
const ExecutionContext *exe_ctx,
const Address &start, const Address &start,
uint32_t num_instructions uint32_t num_instructions,
) bool prefer_file_cache)
{ {
m_instruction_list.Clear(); m_instruction_list.Clear();
@ -1119,12 +1123,15 @@ Disassembler::ParseInstructions
DataBufferSP data_sp (heap_buffer); DataBufferSP data_sp (heap_buffer);
Error error; Error error;
bool prefer_file_cache = true; lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
const size_t bytes_read = target->ReadMemory (start, const size_t bytes_read = target->ReadMemory (start,
prefer_file_cache, prefer_file_cache,
heap_buffer->GetBytes(), heap_buffer->GetBytes(),
byte_size, byte_size,
error); error,
&load_addr);
const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
if (bytes_read == 0) if (bytes_read == 0)
return 0; return 0;
@ -1137,7 +1144,8 @@ Disassembler::ParseInstructions
data, data,
0, 0,
num_instructions, num_instructions,
append_instructions); append_instructions,
data_from_file);
return m_instruction_list.GetSize(); return m_instruction_list.GetSize();
} }

View File

@ -234,7 +234,7 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
DataExtractor::TypeUInt8); DataExtractor::TypeUInt8);
} }
disassembler->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false); disassembler->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);
InstructionList &instruction_list = disassembler->GetInstructionList(); InstructionList &instruction_list = disassembler->GetInstructionList();
const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize(); const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();

View File

@ -48,10 +48,10 @@ public:
const lldb_private::Address &address, const lldb_private::Address &address,
AddressClass addr_class) : AddressClass addr_class) :
Instruction (address, addr_class), Instruction (address, addr_class),
m_is_valid(false),
m_disasm(disasm),
m_disasm_sp (disasm.shared_from_this()), m_disasm_sp (disasm.shared_from_this()),
m_does_branch(eLazyBoolCalculate) m_does_branch (eLazyBoolCalculate),
m_is_valid (false),
m_using_file_addr (false)
{ {
} }
@ -60,24 +60,12 @@ public:
{ {
} }
static void
PadToWidth (lldb_private::StreamString &ss,
int new_width)
{
int old_width = ss.GetSize();
if (old_width < new_width)
{
ss.Printf("%*s", new_width - old_width, "");
}
}
virtual bool virtual bool
DoesBranch () DoesBranch ()
{ {
if (m_does_branch == eLazyBoolCalculate) if (m_does_branch == eLazyBoolCalculate)
{ {
m_disasm.Lock(this, NULL); GetDisassemblerLLVMC().Lock(this, NULL);
DataExtractor data; DataExtractor data;
if (m_opcode.GetData(data)) if (m_opcode.GetData(data))
{ {
@ -85,10 +73,10 @@ public:
lldb::addr_t pc = m_address.GetFileAddress(); lldb::addr_t pc = m_address.GetFileAddress();
DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa); DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1)); const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize(); const size_t opcode_data_len = data.GetByteSize();
llvm::MCInst inst; llvm::MCInst inst;
size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data, const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
opcode_data_len, opcode_data_len,
pc, pc,
inst); inst);
@ -97,14 +85,14 @@ public:
m_does_branch = eLazyBoolYes; m_does_branch = eLazyBoolYes;
else else
{ {
bool can_branch = mc_disasm_ptr->CanBranch(inst); const bool can_branch = mc_disasm_ptr->CanBranch(inst);
if (can_branch) if (can_branch)
m_does_branch = eLazyBoolYes; m_does_branch = eLazyBoolYes;
else else
m_does_branch = eLazyBoolNo; m_does_branch = eLazyBoolNo;
} }
} }
m_disasm.Unlock(); GetDisassemblerLLVMC().Unlock();
} }
return m_does_branch == eLazyBoolYes; return m_does_branch == eLazyBoolYes;
} }
@ -112,20 +100,19 @@ public:
DisassemblerLLVMC::LLVMCDisassembler * DisassemblerLLVMC::LLVMCDisassembler *
GetDisasmToUse (bool &is_alternate_isa) GetDisasmToUse (bool &is_alternate_isa)
{ {
DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = m_disasm.m_disasm_ap.get();
is_alternate_isa = false; is_alternate_isa = false;
if (m_disasm.m_alternate_disasm_ap.get() != NULL) DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
if (llvm_disasm.m_alternate_disasm_ap.get() != NULL)
{ {
const AddressClass address_class = GetAddressClass (); const AddressClass address_class = GetAddressClass ();
if (address_class == eAddressClassCodeAlternateISA) if (address_class == eAddressClassCodeAlternateISA)
{ {
mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
is_alternate_isa = true; is_alternate_isa = true;
return llvm_disasm.m_alternate_disasm_ap.get();
} }
} }
return mc_disasm_ptr; return llvm_disasm.m_disasm_ap.get();
} }
virtual size_t virtual size_t
@ -136,7 +123,8 @@ public:
// All we have to do is read the opcode which can be easy for some // All we have to do is read the opcode which can be easy for some
// architetures // architetures
bool got_op = false; bool got_op = false;
const ArchSpec &arch = m_disasm.GetArchitecture(); DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
const ArchSpec &arch = llvm_disasm.GetArchitecture();
const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize(); const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize(); const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
@ -179,17 +167,6 @@ public:
bool is_alternate_isa = false; bool is_alternate_isa = false;
DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa); DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
if (m_disasm.m_alternate_disasm_ap.get() != NULL)
{
const AddressClass address_class = GetAddressClass ();
if (address_class == eAddressClassCodeAlternateISA)
{
mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
is_alternate_isa = true;
}
}
const llvm::Triple::ArchType machine = arch.GetMachine(); const llvm::Triple::ArchType machine = arch.GetMachine();
if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
{ {
@ -219,17 +196,17 @@ public:
{ {
// The opcode isn't evenly sized, so we need to actually use the llvm // The opcode isn't evenly sized, so we need to actually use the llvm
// disassembler to parse it and get the size. // disassembler to parse it and get the size.
m_disasm.Lock(this, NULL);
uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1)); uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
const size_t opcode_data_len = data.GetByteSize() - data_offset; const size_t opcode_data_len = data.BytesLeft(data_offset);
const addr_t pc = m_address.GetFileAddress(); const addr_t pc = m_address.GetFileAddress();
llvm::MCInst inst; llvm::MCInst inst;
llvm_disasm.Lock(this, NULL);
const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data, const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
opcode_data_len, opcode_data_len,
pc, pc,
inst); inst);
m_disasm.Unlock(); llvm_disasm.Unlock();
if (inst_size == 0) if (inst_size == 0)
m_opcode.Clear(); m_opcode.Clear();
else else
@ -264,28 +241,39 @@ public:
{ {
char out_string[512]; char out_string[512];
DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr; DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
if (address_class == eAddressClassCodeAlternateISA) if (address_class == eAddressClassCodeAlternateISA)
mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get(); mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get();
else else
mc_disasm_ptr = m_disasm.m_disasm_ap.get(); mc_disasm_ptr = llvm_disasm.m_disasm_ap.get();
lldb::addr_t pc = LLDB_INVALID_ADDRESS; lldb::addr_t pc = m_address.GetFileAddress();
m_using_file_addr = true;
const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file;
if (!data_from_file)
{
if (exe_ctx) if (exe_ctx)
{ {
Target *target = exe_ctx->GetTargetPtr(); Target *target = exe_ctx->GetTargetPtr();
if (target) if (target)
pc = m_address.GetLoadAddress(target); {
const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
if (load_addr != LLDB_INVALID_ADDRESS)
{
pc = load_addr;
m_using_file_addr = false;
}
}
}
} }
if (pc == LLDB_INVALID_ADDRESS) llvm_disasm.Lock(this, exe_ctx);
pc = m_address.GetFileAddress();
m_disasm.Lock(this, exe_ctx); const uint8_t *opcode_data = data.GetDataStart();
uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1));
const size_t opcode_data_len = data.GetByteSize(); const size_t opcode_data_len = data.GetByteSize();
llvm::MCInst inst; llvm::MCInst inst;
size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data, size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
@ -296,7 +284,7 @@ public:
if (inst_size > 0) if (inst_size > 0)
mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string)); mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
m_disasm.Unlock(); llvm_disasm.Unlock();
if (inst_size == 0) if (inst_size == 0)
{ {
@ -361,7 +349,7 @@ public:
{ {
if (m_does_branch == eLazyBoolCalculate) if (m_does_branch == eLazyBoolCalculate)
{ {
bool can_branch = mc_disasm_ptr->CanBranch(inst); const bool can_branch = mc_disasm_ptr->CanBranch(inst);
if (can_branch) if (can_branch)
m_does_branch = eLazyBoolYes; m_does_branch = eLazyBoolYes;
else else
@ -389,22 +377,33 @@ public:
} }
bool bool
IsValid () IsValid () const
{ {
return m_is_valid; return m_is_valid;
} }
bool
UsingFileAddress() const
{
return m_using_file_addr;
}
size_t size_t
GetByteSize () GetByteSize () const
{ {
return m_opcode.GetByteSize(); return m_opcode.GetByteSize();
} }
DisassemblerLLVMC &
GetDisassemblerLLVMC ()
{
return *(DisassemblerLLVMC *)m_disasm_sp.get();
}
protected: protected:
bool m_is_valid;
DisassemblerLLVMC &m_disasm;
DisassemblerSP m_disasm_sp; // for ownership DisassemblerSP m_disasm_sp; // for ownership
LazyBool m_does_branch; LazyBool m_does_branch;
bool m_is_valid;
bool m_using_file_addr;
static bool s_regex_compiled; static bool s_regex_compiled;
static ::regex_t s_regex; static ::regex_t s_regex;
@ -476,11 +475,11 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, uns
namespace { namespace {
// This is the memory object we use in GetInstruction. // This is the memory object we use in GetInstruction.
class LLDBDisasmMemoryObject : public llvm::MemoryObject { class LLDBDisasmMemoryObject : public llvm::MemoryObject {
uint8_t *m_bytes; const uint8_t *m_bytes;
uint64_t m_size; uint64_t m_size;
uint64_t m_base_PC; uint64_t m_base_PC;
public: public:
LLDBDisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) : LLDBDisasmMemoryObject(const uint8_t *bytes, uint64_t size, uint64_t basePC) :
m_bytes(bytes), m_size(size), m_base_PC(basePC) {} m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
uint64_t getBase() const { return m_base_PC; } uint64_t getBase() const { return m_base_PC; }
@ -496,14 +495,12 @@ namespace {
} // End Anonymous Namespace } // End Anonymous Namespace
uint64_t uint64_t
DisassemblerLLVMC::LLVMCDisassembler::GetMCInst ( DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data,
uint8_t *opcode_data,
size_t opcode_data_len, size_t opcode_data_len,
lldb::addr_t pc, lldb::addr_t pc,
llvm::MCInst &mc_inst) llvm::MCInst &mc_inst)
{ {
LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc); LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
llvm::MCInst inst;
llvm::MCDisassembler::DecodeStatus status; llvm::MCDisassembler::DecodeStatus status;
uint64_t new_inst_size; uint64_t new_inst_size;
@ -520,17 +517,18 @@ DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (
} }
uint64_t uint64_t
DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len) DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst,
char *dst,
size_t dst_len)
{ {
llvm::StringRef unused_annotations; llvm::StringRef unused_annotations;
llvm::SmallString<64> inst_string; llvm::SmallString<64> inst_string;
llvm::raw_svector_ostream inst_stream(inst_string); llvm::raw_svector_ostream inst_stream(inst_string);
m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations); m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
inst_stream.flush(); inst_stream.flush();
const size_t output_size = std::min(dst_len - 1, inst_string.size());
size_t output_size = std::min(out_buffer_len -1, inst_string.size()); std::memcpy(dst, inst_string.data(), output_size);
std::memcpy(output_buffer, inst_string.data(), output_size); dst[output_size] = '\0';
output_buffer[output_size] = '\0';
return output_size; return output_size;
} }
@ -576,7 +574,8 @@ DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) : DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
Disassembler(arch, flavor_string), Disassembler(arch, flavor_string),
m_exe_ctx (NULL), m_exe_ctx (NULL),
m_inst (NULL) m_inst (NULL),
m_data_from_file (false)
{ {
if (!FlavorValidForArchSpec (arch, m_flavor.c_str())) if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
{ {
@ -633,7 +632,8 @@ DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
const DataExtractor& data, const DataExtractor& data,
lldb::offset_t data_offset, lldb::offset_t data_offset,
size_t num_instructions, size_t num_instructions,
bool append) bool append,
bool data_from_file)
{ {
if (!append) if (!append)
m_instruction_list.Clear(); m_instruction_list.Clear();
@ -641,6 +641,7 @@ DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
if (!IsValid()) if (!IsValid())
return 0; return 0;
m_data_from_file = data_from_file;
uint32_t data_cursor = data_offset; uint32_t data_cursor = data_offset;
const size_t data_byte_size = data.GetByteSize(); const size_t data_byte_size = data.GetByteSize();
uint32_t instructions_parsed = 0; uint32_t instructions_parsed = 0;
@ -760,36 +761,33 @@ const char *DisassemblerLLVMC::SymbolLookup (uint64_t value,
if (m_exe_ctx && m_inst) if (m_exe_ctx && m_inst)
{ {
//std::string remove_this_prior_to_checkin; //std::string remove_this_prior_to_checkin;
Address reference_address;
Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL; Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
Address value_so_addr;
if (target && !target->GetSectionLoadList().IsEmpty()) if (m_inst->UsingFileAddress())
target->GetSectionLoadList().ResolveLoadAddress(value, reference_address);
else
{ {
ModuleSP module_sp(m_inst->GetAddress().GetModule()); ModuleSP module_sp(m_inst->GetAddress().GetModule());
if (module_sp) if (module_sp)
module_sp->ResolveFileAddress(value, reference_address); module_sp->ResolveFileAddress(value, value_so_addr);
}
else if (target && !target->GetSectionLoadList().IsEmpty())
{
target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
} }
if (reference_address.IsValid() && reference_address.GetSection()) if (value_so_addr.IsValid() && value_so_addr.GetSection())
{ {
StreamString ss; StreamString ss;
reference_address.Dump (&ss, value_so_addr.Dump (&ss,
target, target,
Address::DumpStyleResolvedDescriptionNoModule, Address::DumpStyleResolvedDescriptionNoModule,
Address::DumpStyleSectionNameOffset); Address::DumpStyleSectionNameOffset);
if (!ss.GetString().empty()) if (!ss.GetString().empty())
{ {
//remove_this_prior_to_checkin = ss.GetString();
//if (*type_ptr)
m_inst->AppendComment(ss.GetString()); m_inst->AppendComment(ss.GetString());
} }
} }
//printf ("DisassemblerLLVMC::SymbolLookup (value=0x%16.16" PRIx64 ", type=%" PRIu64 ", pc=0x%16.16" PRIx64 ", name=\"%s\") m_exe_ctx=%p, m_inst=%p\n", value, *type_ptr, pc, remove_this_prior_to_checkin.c_str(), m_exe_ctx, m_inst);
} }
} }

View File

@ -45,7 +45,7 @@ class DisassemblerLLVMC : public lldb_private::Disassembler
~LLVMCDisassembler() {}; ~LLVMCDisassembler() {};
uint64_t GetMCInst (uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst); uint64_t GetMCInst (const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst);
uint64_t PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len); uint64_t PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len);
bool CanBranch (llvm::MCInst &mc_inst); bool CanBranch (llvm::MCInst &mc_inst);
bool IsValid() bool IsValid()
@ -88,12 +88,13 @@ public:
virtual virtual
~DisassemblerLLVMC(); ~DisassemblerLLVMC();
size_t virtual size_t
DecodeInstructions (const lldb_private::Address &base_addr, DecodeInstructions (const lldb_private::Address &base_addr,
const lldb_private::DataExtractor& data, const lldb_private::DataExtractor& data,
lldb::offset_t data_offset, lldb::offset_t data_offset,
size_t num_instructions, size_t num_instructions,
bool append); bool append,
bool data_from_file);
//------------------------------------------------------------------ //------------------------------------------------------------------
// PluginInterface protocol // PluginInterface protocol
@ -161,6 +162,7 @@ protected:
const lldb_private::ExecutionContext *m_exe_ctx; const lldb_private::ExecutionContext *m_exe_ctx;
InstructionLLVMC *m_inst; InstructionLLVMC *m_inst;
lldb_private::Mutex m_mutex; lldb_private::Mutex m_mutex;
bool m_data_from_file;
std::auto_ptr<LLVMCDisassembler> m_disasm_ap; std::auto_ptr<LLVMCDisassembler> m_disasm_ap;
std::auto_ptr<LLVMCDisassembler> m_alternate_disasm_ap; std::auto_ptr<LLVMCDisassembler> m_alternate_disasm_ap;

View File

@ -208,10 +208,11 @@ ThreadPlanAssemblyTracer::Log ()
process_sp->GetByteOrder(), process_sp->GetByteOrder(),
process_sp->GetAddressByteSize()); process_sp->GetAddressByteSize());
bool data_from_file = false;
if (addr_valid) if (addr_valid)
disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false); disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false, data_from_file);
else else
disassembler->DecodeInstructions (Address (pc), extractor, 0, 1, false); disassembler->DecodeInstructions (Address (pc), extractor, 0, 1, false, data_from_file);
InstructionList &instruction_list = disassembler->GetInstructionList(); InstructionList &instruction_list = disassembler->GetInstructionList();
const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize(); const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();