forked from OSchip/llvm-project
<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:
parent
a486a11dcf
commit
3faf47c462
|
@ -1246,8 +1246,6 @@ public:
|
|||
bool
|
||||
Append (void* bytes, lldb::offset_t length);
|
||||
|
||||
protected:
|
||||
|
||||
lldb::offset_t
|
||||
BytesLeft (lldb::offset_t offset) const
|
||||
{
|
||||
|
@ -1257,6 +1255,8 @@ protected:
|
|||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member variables
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -273,7 +273,8 @@ public:
|
|||
const Address &start,
|
||||
const void *bytes,
|
||||
size_t length,
|
||||
uint32_t num_instructions = UINT32_MAX);
|
||||
uint32_t max_num_instructions,
|
||||
bool data_from_file);
|
||||
|
||||
static bool
|
||||
Disassemble (Debugger &debugger,
|
||||
|
@ -356,19 +357,22 @@ public:
|
|||
size_t
|
||||
ParseInstructions (const ExecutionContext *exe_ctx,
|
||||
const AddressRange &range,
|
||||
Stream *error_strm_ptr);
|
||||
Stream *error_strm_ptr,
|
||||
bool prefer_file_cache);
|
||||
|
||||
size_t
|
||||
ParseInstructions (const ExecutionContext *exe_ctx,
|
||||
const Address &range,
|
||||
uint32_t num_instructions);
|
||||
uint32_t num_instructions,
|
||||
bool prefer_file_cache);
|
||||
|
||||
virtual size_t
|
||||
DecodeInstructions (const Address &base_addr,
|
||||
const DataExtractor& data,
|
||||
lldb::offset_t data_offset,
|
||||
size_t num_instructions,
|
||||
bool append) = 0;
|
||||
bool append,
|
||||
bool data_from_file) = 0;
|
||||
|
||||
InstructionList &
|
||||
GetInstructionList ();
|
||||
|
|
|
@ -2288,14 +2288,22 @@ SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const cha
|
|||
DataBufferHeap data (target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
|
||||
bool prefer_file_cache = false;
|
||||
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(),
|
||||
NULL,
|
||||
flavor_string,
|
||||
*addr_ptr,
|
||||
data.GetBytes(),
|
||||
bytes_read,
|
||||
count));
|
||||
count,
|
||||
data_from_file));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2322,12 +2330,16 @@ SBTarget::GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flav
|
|||
if (base_addr.get())
|
||||
addr = *base_addr.get();
|
||||
|
||||
const bool data_from_file = true;
|
||||
|
||||
sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
|
||||
NULL,
|
||||
flavor_string,
|
||||
addr,
|
||||
buf,
|
||||
size));
|
||||
size,
|
||||
UINT32_MAX,
|
||||
data_from_file));
|
||||
}
|
||||
|
||||
return sb_instructions;
|
||||
|
|
|
@ -1328,13 +1328,18 @@ DataExtractor::Dump (Stream *s,
|
|||
{
|
||||
lldb::addr_t addr = base_addr + start_offset;
|
||||
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))
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -250,7 +250,8 @@ Disassembler::DisassembleRange
|
|||
|
||||
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)
|
||||
disasm_sp.reset();
|
||||
}
|
||||
|
@ -259,32 +260,31 @@ Disassembler::DisassembleRange
|
|||
}
|
||||
|
||||
lldb::DisassemblerSP
|
||||
Disassembler::DisassembleBytes
|
||||
(
|
||||
const ArchSpec &arch,
|
||||
Disassembler::DisassembleBytes (const ArchSpec &arch,
|
||||
const char *plugin_name,
|
||||
const char *flavor,
|
||||
const Address &start,
|
||||
const void *bytes,
|
||||
size_t length,
|
||||
uint32_t num_instructions
|
||||
)
|
||||
const void *src,
|
||||
size_t src_len,
|
||||
uint32_t num_instructions,
|
||||
bool data_from_file)
|
||||
{
|
||||
lldb::DisassemblerSP disasm_sp;
|
||||
|
||||
if (bytes)
|
||||
if (src)
|
||||
{
|
||||
disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
|
||||
|
||||
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,
|
||||
data,
|
||||
0,
|
||||
num_instructions,
|
||||
false);
|
||||
false,
|
||||
data_from_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,8 +316,8 @@ Disassembler::Disassemble
|
|||
AddressRange range;
|
||||
ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
|
||||
range.SetByteSize (disasm_range.GetByteSize());
|
||||
|
||||
size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm);
|
||||
const bool prefer_file_cache = false;
|
||||
size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
|
||||
if (bytes_disassembled == 0)
|
||||
return false;
|
||||
|
||||
|
@ -351,13 +351,19 @@ Disassembler::Disassemble
|
|||
{
|
||||
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())
|
||||
{
|
||||
Address addr;
|
||||
ResolveAddress (exe_ctx, start_address, addr);
|
||||
|
||||
size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, addr, num_instructions);
|
||||
const bool prefer_file_cache = false;
|
||||
size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
|
||||
addr,
|
||||
num_instructions,
|
||||
prefer_file_cache);
|
||||
if (bytes_disassembled == 0)
|
||||
return false;
|
||||
return PrintInstructions (disasm_sp.get(),
|
||||
|
@ -1045,12 +1051,10 @@ InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Tar
|
|||
}
|
||||
|
||||
size_t
|
||||
Disassembler::ParseInstructions
|
||||
(
|
||||
const ExecutionContext *exe_ctx,
|
||||
Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
|
||||
const AddressRange &range,
|
||||
Stream *error_strm_ptr
|
||||
)
|
||||
Stream *error_strm_ptr,
|
||||
bool prefer_file_cache)
|
||||
{
|
||||
if (exe_ctx)
|
||||
{
|
||||
|
@ -1063,12 +1067,13 @@ Disassembler::ParseInstructions
|
|||
DataBufferSP data_sp(heap_buffer);
|
||||
|
||||
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(),
|
||||
prefer_file_cache,
|
||||
heap_buffer->GetBytes(),
|
||||
heap_buffer->GetByteSize(),
|
||||
error);
|
||||
error,
|
||||
&load_addr);
|
||||
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
|
@ -1077,7 +1082,8 @@ Disassembler::ParseInstructions
|
|||
DataExtractor data (data_sp,
|
||||
m_arch.GetByteOrder(),
|
||||
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)
|
||||
{
|
||||
|
@ -1096,12 +1102,10 @@ Disassembler::ParseInstructions
|
|||
}
|
||||
|
||||
size_t
|
||||
Disassembler::ParseInstructions
|
||||
(
|
||||
const ExecutionContext *exe_ctx,
|
||||
Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
|
||||
const Address &start,
|
||||
uint32_t num_instructions
|
||||
)
|
||||
uint32_t num_instructions,
|
||||
bool prefer_file_cache)
|
||||
{
|
||||
m_instruction_list.Clear();
|
||||
|
||||
|
@ -1119,12 +1123,15 @@ Disassembler::ParseInstructions
|
|||
DataBufferSP data_sp (heap_buffer);
|
||||
|
||||
Error error;
|
||||
bool prefer_file_cache = true;
|
||||
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
|
||||
const size_t bytes_read = target->ReadMemory (start,
|
||||
prefer_file_cache,
|
||||
heap_buffer->GetBytes(),
|
||||
byte_size,
|
||||
error);
|
||||
error,
|
||||
&load_addr);
|
||||
|
||||
const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
|
||||
|
||||
if (bytes_read == 0)
|
||||
return 0;
|
||||
|
@ -1137,7 +1144,8 @@ Disassembler::ParseInstructions
|
|||
data,
|
||||
0,
|
||||
num_instructions,
|
||||
append_instructions);
|
||||
append_instructions,
|
||||
data_from_file);
|
||||
|
||||
return m_instruction_list.GetSize();
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
|
|||
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();
|
||||
const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
|
||||
|
|
|
@ -47,11 +47,11 @@ public:
|
|||
InstructionLLVMC (DisassemblerLLVMC &disasm,
|
||||
const lldb_private::Address &address,
|
||||
AddressClass addr_class) :
|
||||
Instruction(address, addr_class),
|
||||
m_is_valid(false),
|
||||
m_disasm(disasm),
|
||||
m_disasm_sp(disasm.shared_from_this()),
|
||||
m_does_branch(eLazyBoolCalculate)
|
||||
Instruction (address, addr_class),
|
||||
m_disasm_sp (disasm.shared_from_this()),
|
||||
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
|
||||
DoesBranch ()
|
||||
{
|
||||
if (m_does_branch == eLazyBoolCalculate)
|
||||
{
|
||||
m_disasm.Lock(this, NULL);
|
||||
GetDisassemblerLLVMC().Lock(this, NULL);
|
||||
DataExtractor data;
|
||||
if (m_opcode.GetData(data))
|
||||
{
|
||||
|
@ -85,10 +73,10 @@ public:
|
|||
lldb::addr_t pc = m_address.GetFileAddress();
|
||||
|
||||
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();
|
||||
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,
|
||||
pc,
|
||||
inst);
|
||||
|
@ -97,14 +85,14 @@ public:
|
|||
m_does_branch = eLazyBoolYes;
|
||||
else
|
||||
{
|
||||
bool can_branch = mc_disasm_ptr->CanBranch(inst);
|
||||
const bool can_branch = mc_disasm_ptr->CanBranch(inst);
|
||||
if (can_branch)
|
||||
m_does_branch = eLazyBoolYes;
|
||||
else
|
||||
m_does_branch = eLazyBoolNo;
|
||||
}
|
||||
}
|
||||
m_disasm.Unlock();
|
||||
GetDisassemblerLLVMC().Unlock();
|
||||
}
|
||||
return m_does_branch == eLazyBoolYes;
|
||||
}
|
||||
|
@ -112,20 +100,19 @@ public:
|
|||
DisassemblerLLVMC::LLVMCDisassembler *
|
||||
GetDisasmToUse (bool &is_alternate_isa)
|
||||
{
|
||||
DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = m_disasm.m_disasm_ap.get();
|
||||
|
||||
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 ();
|
||||
|
||||
if (address_class == eAddressClassCodeAlternateISA)
|
||||
{
|
||||
mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
|
||||
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
|
||||
|
@ -136,7 +123,8 @@ public:
|
|||
// All we have to do is read the opcode which can be easy for some
|
||||
// architetures
|
||||
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 max_op_byte_size = arch.GetMaximumOpcodeByteSize();
|
||||
|
@ -179,17 +167,6 @@ public:
|
|||
bool is_alternate_isa = false;
|
||||
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();
|
||||
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
|
||||
// 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));
|
||||
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();
|
||||
llvm::MCInst inst;
|
||||
|
||||
llvm_disasm.Lock(this, NULL);
|
||||
const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
|
||||
opcode_data_len,
|
||||
pc,
|
||||
inst);
|
||||
m_disasm.Unlock();
|
||||
llvm_disasm.Unlock();
|
||||
if (inst_size == 0)
|
||||
m_opcode.Clear();
|
||||
else
|
||||
|
@ -264,31 +241,42 @@ public:
|
|||
{
|
||||
char out_string[512];
|
||||
|
||||
DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
|
||||
|
||||
DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
|
||||
|
||||
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
|
||||
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)
|
||||
{
|
||||
Target *target = exe_ctx->GetTargetPtr();
|
||||
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)
|
||||
pc = m_address.GetFileAddress();
|
||||
llvm_disasm.Lock(this, exe_ctx);
|
||||
|
||||
m_disasm.Lock(this, exe_ctx);
|
||||
|
||||
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();
|
||||
llvm::MCInst inst;
|
||||
size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
|
||||
size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
|
||||
opcode_data_len,
|
||||
pc,
|
||||
inst);
|
||||
|
@ -296,7 +284,7 @@ public:
|
|||
if (inst_size > 0)
|
||||
mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
|
||||
|
||||
m_disasm.Unlock();
|
||||
llvm_disasm.Unlock();
|
||||
|
||||
if (inst_size == 0)
|
||||
{
|
||||
|
@ -361,7 +349,7 @@ public:
|
|||
{
|
||||
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)
|
||||
m_does_branch = eLazyBoolYes;
|
||||
else
|
||||
|
@ -389,22 +377,33 @@ public:
|
|||
}
|
||||
|
||||
bool
|
||||
IsValid ()
|
||||
IsValid () const
|
||||
{
|
||||
return m_is_valid;
|
||||
}
|
||||
|
||||
bool
|
||||
UsingFileAddress() const
|
||||
{
|
||||
return m_using_file_addr;
|
||||
}
|
||||
size_t
|
||||
GetByteSize ()
|
||||
GetByteSize () const
|
||||
{
|
||||
return m_opcode.GetByteSize();
|
||||
}
|
||||
|
||||
DisassemblerLLVMC &
|
||||
GetDisassemblerLLVMC ()
|
||||
{
|
||||
return *(DisassemblerLLVMC *)m_disasm_sp.get();
|
||||
}
|
||||
protected:
|
||||
|
||||
bool m_is_valid;
|
||||
DisassemblerLLVMC &m_disasm;
|
||||
DisassemblerSP m_disasm_sp; // for ownership
|
||||
LazyBool m_does_branch;
|
||||
bool m_is_valid;
|
||||
bool m_using_file_addr;
|
||||
|
||||
static bool s_regex_compiled;
|
||||
static ::regex_t s_regex;
|
||||
|
@ -476,11 +475,11 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, uns
|
|||
namespace {
|
||||
// This is the memory object we use in GetInstruction.
|
||||
class LLDBDisasmMemoryObject : public llvm::MemoryObject {
|
||||
uint8_t *m_bytes;
|
||||
const uint8_t *m_bytes;
|
||||
uint64_t m_size;
|
||||
uint64_t m_base_PC;
|
||||
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) {}
|
||||
|
||||
uint64_t getBase() const { return m_base_PC; }
|
||||
|
@ -496,14 +495,12 @@ namespace {
|
|||
} // End Anonymous Namespace
|
||||
|
||||
uint64_t
|
||||
DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (
|
||||
uint8_t *opcode_data,
|
||||
DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data,
|
||||
size_t opcode_data_len,
|
||||
lldb::addr_t pc,
|
||||
llvm::MCInst &mc_inst)
|
||||
{
|
||||
LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
|
||||
llvm::MCInst inst;
|
||||
llvm::MCDisassembler::DecodeStatus status;
|
||||
|
||||
uint64_t new_inst_size;
|
||||
|
@ -520,17 +517,18 @@ DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (
|
|||
}
|
||||
|
||||
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::SmallString<64> inst_string;
|
||||
llvm::raw_svector_ostream inst_stream(inst_string);
|
||||
m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
|
||||
inst_stream.flush();
|
||||
|
||||
size_t output_size = std::min(out_buffer_len -1, inst_string.size());
|
||||
std::memcpy(output_buffer, inst_string.data(), output_size);
|
||||
output_buffer[output_size] = '\0';
|
||||
const size_t output_size = std::min(dst_len - 1, inst_string.size());
|
||||
std::memcpy(dst, inst_string.data(), output_size);
|
||||
dst[output_size] = '\0';
|
||||
|
||||
return output_size;
|
||||
}
|
||||
|
@ -576,7 +574,8 @@ DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
|
|||
DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
|
||||
Disassembler(arch, flavor_string),
|
||||
m_exe_ctx (NULL),
|
||||
m_inst (NULL)
|
||||
m_inst (NULL),
|
||||
m_data_from_file (false)
|
||||
{
|
||||
if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
|
||||
{
|
||||
|
@ -633,7 +632,8 @@ DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
|
|||
const DataExtractor& data,
|
||||
lldb::offset_t data_offset,
|
||||
size_t num_instructions,
|
||||
bool append)
|
||||
bool append,
|
||||
bool data_from_file)
|
||||
{
|
||||
if (!append)
|
||||
m_instruction_list.Clear();
|
||||
|
@ -641,6 +641,7 @@ DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
|
|||
if (!IsValid())
|
||||
return 0;
|
||||
|
||||
m_data_from_file = data_from_file;
|
||||
uint32_t data_cursor = data_offset;
|
||||
const size_t data_byte_size = data.GetByteSize();
|
||||
uint32_t instructions_parsed = 0;
|
||||
|
@ -760,36 +761,33 @@ const char *DisassemblerLLVMC::SymbolLookup (uint64_t value,
|
|||
if (m_exe_ctx && m_inst)
|
||||
{
|
||||
//std::string remove_this_prior_to_checkin;
|
||||
Address reference_address;
|
||||
|
||||
Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
|
||||
|
||||
if (target && !target->GetSectionLoadList().IsEmpty())
|
||||
target->GetSectionLoadList().ResolveLoadAddress(value, reference_address);
|
||||
else
|
||||
Address value_so_addr;
|
||||
if (m_inst->UsingFileAddress())
|
||||
{
|
||||
ModuleSP module_sp(m_inst->GetAddress().GetModule());
|
||||
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;
|
||||
|
||||
reference_address.Dump (&ss,
|
||||
value_so_addr.Dump (&ss,
|
||||
target,
|
||||
Address::DumpStyleResolvedDescriptionNoModule,
|
||||
Address::DumpStyleSectionNameOffset);
|
||||
|
||||
if (!ss.GetString().empty())
|
||||
{
|
||||
//remove_this_prior_to_checkin = ss.GetString();
|
||||
//if (*type_ptr)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class DisassemblerLLVMC : public lldb_private::Disassembler
|
|||
|
||||
~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);
|
||||
bool CanBranch (llvm::MCInst &mc_inst);
|
||||
bool IsValid()
|
||||
|
@ -88,12 +88,13 @@ public:
|
|||
virtual
|
||||
~DisassemblerLLVMC();
|
||||
|
||||
size_t
|
||||
virtual size_t
|
||||
DecodeInstructions (const lldb_private::Address &base_addr,
|
||||
const lldb_private::DataExtractor& data,
|
||||
lldb::offset_t data_offset,
|
||||
size_t num_instructions,
|
||||
bool append);
|
||||
bool append,
|
||||
bool data_from_file);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// PluginInterface protocol
|
||||
|
@ -161,6 +162,7 @@ protected:
|
|||
const lldb_private::ExecutionContext *m_exe_ctx;
|
||||
InstructionLLVMC *m_inst;
|
||||
lldb_private::Mutex m_mutex;
|
||||
bool m_data_from_file;
|
||||
|
||||
std::auto_ptr<LLVMCDisassembler> m_disasm_ap;
|
||||
std::auto_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
|
||||
|
|
|
@ -208,10 +208,11 @@ ThreadPlanAssemblyTracer::Log ()
|
|||
process_sp->GetByteOrder(),
|
||||
process_sp->GetAddressByteSize());
|
||||
|
||||
bool data_from_file = false;
|
||||
if (addr_valid)
|
||||
disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false);
|
||||
disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false, data_from_file);
|
||||
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();
|
||||
const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
|
||||
|
|
Loading…
Reference in New Issue