diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectFile')
4 files changed, 539 insertions, 486 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 479d0d82878..ae08a632024 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -464,7 +464,6 @@ ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp, ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) : ObjectFile(module_sp, file, offset, length, data_sp), - m_mutex (Mutex::eMutexTypeRecursive), m_sections_ap(), m_symtab_ap(), m_mach_segments(), @@ -482,7 +481,6 @@ ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) : ObjectFile(module_sp, process_sp, header_addr, header_data_sp), - m_mutex (Mutex::eMutexTypeRecursive), m_sections_ap(), m_symtab_ap(), m_mach_segments(), @@ -503,75 +501,79 @@ ObjectFileMachO::~ObjectFileMachO() bool ObjectFileMachO::ParseHeader () { - lldb_private::Mutex::Locker locker(m_mutex); - bool can_parse = false; - uint32_t offset = 0; - m_data.SetByteOrder (lldb::endian::InlHostByteOrder()); - // Leave magic in the original byte order - m_header.magic = m_data.GetU32(&offset); - switch (m_header.magic) + ModuleSP module_sp(GetModule()); + if (module_sp) { - case HeaderMagic32: - m_data.SetByteOrder (lldb::endian::InlHostByteOrder()); - m_data.SetAddressByteSize(4); - can_parse = true; - break; - - case HeaderMagic64: + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + bool can_parse = false; + uint32_t offset = 0; m_data.SetByteOrder (lldb::endian::InlHostByteOrder()); - m_data.SetAddressByteSize(8); - can_parse = true; - break; + // Leave magic in the original byte order + m_header.magic = m_data.GetU32(&offset); + switch (m_header.magic) + { + case HeaderMagic32: + m_data.SetByteOrder (lldb::endian::InlHostByteOrder()); + m_data.SetAddressByteSize(4); + can_parse = true; + break; - case HeaderMagic32Swapped: - m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); - m_data.SetAddressByteSize(4); - can_parse = true; - break; + case HeaderMagic64: + m_data.SetByteOrder (lldb::endian::InlHostByteOrder()); + m_data.SetAddressByteSize(8); + can_parse = true; + break; - case HeaderMagic64Swapped: - m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); - m_data.SetAddressByteSize(8); - can_parse = true; - break; + case HeaderMagic32Swapped: + m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); + m_data.SetAddressByteSize(4); + can_parse = true; + break; - default: - break; - } + case HeaderMagic64Swapped: + m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); + m_data.SetAddressByteSize(8); + can_parse = true; + break; - if (can_parse) - { - m_data.GetU32(&offset, &m_header.cputype, 6); + default: + break; + } - ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); - - if (SetModulesArchitecture (mach_arch)) + if (can_parse) { - const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic); - if (m_data.GetByteSize() < header_and_lc_size) + m_data.GetU32(&offset, &m_header.cputype, 6); + + ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); + + if (SetModulesArchitecture (mach_arch)) { - DataBufferSP data_sp; - ProcessSP process_sp (m_process_wp.lock()); - if (process_sp) - { - data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size); - } - else + const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic); + if (m_data.GetByteSize() < header_and_lc_size) { - // Read in all only the load command data from the file on disk - data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size); - if (data_sp->GetByteSize() != header_and_lc_size) - return false; + DataBufferSP data_sp; + ProcessSP process_sp (m_process_wp.lock()); + if (process_sp) + { + data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size); + } + else + { + // Read in all only the load command data from the file on disk + data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size); + if (data_sp->GetByteSize() != header_and_lc_size) + return false; + } + if (data_sp) + m_data.SetData (data_sp); } - if (data_sp) - m_data.SetData (data_sp); } + return true; + } + else + { + memset(&m_header, 0, sizeof(struct mach_header)); } - return true; - } - else - { - memset(&m_header, 0, sizeof(struct mach_header)); } return false; } @@ -580,7 +582,6 @@ ObjectFileMachO::ParseHeader () ByteOrder ObjectFileMachO::GetByteOrder () const { - lldb_private::Mutex::Locker locker(m_mutex); return m_data.GetByteOrder (); } @@ -593,7 +594,6 @@ ObjectFileMachO::IsExecutable() const size_t ObjectFileMachO::GetAddressByteSize () const { - lldb_private::Mutex::Locker locker(m_mutex); return m_data.GetAddressByteSize (); } @@ -710,13 +710,17 @@ ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr) Symtab * ObjectFileMachO::GetSymtab() { - lldb_private::Mutex::Locker symfile_locker(m_mutex); - if (m_symtab_ap.get() == NULL) + ModuleSP module_sp(GetModule()); + if (module_sp) { - m_symtab_ap.reset(new Symtab(this)); - Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); - ParseSymtab (true); - m_symtab_ap->Finalize (); + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (m_symtab_ap.get() == NULL) + { + m_symtab_ap.reset(new Symtab(this)); + Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); + ParseSymtab (true); + m_symtab_ap->Finalize (); + } } return m_symtab_ap.get(); } @@ -725,11 +729,15 @@ ObjectFileMachO::GetSymtab() SectionList * ObjectFileMachO::GetSectionList() { - lldb_private::Mutex::Locker locker(m_mutex); - if (m_sections_ap.get() == NULL) + ModuleSP module_sp(GetModule()); + if (module_sp) { - m_sections_ap.reset(new SectionList()); - ParseSections(); + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (m_sections_ap.get() == NULL) + { + m_sections_ap.reset(new SectionList()); + ParseSections(); + } } return m_sections_ap.get(); } @@ -2172,50 +2180,58 @@ ObjectFileMachO::ParseSymtab (bool minimize) void ObjectFileMachO::Dump (Stream *s) { - lldb_private::Mutex::Locker locker(m_mutex); - s->Printf("%p: ", this); - s->Indent(); - if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped) - s->PutCString("ObjectFileMachO64"); - else - s->PutCString("ObjectFileMachO32"); + ModuleSP module_sp(GetModule()); + if (module_sp) + { + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + s->Printf("%p: ", this); + s->Indent(); + if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped) + s->PutCString("ObjectFileMachO64"); + else + s->PutCString("ObjectFileMachO32"); - ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); + ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); - *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; + *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; - if (m_sections_ap.get()) - m_sections_ap->Dump(s, NULL, true, UINT32_MAX); + if (m_sections_ap.get()) + m_sections_ap->Dump(s, NULL, true, UINT32_MAX); - if (m_symtab_ap.get()) - m_symtab_ap->Dump(s, NULL, eSortOrderNone); + if (m_symtab_ap.get()) + m_symtab_ap->Dump(s, NULL, eSortOrderNone); + } } bool ObjectFileMachO::GetUUID (lldb_private::UUID* uuid) { - lldb_private::Mutex::Locker locker(m_mutex); - struct uuid_command load_cmd; - uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); - uint32_t i; - for (i=0; i<m_header.ncmds; ++i) + ModuleSP module_sp(GetModule()); + if (module_sp) { - const uint32_t cmd_offset = offset; - if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) - break; - - if (load_cmd.cmd == LoadCommandUUID) + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + struct uuid_command load_cmd; + uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); + uint32_t i; + for (i=0; i<m_header.ncmds; ++i) { - const uint8_t *uuid_bytes = m_data.PeekData(offset, 16); - if (uuid_bytes) + const uint32_t cmd_offset = offset; + if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) + break; + + if (load_cmd.cmd == LoadCommandUUID) { - uuid->SetBytes (uuid_bytes); - return true; + const uint8_t *uuid_bytes = m_data.PeekData(offset, 16); + if (uuid_bytes) + { + uuid->SetBytes (uuid_bytes); + return true; + } + return false; } - return false; + offset = cmd_offset + load_cmd.cmdsize; } - offset = cmd_offset + load_cmd.cmdsize; } return false; } @@ -2224,45 +2240,49 @@ ObjectFileMachO::GetUUID (lldb_private::UUID* uuid) uint32_t ObjectFileMachO::GetDependentModules (FileSpecList& files) { - lldb_private::Mutex::Locker locker(m_mutex); - struct load_command load_cmd; - uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); uint32_t count = 0; - const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system - uint32_t i; - for (i=0; i<m_header.ncmds; ++i) + ModuleSP module_sp(GetModule()); + if (module_sp) { - const uint32_t cmd_offset = offset; - if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) - break; - - switch (load_cmd.cmd) + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + struct load_command load_cmd; + uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); + const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system + uint32_t i; + for (i=0; i<m_header.ncmds; ++i) { - case LoadCommandDylibLoad: - case LoadCommandDylibLoadWeak: - case LoadCommandDylibReexport: - case LoadCommandDynamicLinkerLoad: - case LoadCommandFixedVMShlibLoad: - case LoadCommandDylibLoadUpward: + const uint32_t cmd_offset = offset; + if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) + break; + + switch (load_cmd.cmd) { - uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); - const char *path = m_data.PeekCStr(name_offset); - // Skip any path that starts with '@' since these are usually: - // @executable_path/.../file - // @rpath/.../file - if (path && path[0] != '@') + case LoadCommandDylibLoad: + case LoadCommandDylibLoadWeak: + case LoadCommandDylibReexport: + case LoadCommandDynamicLinkerLoad: + case LoadCommandFixedVMShlibLoad: + case LoadCommandDylibLoadUpward: { - FileSpec file_spec(path, resolve_path); - if (files.AppendIfUnique(file_spec)) - count++; + uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); + const char *path = m_data.PeekCStr(name_offset); + // Skip any path that starts with '@' since these are usually: + // @executable_path/.../file + // @rpath/.../file + if (path && path[0] != '@') + { + FileSpec file_spec(path, resolve_path); + if (files.AppendIfUnique(file_spec)) + count++; + } } - } - break; + break; - default: - break; + default: + break; + } + offset = cmd_offset + load_cmd.cmdsize; } - offset = cmd_offset + load_cmd.cmdsize; } return count; } @@ -2294,116 +2314,120 @@ ObjectFileMachO::GetEntryPointAddress () // // - lldb_private::Mutex::Locker locker(m_mutex); - struct load_command load_cmd; - uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); - uint32_t i; - lldb::addr_t start_address = LLDB_INVALID_ADDRESS; - bool done = false; - - for (i=0; i<m_header.ncmds; ++i) + ModuleSP module_sp(GetModule()); + if (module_sp) { - const uint32_t cmd_offset = offset; - if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) - break; - - switch (load_cmd.cmd) + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + struct load_command load_cmd; + uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); + uint32_t i; + lldb::addr_t start_address = LLDB_INVALID_ADDRESS; + bool done = false; + + for (i=0; i<m_header.ncmds; ++i) { - case LoadCommandUnixThread: - case LoadCommandThread: + const uint32_t cmd_offset = offset; + if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) + break; + + switch (load_cmd.cmd) { - while (offset < cmd_offset + load_cmd.cmdsize) + case LoadCommandUnixThread: + case LoadCommandThread: { - uint32_t flavor = m_data.GetU32(&offset); - uint32_t count = m_data.GetU32(&offset); - if (count == 0) + while (offset < cmd_offset + load_cmd.cmdsize) { - // We've gotten off somehow, log and exit; - return m_entry_point_address; - } - - switch (m_header.cputype) - { - case llvm::MachO::CPUTypeARM: - if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h - { - offset += 60; // This is the offset of pc in the GPR thread state data structure. - start_address = m_data.GetU32(&offset); - done = true; - } - break; - case llvm::MachO::CPUTypeI386: - if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h - { - offset += 40; // This is the offset of eip in the GPR thread state data structure. - start_address = m_data.GetU32(&offset); - done = true; + uint32_t flavor = m_data.GetU32(&offset); + uint32_t count = m_data.GetU32(&offset); + if (count == 0) + { + // We've gotten off somehow, log and exit; + return m_entry_point_address; } - break; - case llvm::MachO::CPUTypeX86_64: - if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h - { - offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure. - start_address = m_data.GetU64(&offset); - done = true; + + switch (m_header.cputype) + { + case llvm::MachO::CPUTypeARM: + if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h + { + offset += 60; // This is the offset of pc in the GPR thread state data structure. + start_address = m_data.GetU32(&offset); + done = true; + } + break; + case llvm::MachO::CPUTypeI386: + if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h + { + offset += 40; // This is the offset of eip in the GPR thread state data structure. + start_address = m_data.GetU32(&offset); + done = true; + } + break; + case llvm::MachO::CPUTypeX86_64: + if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h + { + offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure. + start_address = m_data.GetU64(&offset); + done = true; + } + break; + default: + return m_entry_point_address; } - break; - default: - return m_entry_point_address; + // Haven't found the GPR flavor yet, skip over the data for this flavor: + if (done) + break; + offset += count * 4; } - // Haven't found the GPR flavor yet, skip over the data for this flavor: - if (done) - break; - offset += count * 4; } - } - break; - case LoadCommandMain: - { - ConstString text_segment_name ("__TEXT"); - uint64_t entryoffset = m_data.GetU64(&offset); - SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name); - if (text_segment_sp) + break; + case LoadCommandMain: { - done = true; - start_address = text_segment_sp->GetFileAddress() + entryoffset; + ConstString text_segment_name ("__TEXT"); + uint64_t entryoffset = m_data.GetU64(&offset); + SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name); + if (text_segment_sp) + { + done = true; + start_address = text_segment_sp->GetFileAddress() + entryoffset; + } } + + default: + break; } + if (done) + break; - default: - break; + // Go to the next load command: + offset = cmd_offset + load_cmd.cmdsize; } - if (done) - break; - - // Go to the next load command: - offset = cmd_offset + load_cmd.cmdsize; - } - - if (start_address != LLDB_INVALID_ADDRESS) - { - // We got the start address from the load commands, so now resolve that address in the sections - // of this ObjectFile: - if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList())) + + if (start_address != LLDB_INVALID_ADDRESS) { - m_entry_point_address.Clear(); + // We got the start address from the load commands, so now resolve that address in the sections + // of this ObjectFile: + if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList())) + { + m_entry_point_address.Clear(); + } } - } - else - { - // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the - // "start" symbol in the main executable. - - ModuleSP module_sp (GetModule()); - - if (module_sp) + else { - SymbolContextList contexts; - SymbolContext context; - if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts)) + // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the + // "start" symbol in the main executable. + + ModuleSP module_sp (GetModule()); + + if (module_sp) { - if (contexts.GetContextAtIndex(0, context)) - m_entry_point_address = context.symbol->GetAddress(); + SymbolContextList contexts; + SymbolContext context; + if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts)) + { + if (contexts.GetContextAtIndex(0, context)) + m_entry_point_address = context.symbol->GetAddress(); + } } } } @@ -2432,26 +2456,30 @@ ObjectFileMachO::GetHeaderAddress () uint32_t ObjectFileMachO::GetNumThreadContexts () { - lldb_private::Mutex::Locker locker(m_mutex); - if (!m_thread_context_offsets_valid) + ModuleSP module_sp(GetModule()); + if (module_sp) { - m_thread_context_offsets_valid = true; - uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); - FileRangeArray::Entry file_range; - thread_command thread_cmd; - for (uint32_t i=0; i<m_header.ncmds; ++i) + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (!m_thread_context_offsets_valid) { - const uint32_t cmd_offset = offset; - if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL) - break; - - if (thread_cmd.cmd == LoadCommandThread) + m_thread_context_offsets_valid = true; + uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); + FileRangeArray::Entry file_range; + thread_command thread_cmd; + for (uint32_t i=0; i<m_header.ncmds; ++i) { - file_range.SetRangeBase (offset); - file_range.SetByteSize (thread_cmd.cmdsize - 8); - m_thread_context_offsets.Append (file_range); + const uint32_t cmd_offset = offset; + if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL) + break; + + if (thread_cmd.cmd == LoadCommandThread) + { + file_range.SetRangeBase (offset); + file_range.SetByteSize (thread_cmd.cmdsize - 8); + m_thread_context_offsets.Append (file_range); + } + offset = cmd_offset + thread_cmd.cmdsize; } - offset = cmd_offset + thread_cmd.cmdsize; } } return m_thread_context_offsets.GetSize(); @@ -2460,30 +2488,35 @@ ObjectFileMachO::GetNumThreadContexts () lldb::RegisterContextSP ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread) { - lldb_private::Mutex::Locker locker(m_mutex); - if (!m_thread_context_offsets_valid) - GetNumThreadContexts (); - lldb::RegisterContextSP reg_ctx_sp; - const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx); - - DataExtractor data (m_data, - thread_context_file_range->GetRangeBase(), - thread_context_file_range->GetByteSize()); - switch (m_header.cputype) + ModuleSP module_sp(GetModule()); + if (module_sp) { - case llvm::MachO::CPUTypeARM: - reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data)); - break; - - case llvm::MachO::CPUTypeI386: - reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data)); - break; - - case llvm::MachO::CPUTypeX86_64: - reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data)); - break; + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (!m_thread_context_offsets_valid) + GetNumThreadContexts (); + + const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx); + + DataExtractor data (m_data, + thread_context_file_range->GetRangeBase(), + thread_context_file_range->GetByteSize()); + + switch (m_header.cputype) + { + case llvm::MachO::CPUTypeARM: + reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data)); + break; + + case llvm::MachO::CPUTypeI386: + reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data)); + break; + + case llvm::MachO::CPUTypeX86_64: + reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data)); + break; + } } return reg_ctx_sp; } @@ -2588,50 +2621,54 @@ ObjectFileMachO::CalculateStrata() uint32_t ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions) { - lldb_private::Mutex::Locker locker(m_mutex); - struct dylib_command load_cmd; - uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); - uint32_t version_cmd = 0; - uint64_t version = 0; - uint32_t i; - for (i=0; i<m_header.ncmds; ++i) + ModuleSP module_sp(GetModule()); + if (module_sp) { - const uint32_t cmd_offset = offset; - if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) - break; - - if (load_cmd.cmd == LoadCommandDylibIdent) + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + struct dylib_command load_cmd; + uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); + uint32_t version_cmd = 0; + uint64_t version = 0; + uint32_t i; + for (i=0; i<m_header.ncmds; ++i) { - if (version_cmd == 0) + const uint32_t cmd_offset = offset; + if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) + break; + + if (load_cmd.cmd == LoadCommandDylibIdent) { - version_cmd = load_cmd.cmd; - if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL) - break; - version = load_cmd.dylib.current_version; + if (version_cmd == 0) + { + version_cmd = load_cmd.cmd; + if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL) + break; + version = load_cmd.dylib.current_version; + } + break; // Break for now unless there is another more complete version + // number load command in the future. } - break; // Break for now unless there is another more complete version - // number load command in the future. + offset = cmd_offset + load_cmd.cmdsize; } - offset = cmd_offset + load_cmd.cmdsize; - } - - if (version_cmd == LoadCommandDylibIdent) - { - if (versions != NULL && num_versions > 0) + + if (version_cmd == LoadCommandDylibIdent) { - if (num_versions > 0) - versions[0] = (version & 0xFFFF0000ull) >> 16; - if (num_versions > 1) - versions[1] = (version & 0x0000FF00ull) >> 8; - if (num_versions > 2) - versions[2] = (version & 0x000000FFull); - // Fill in an remaining version numbers with invalid values - for (i=3; i<num_versions; ++i) - versions[i] = UINT32_MAX; + if (versions != NULL && num_versions > 0) + { + if (num_versions > 0) + versions[0] = (version & 0xFFFF0000ull) >> 16; + if (num_versions > 1) + versions[1] = (version & 0x0000FF00ull) >> 8; + if (num_versions > 2) + versions[2] = (version & 0x000000FFull); + // Fill in an remaining version numbers with invalid values + for (i=3; i<num_versions; ++i) + versions[i] = UINT32_MAX; + } + // The LC_ID_DYLIB load command has a version with 3 version numbers + // in it, so always return 3 + return 3; } - // The LC_ID_DYLIB load command has a version with 3 version numbers - // in it, so always return 3 - return 3; } return false; } @@ -2639,18 +2676,22 @@ ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions) bool ObjectFileMachO::GetArchitecture (ArchSpec &arch) { - lldb_private::Mutex::Locker locker(m_mutex); - arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype); - - // Files with type MH_PRELOAD are currently used in cases where the image - // debugs at the addresses in the file itself. Below we set the OS to - // unknown to make sure we use the DynamicLoaderStatic()... - if (m_header.filetype == HeaderFileTypePreloadedExecutable) + ModuleSP module_sp(GetModule()); + if (module_sp) { - arch.GetTriple().setOS (llvm::Triple::UnknownOS); + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype); + + // Files with type MH_PRELOAD are currently used in cases where the image + // debugs at the addresses in the file itself. Below we set the OS to + // unknown to make sure we use the DynamicLoaderStatic()... + if (m_header.filetype == HeaderFileTypePreloadedExecutable) + { + arch.GetTriple().setOS (llvm::Triple::UnknownOS); + } + return true; } - - return true; + return false; } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 8376cf3406b..0790c6c6de6 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -143,7 +143,6 @@ public: GetVersion (uint32_t *versions, uint32_t num_versions); protected: - mutable lldb_private::Mutex m_mutex; llvm::MachO::mach_header m_header; mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap; mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap; diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 407d76ae588..f908ec0a3c8 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -181,7 +181,6 @@ ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp, addr_t offset, addr_t length) : ObjectFile (module_sp, file, offset, length, dataSP), - m_mutex (Mutex::eMutexTypeRecursive), m_dos_header (), m_coff_header (), m_coff_header_opt (), @@ -201,26 +200,30 @@ ObjectFilePECOFF::~ObjectFilePECOFF() bool ObjectFilePECOFF::ParseHeader () { - Mutex::Locker locker(m_mutex); - m_sect_headers.clear(); - m_data.SetByteOrder (eByteOrderLittle); - uint32_t offset = 0; - - if (ParseDOSHeader()) + ModuleSP module_sp(GetModule()); + if (module_sp) { - offset = m_dos_header.e_lfanew; - uint32_t pe_signature = m_data.GetU32 (&offset); - if (pe_signature != IMAGE_NT_SIGNATURE) - return false; - if (ParseCOFFHeader(&offset)) + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + m_sect_headers.clear(); + m_data.SetByteOrder (eByteOrderLittle); + uint32_t offset = 0; + + if (ParseDOSHeader()) { - if (m_coff_header.hdrsize > 0) - ParseCOFFOptionalHeader(&offset); - ParseSectionHeaders (offset); + offset = m_dos_header.e_lfanew; + uint32_t pe_signature = m_data.GetU32 (&offset); + if (pe_signature != IMAGE_NT_SIGNATURE) + return false; + if (ParseCOFFHeader(&offset)) + { + if (m_coff_header.hdrsize > 0) + ParseCOFFOptionalHeader(&offset); + ParseSectionHeaders (offset); + } + StreamFile s(stdout, false);// REMOVE THIS LINE!!! + Dump(&s);// REMOVE THIS LINE!!! + return true; } - StreamFile s(stdout, false);// REMOVE THIS LINE!!! - Dump(&s);// REMOVE THIS LINE!!! - return true; } return false; } @@ -482,69 +485,73 @@ ObjectFilePECOFF::GetSectionName(std::string& sect_name, const section_header_t& Symtab * ObjectFilePECOFF::GetSymtab() { - Mutex::Locker symfile_locker(m_mutex); - if (m_symtab_ap.get() == NULL) + ModuleSP module_sp(GetModule()); + if (module_sp) { - SectionList *sect_list = GetSectionList(); - m_symtab_ap.reset(new Symtab(this)); - Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); - - const uint32_t num_syms = m_coff_header.nsyms; - - if (num_syms > 0 && m_coff_header.symoff > 0) + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (m_symtab_ap.get() == NULL) { - const uint32_t symbol_size = sizeof(section_header_t); - const uint32_t addr_byte_size = GetAddressByteSize (); - const size_t symbol_data_size = num_syms * symbol_size; - // Include the 4 bytes string table size at the end of the symbols - DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4)); - DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size); - uint32_t offset = symbol_data_size; - const uint32_t strtab_size = symtab_data.GetU32 (&offset); - DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size + 4, strtab_size)); - DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size); - - offset = 0; - std::string symbol_name; - Symbol *symbols = m_symtab_ap->Resize (num_syms); - for (uint32_t i=0; i<num_syms; ++i) + SectionList *sect_list = GetSectionList(); + m_symtab_ap.reset(new Symtab(this)); + Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); + + const uint32_t num_syms = m_coff_header.nsyms; + + if (num_syms > 0 && m_coff_header.symoff > 0) { - coff_symbol_t symbol; - const uint32_t symbol_offset = offset; - const char *symbol_name_cstr = NULL; - // If the first 4 bytes of the symbol string are zero, then we - // it is followed by a 4 byte string table offset. Else these - // 8 bytes contain the symbol name - if (symtab_data.GetU32 (&offset) == 0) + const uint32_t symbol_size = sizeof(section_header_t); + const uint32_t addr_byte_size = GetAddressByteSize (); + const size_t symbol_data_size = num_syms * symbol_size; + // Include the 4 bytes string table size at the end of the symbols + DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4)); + DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size); + uint32_t offset = symbol_data_size; + const uint32_t strtab_size = symtab_data.GetU32 (&offset); + DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size + 4, strtab_size)); + DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size); + + offset = 0; + std::string symbol_name; + Symbol *symbols = m_symtab_ap->Resize (num_syms); + for (uint32_t i=0; i<num_syms; ++i) { - // Long string that doesn't fit into the symbol table name, - // so now we must read the 4 byte string table offset - uint32_t strtab_offset = symtab_data.GetU32 (&offset); - symbol_name_cstr = strtab_data.PeekCStr (strtab_offset); - symbol_name.assign (symbol_name_cstr); + coff_symbol_t symbol; + const uint32_t symbol_offset = offset; + const char *symbol_name_cstr = NULL; + // If the first 4 bytes of the symbol string are zero, then we + // it is followed by a 4 byte string table offset. Else these + // 8 bytes contain the symbol name + if (symtab_data.GetU32 (&offset) == 0) + { + // Long string that doesn't fit into the symbol table name, + // so now we must read the 4 byte string table offset + uint32_t strtab_offset = symtab_data.GetU32 (&offset); + symbol_name_cstr = strtab_data.PeekCStr (strtab_offset); + symbol_name.assign (symbol_name_cstr); + } + else + { + // Short string that fits into the symbol table name which is 8 bytes + offset += sizeof(symbol.name) - 4; // Skip remaining + symbol_name_cstr = symtab_data.PeekCStr (symbol_offset); + if (symbol_name_cstr == NULL) + break; + symbol_name.assign (symbol_name_cstr, sizeof(symbol.name)); + } + symbol.value = symtab_data.GetU32 (&offset); + symbol.sect = symtab_data.GetU16 (&offset); + symbol.type = symtab_data.GetU16 (&offset); + symbol.storage = symtab_data.GetU8 (&offset); + symbol.naux = symtab_data.GetU8 (&offset); + Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1), symbol.value); + symbols[i].GetMangled ().SetValue (symbol_name.c_str(), symbol_name[0]=='_' && symbol_name[1] == 'Z'); + symbols[i].GetAddress() = symbol_addr; + + if (symbol.naux > 0) + i += symbol.naux; } - else - { - // Short string that fits into the symbol table name which is 8 bytes - offset += sizeof(symbol.name) - 4; // Skip remaining - symbol_name_cstr = symtab_data.PeekCStr (symbol_offset); - if (symbol_name_cstr == NULL) - break; - symbol_name.assign (symbol_name_cstr, sizeof(symbol.name)); - } - symbol.value = symtab_data.GetU32 (&offset); - symbol.sect = symtab_data.GetU16 (&offset); - symbol.type = symtab_data.GetU16 (&offset); - symbol.storage = symtab_data.GetU8 (&offset); - symbol.naux = symtab_data.GetU8 (&offset); - Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1), symbol.value); - symbols[i].GetMangled ().SetValue (symbol_name.c_str(), symbol_name[0]=='_' && symbol_name[1] == 'Z'); - symbols[i].GetAddress() = symbol_addr; - - if (symbol.naux > 0) - i += symbol.naux; + } - } } return m_symtab_ap.get(); @@ -554,89 +561,93 @@ ObjectFilePECOFF::GetSymtab() SectionList * ObjectFilePECOFF::GetSectionList() { - Mutex::Locker symfile_locker(m_mutex); - if (m_sections_ap.get() == NULL) + ModuleSP module_sp(GetModule()); + if (module_sp) { - m_sections_ap.reset(new SectionList()); - const uint32_t nsects = m_sect_headers.size(); - ModuleSP module_sp (GetModule()); - for (uint32_t idx = 0; idx<nsects; ++idx) + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (m_sections_ap.get() == NULL) { - std::string sect_name; - GetSectionName (sect_name, m_sect_headers[idx]); - ConstString const_sect_name (sect_name.c_str()); - static ConstString g_code_sect_name (".code"); - static ConstString g_CODE_sect_name ("CODE"); - static ConstString g_data_sect_name (".data"); - static ConstString g_DATA_sect_name ("DATA"); - static ConstString g_bss_sect_name (".bss"); - static ConstString g_BSS_sect_name ("BSS"); - static ConstString g_debug_sect_name (".debug"); - static ConstString g_reloc_sect_name (".reloc"); - static ConstString g_stab_sect_name (".stab"); - static ConstString g_stabstr_sect_name (".stabstr"); - SectionType section_type = eSectionTypeOther; - if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_CODE && - ((const_sect_name == g_code_sect_name) || (const_sect_name == g_CODE_sect_name))) - { - section_type = eSectionTypeCode; - } - else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_INITIALIZED_DATA && - ((const_sect_name == g_data_sect_name) || (const_sect_name == g_DATA_sect_name))) - { - section_type = eSectionTypeData; - } - else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA && - ((const_sect_name == g_bss_sect_name) || (const_sect_name == g_BSS_sect_name))) + m_sections_ap.reset(new SectionList()); + const uint32_t nsects = m_sect_headers.size(); + ModuleSP module_sp (GetModule()); + for (uint32_t idx = 0; idx<nsects; ++idx) { - if (m_sect_headers[idx].size == 0) - section_type = eSectionTypeZeroFill; - else + std::string sect_name; + GetSectionName (sect_name, m_sect_headers[idx]); + ConstString const_sect_name (sect_name.c_str()); + static ConstString g_code_sect_name (".code"); + static ConstString g_CODE_sect_name ("CODE"); + static ConstString g_data_sect_name (".data"); + static ConstString g_DATA_sect_name ("DATA"); + static ConstString g_bss_sect_name (".bss"); + static ConstString g_BSS_sect_name ("BSS"); + static ConstString g_debug_sect_name (".debug"); + static ConstString g_reloc_sect_name (".reloc"); + static ConstString g_stab_sect_name (".stab"); + static ConstString g_stabstr_sect_name (".stabstr"); + SectionType section_type = eSectionTypeOther; + if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_CODE && + ((const_sect_name == g_code_sect_name) || (const_sect_name == g_CODE_sect_name))) + { + section_type = eSectionTypeCode; + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_INITIALIZED_DATA && + ((const_sect_name == g_data_sect_name) || (const_sect_name == g_DATA_sect_name))) + { section_type = eSectionTypeData; - } - else if (const_sect_name == g_debug_sect_name) - { - section_type = eSectionTypeDebug; - } - else if (const_sect_name == g_stabstr_sect_name) - { - section_type = eSectionTypeDataCString; - } - else if (const_sect_name == g_reloc_sect_name) - { - section_type = eSectionTypeOther; - } - else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_CODE) - { - section_type = eSectionTypeCode; - } - else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_INITIALIZED_DATA) - { - section_type = eSectionTypeData; - } - else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) - { - if (m_sect_headers[idx].size == 0) - section_type = eSectionTypeZeroFill; - else + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA && + ((const_sect_name == g_bss_sect_name) || (const_sect_name == g_BSS_sect_name))) + { + if (m_sect_headers[idx].size == 0) + section_type = eSectionTypeZeroFill; + else + section_type = eSectionTypeData; + } + else if (const_sect_name == g_debug_sect_name) + { + section_type = eSectionTypeDebug; + } + else if (const_sect_name == g_stabstr_sect_name) + { + section_type = eSectionTypeDataCString; + } + else if (const_sect_name == g_reloc_sect_name) + { + section_type = eSectionTypeOther; + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_CODE) + { + section_type = eSectionTypeCode; + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_INITIALIZED_DATA) + { section_type = eSectionTypeData; - } + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) + { + if (m_sect_headers[idx].size == 0) + section_type = eSectionTypeZeroFill; + else + section_type = eSectionTypeData; + } - // Use a segment ID of the segment index shifted left by 8 so they - // never conflict with any of the sections. - SectionSP section_sp (new Section (module_sp, // Module to which this section belongs - idx + 1, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible - const_sect_name, // Name of this section - section_type, // This section is a container of other sections. - m_sect_headers[idx].vmaddr, // File VM address == addresses as they are found in the object file - m_sect_headers[idx].vmsize, // VM size in bytes of this section - m_sect_headers[idx].offset, // Offset to the data for this section in the file - m_sect_headers[idx].size, // Size in bytes of this section as found in the the file - m_sect_headers[idx].flags)); // Flags for this section - - //section_sp->SetIsEncrypted (segment_is_encrypted); - - m_sections_ap->AddSection(section_sp); + // Use a segment ID of the segment index shifted left by 8 so they + // never conflict with any of the sections. + SectionSP section_sp (new Section (module_sp, // Module to which this section belongs + idx + 1, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible + const_sect_name, // Name of this section + section_type, // This section is a container of other sections. + m_sect_headers[idx].vmaddr, // File VM address == addresses as they are found in the object file + m_sect_headers[idx].vmsize, // VM size in bytes of this section + m_sect_headers[idx].offset, // Offset to the data for this section in the file + m_sect_headers[idx].size, // Size in bytes of this section as found in the the file + m_sect_headers[idx].flags)); // Flags for this section + + //section_sp->SetIsEncrypted (segment_is_encrypted); + + m_sections_ap->AddSection(section_sp); + } } } return m_sections_ap.get(); @@ -664,33 +675,37 @@ ObjectFilePECOFF::GetDependentModules (FileSpecList& files) void ObjectFilePECOFF::Dump(Stream *s) { - Mutex::Locker locker(m_mutex); - s->Printf("%p: ", this); - s->Indent(); - s->PutCString("ObjectFilePECOFF"); - - ArchSpec header_arch; - GetArchitecture (header_arch); - - *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; - - if (m_sections_ap.get()) - m_sections_ap->Dump(s, NULL, true, UINT32_MAX); - - if (m_symtab_ap.get()) - m_symtab_ap->Dump(s, NULL, eSortOrderNone); - - if (m_dos_header.e_magic) - DumpDOSHeader (s, m_dos_header); - if (m_coff_header.machine) + ModuleSP module_sp(GetModule()); + if (module_sp) { - DumpCOFFHeader (s, m_coff_header); - if (m_coff_header.hdrsize) - DumpOptCOFFHeader (s, m_coff_header_opt); + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + s->Printf("%p: ", this); + s->Indent(); + s->PutCString("ObjectFilePECOFF"); + + ArchSpec header_arch; + GetArchitecture (header_arch); + + *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; + + if (m_sections_ap.get()) + m_sections_ap->Dump(s, NULL, true, UINT32_MAX); + + if (m_symtab_ap.get()) + m_symtab_ap->Dump(s, NULL, eSortOrderNone); + + if (m_dos_header.e_magic) + DumpDOSHeader (s, m_dos_header); + if (m_coff_header.machine) + { + DumpCOFFHeader (s, m_coff_header); + if (m_coff_header.hdrsize) + DumpOptCOFFHeader (s, m_coff_header_opt); + } + s->EOL(); + DumpSectionHeaders(s); + s->EOL(); } - s->EOL(); - DumpSectionHeaders(s); - s->EOL(); } //---------------------------------------------------------------------- diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h index b717a06ae85..2e41ce4ff2b 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -12,7 +12,6 @@ #include <vector> -#include "lldb/Host/Mutex.h" #include "lldb/Symbol/ObjectFile.h" class ObjectFilePECOFF : @@ -228,7 +227,6 @@ protected: typedef SectionHeaderColl::iterator SectionHeaderCollIter; typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter; private: - mutable lldb_private::Mutex m_mutex; mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap; mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap; dos_header_t m_dos_header; |