diff options
Diffstat (limited to 'lldb/source/Core')
-rw-r--r-- | lldb/source/Core/ArchSpec.cpp | 91 | ||||
-rw-r--r-- | lldb/source/Core/Disassembler.cpp | 200 | ||||
-rw-r--r-- | lldb/source/Core/Module.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Core/Opcode.cpp | 2 |
4 files changed, 160 insertions, 139 deletions
diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp index 17134938d09..210d32aa421 100644 --- a/lldb/source/Core/ArchSpec.cpp +++ b/lldb/source/Core/ArchSpec.cpp @@ -30,6 +30,8 @@ namespace lldb_private { { ByteOrder default_byte_order; uint32_t addr_byte_size; + uint32_t min_opcode_byte_size; + uint32_t max_opcode_byte_size; llvm::Triple::ArchType machine; ArchSpec::Core core; const char *name; @@ -40,45 +42,47 @@ namespace lldb_private { // This core information can be looked using the ArchSpec::Core as the index static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] = { - { eByteOrderLittle, 4, llvm::Triple::alpha , ArchSpec::eCore_alpha_generic , "alpha" }, - - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4t , "armv4t" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5 , "armv5" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5t , "armv5t" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6 , "armv6" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7 , "armv7" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7f , "armv7f" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7k , "armv7k" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7s , "armv7s" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_xscale , "xscale" }, + // TODO: verify alpha has 32 bit fixed instructions + { eByteOrderLittle, 4, 4, 4, llvm::Triple::alpha , ArchSpec::eCore_alpha_generic , "alpha" }, + + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4t , "armv4t" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5 , "armv5" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5t , "armv5t" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6 , "armv6" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7 , "armv7" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7f , "armv7f" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7k , "armv7k" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7s , "armv7s" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_xscale , "xscale" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumb_generic , "thumb" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603e , "ppc603e" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603ev , "ppc603ev" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604 , "ppc604" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604e , "ppc604e" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc620 , "ppc620" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc750 , "ppc750" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7400 , "ppc7400" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603e , "ppc603e" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603ev , "ppc603ev" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604 , "ppc604" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604e , "ppc604e" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc620 , "ppc620" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc750 , "ppc750" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7400 , "ppc7400" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" }, - { eByteOrderLittle, 8, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" }, - { eByteOrderLittle, 8, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" }, - { eByteOrderLittle, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" }, - { eByteOrderLittle, 8, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" }, - { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" }, - { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" }, - { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" }, + { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" }, + { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" }, + { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" }, - { eByteOrderLittle, 8, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" } + { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" } }; struct ArchDefinitionEntry @@ -118,6 +122,7 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = { ArchSpec::eCore_arm_armv7f , llvm::MachO::CPUTypeARM , 10 }, { ArchSpec::eCore_arm_armv7k , llvm::MachO::CPUTypeARM , 12 }, { ArchSpec::eCore_arm_armv7s , llvm::MachO::CPUTypeARM , 11 }, + { ArchSpec::eCore_thumb_generic , llvm::MachO::CPUTypeARM , 0 }, { ArchSpec::eCore_ppc_generic , llvm::MachO::CPUTypePowerPC , CPU_ANY }, { ArchSpec::eCore_ppc_generic , llvm::MachO::CPUTypePowerPC , 0 }, { ArchSpec::eCore_ppc_ppc601 , llvm::MachO::CPUTypePowerPC , 1 }, @@ -496,10 +501,22 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su return IsValid(); } -void -ArchSpec::SetByteOrder (lldb::ByteOrder byte_order) +uint32_t +ArchSpec::GetMinimumOpcodeByteSize() const +{ + const CoreDefinition *core_def = FindCoreDefinition (m_core); + if (core_def) + return core_def->min_opcode_byte_size; + return 0; +} + +uint32_t +ArchSpec::GetMaximumOpcodeByteSize() const { - m_byte_order = byte_order; + const CoreDefinition *core_def = FindCoreDefinition (m_core); + if (core_def) + return core_def->max_opcode_byte_size; + return 0; } //===----------------------------------------------------------------------===// diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index 9f3897752fe..e37f4818c9c 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -69,6 +69,33 @@ Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name) } +static void +ResolveAddress (const ExecutionContext &exe_ctx, + const Address &addr, + Address &resolved_addr) +{ + if (!addr.IsSectionOffset()) + { + // If we weren't passed in a section offset address range, + // try and resolve it to something + if (exe_ctx.target) + { + if (exe_ctx.target->GetSectionLoadList().IsEmpty()) + { + exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); + } + else + { + exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); + } + // We weren't able to resolve the address, just treat it as a + // raw address + if (resolved_addr.IsValid()) + return; + } + } + resolved_addr = addr; +} size_t Disassembler::Disassemble @@ -192,8 +219,7 @@ Disassembler::DisassembleRange if (disasm_sp) { - DataExtractor data; - size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, data); + size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range); if (bytes_disassembled == 0) disasm_sp.reset(); } @@ -223,27 +249,11 @@ Disassembler::Disassemble if (disasm_ap.get()) { - AddressRange range(disasm_range); + AddressRange range; + ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); + range.SetByteSize (disasm_range.GetByteSize()); - // If we weren't passed in a section offset address range, - // try and resolve it to something - if (range.GetBaseAddress().IsSectionOffset() == false) - { - if (exe_ctx.target) - { - if (exe_ctx.target->GetSectionLoadList().IsEmpty()) - { - exe_ctx.target->GetImages().ResolveFileAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress()); - } - else - { - exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress()); - } - } - } - - DataExtractor data; - size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range, data); + size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range); if (bytes_disassembled == 0) return false; @@ -280,29 +290,12 @@ Disassembler::Disassemble if (num_instructions > 0) { std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); - Address addr = start_address; - if (disasm_ap.get()) { - // If we weren't passed in a section offset address range, - // try and resolve it to something - if (addr.IsSectionOffset() == false) - { - if (exe_ctx.target) - { - if (exe_ctx.target->GetSectionLoadList().IsEmpty()) - { - exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), addr); - } - else - { - exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), addr); - } - } - } + Address addr; + ResolveAddress (exe_ctx, start_address, addr); - DataExtractor data; - size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions, data); + size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions); if (bytes_disassembled == 0) return false; return PrintInstructions (disasm_ap.get(), @@ -341,11 +334,12 @@ Disassembler::PrintInstructions if (num_instructions > 0 && num_instructions < num_instructions_found) num_instructions_found = num_instructions; + const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); uint32_t offset = 0; SymbolContext sc; SymbolContext prev_sc; AddressRange sc_range; - Address addr = start_addr; + Address addr (start_addr); if (num_mixed_context_lines) strm.IndentMore (); @@ -425,7 +419,7 @@ Disassembler::PrintInstructions if (num_mixed_context_lines) strm.IndentMore (); strm.Indent(); - inst->Dump(&strm, true, show_bytes, &exe_ctx, raw); + inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw); strm.EOL(); addr.Slide(inst->GetOpcode().GetByteSize()); @@ -492,8 +486,9 @@ Disassembler::Disassemble strm); } -Instruction::Instruction(const Address &address) : +Instruction::Instruction(const Address &address, AddressClass addr_class) : m_address (address), + m_address_class (addr_class), m_opcode() { } @@ -502,6 +497,13 @@ Instruction::~Instruction() { } +AddressClass +Instruction::GetAddressClass () +{ + if (m_address_class == eAddressClassInvalid) + m_address_class = m_address.GetAddressClass(); + return m_address_class; +} InstructionList::InstructionList() : m_instructions() @@ -518,6 +520,23 @@ InstructionList::GetSize() const return m_instructions.size(); } +uint32_t +InstructionList::GetMaxOpcocdeByteSize () const +{ + uint32_t max_inst_size = 0; + collection::const_iterator pos, end; + for (pos = m_instructions.begin(), end = m_instructions.end(); + pos != end; + ++pos) + { + uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); + if (max_inst_size < inst_size) + max_inst_size = inst_size; + } + return max_inst_size; +} + + InstructionSP InstructionList::GetInstructionAtIndex (uint32_t idx) const @@ -546,8 +565,7 @@ size_t Disassembler::ParseInstructions ( const ExecutionContext *exe_ctx, - const AddressRange &range, - DataExtractor& data + const AddressRange &range ) { Target *target = exe_ctx->target; @@ -559,17 +577,20 @@ Disassembler::ParseInstructions DataBufferSP data_sp(heap_buffer); Error error; - bool prefer_file_cache = true; - const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), prefer_file_cache, heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error); + const bool prefer_file_cache = true; + const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), + prefer_file_cache, + heap_buffer->GetBytes(), + heap_buffer->GetByteSize(), + error); if (bytes_read > 0) { if (bytes_read != heap_buffer->GetByteSize()) heap_buffer->SetByteSize (bytes_read); - - data.SetData(data_sp); - data.SetByteOrder(target->GetArchitecture().GetByteOrder()); - data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); + DataExtractor data (data_sp, + m_arch.GetByteOrder(), + m_arch.GetAddressByteSize()); return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); } @@ -581,64 +602,45 @@ Disassembler::ParseInstructions ( const ExecutionContext *exe_ctx, const Address &start, - uint32_t num_instructions, - DataExtractor& data + uint32_t num_instructions ) { - Address addr = start; - - if (num_instructions == 0) + m_instruction_list.Clear(); + + if (num_instructions == 0 || !start.IsValid()) return 0; Target *target = exe_ctx->target; - // We'll guess at a size for the buffer, if we don't get all the instructions we want we can just re-fill & reuse it. - const addr_t byte_size = num_instructions * 2; - addr_t data_offset = 0; - addr_t next_instruction_offset = 0; - size_t buffer_size = byte_size; + // Calculate the max buffer size we will need in order to disassemble + const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); - uint32_t num_instructions_found = 0; - - if (target == NULL || byte_size == 0 || !start.IsValid()) + if (target == NULL || byte_size == 0) return 0; DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); - DataBufferSP data_sp(heap_buffer); - - data.SetData(data_sp); - data.SetByteOrder(target->GetArchitecture().GetByteOrder()); - data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); + DataBufferSP data_sp (heap_buffer); Error error; bool prefer_file_cache = true; - - m_instruction_list.Clear(); - - while (num_instructions_found < num_instructions) - { - if (buffer_size < data_offset + byte_size) - { - buffer_size = data_offset + byte_size; - heap_buffer->SetByteSize (buffer_size); - data.SetData(data_sp); // Resizing might have changed the backing store location, so we have to reset - // the DataBufferSP in the extractor so it changes to pointing at the right thing. - } - const size_t bytes_read = target->ReadMemory (addr, prefer_file_cache, heap_buffer->GetBytes() + data_offset, byte_size, error); - size_t num_bytes_read = 0; - if (bytes_read == 0) - break; - - num_bytes_read = DecodeInstructions (start, data, next_instruction_offset, num_instructions - num_instructions_found, true); - if (num_bytes_read == 0) - break; - num_instructions_found = m_instruction_list.GetSize(); - - // Prepare for the next round. - data_offset += bytes_read; - addr.Slide (bytes_read); - next_instruction_offset += num_bytes_read; - } - + const size_t bytes_read = target->ReadMemory (start, + prefer_file_cache, + heap_buffer->GetBytes(), + byte_size, + error); + + if (bytes_read == 0) + return 0; + DataExtractor data (data_sp, + m_arch.GetByteOrder(), + m_arch.GetAddressByteSize()); + + const bool append_instructions = true; + DecodeInstructions (start, + data, + 0, + num_instructions, + append_instructions); + return m_instruction_list.GetSize(); } diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index a504829d75c..735dde4a5da 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -351,11 +351,12 @@ Module::FindFunctions (const ConstString &name, const uint32_t num_matches = symbol_indexes.size(); if (num_matches) { + const bool merge_symbol_into_function = true; SymbolContext sc(this); for (uint32_t i=0; i<num_matches; i++) { sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); - sc_list.AppendIfUnique (sc); + sc_list.AppendIfUnique (sc, merge_symbol_into_function); } } } @@ -392,11 +393,12 @@ Module::FindFunctions (const RegularExpression& regex, const uint32_t num_matches = symbol_indexes.size(); if (num_matches) { + const bool merge_symbol_into_function = true; SymbolContext sc(this); for (uint32_t i=0; i<num_matches; i++) { sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]); - sc_list.AppendIfUnique (sc); + sc_list.AppendIfUnique (sc, merge_symbol_into_function); } } } diff --git a/lldb/source/Core/Opcode.cpp b/lldb/source/Core/Opcode.cpp index d33c80c76de..b765bf7dd1d 100644 --- a/lldb/source/Core/Opcode.cpp +++ b/lldb/source/Core/Opcode.cpp @@ -48,7 +48,7 @@ Opcode::Dump (Stream *s, uint32_t min_byte_width) for (uint32_t i=0; i<m_data.inst.length; ++i) { if (i > 0) - s->PutChar (' '); + bytes_written += s->PutChar (' '); bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]); } } |