[Lldb-commits] [lldb] r188246 - <rdar://problem/14717184>
Greg Clayton
gclayton at apple.com
Mon Aug 12 18:42:26 PDT 2013
Author: gclayton
Date: Mon Aug 12 20:42:25 2013
New Revision: 188246
URL: http://llvm.org/viewvc/llvm-project?rev=188246&view=rev
Log:
<rdar://problem/14717184>
LLDB needs in memory module load level settings to control how much information is read from memory when loading in memory modules. This change adds a new setting:
(lldb) settings set target.memory-module-load-level [minimal|partial|complete]
minimal will load only sections (no symbols, or function bounds via function starts or EH frame)
partial will load sections + bounds
complete will load sections + bounds + symbols
Modified:
lldb/trunk/include/lldb/Target/Target.h
lldb/trunk/include/lldb/lldb-private-enumerations.h
lldb/trunk/source/Core/ModuleList.cpp
lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/trunk/source/Target/SectionLoadList.cpp
lldb/trunk/source/Target/Target.cpp
Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=188246&r1=188245&r2=188246&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Mon Aug 12 20:42:25 2013
@@ -170,6 +170,9 @@ public:
Disassembler::HexImmediateStyle
GetHexImmediateStyle() const;
+
+ MemoryModuleLoadLevel
+ GetMemoryModuleLoadLevel() const;
};
Modified: lldb/trunk/include/lldb/lldb-private-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-enumerations.h?rev=188246&r1=188245&r2=188246&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-private-enumerations.h Mon Aug 12 20:42:25 2013
@@ -227,7 +227,18 @@ typedef enum ScriptedCommandSynchronicit
eScriptedCommandSynchronicityAsynchronous,
eScriptedCommandSynchronicityCurrentValue // use whatever the current synchronicity is
} ScriptedCommandSynchronicity;
-
+
+
+//----------------------------------------------------------------------
+// Loading modules from memory
+//----------------------------------------------------------------------
+typedef enum MemoryModuleLoadLevel {
+ eMemoryModuleLoadLevelMinimal, // Load sections only
+ eMemoryModuleLoadLevelPartial, // Load function bounds but no symbols
+ eMemoryModuleLoadLevelComplete, // Load sections and all symbols
+} MemoryModuleLoadLevel;
+
+
} // namespace lldb_private
Modified: lldb/trunk/source/Core/ModuleList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=188246&r1=188245&r2=188246&view=diff
==============================================================================
--- lldb/trunk/source/Core/ModuleList.cpp (original)
+++ lldb/trunk/source/Core/ModuleList.cpp Mon Aug 12 20:42:25 2013
@@ -151,7 +151,10 @@ ModuleList::AppendIfNeeded (const Module
{
bool any_in = false;
for (auto pos : module_list.m_modules)
- any_in = AppendIfNeeded(pos) | any_in;
+ {
+ if (AppendIfNeeded(pos))
+ any_in = true;
+ }
return any_in;
}
Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=188246&r1=188245&r2=188246&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Mon Aug 12 20:42:25 2013
@@ -137,6 +137,7 @@ DynamicLoaderMacOSXDYLD::CreateInstance
DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
DynamicLoader(process),
m_dyld(),
+ m_dyld_module_wp(),
m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
m_dyld_all_image_infos(),
m_dyld_all_image_infos_stop_id (UINT32_MAX),
@@ -425,6 +426,7 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFro
ModuleList modules;
modules.Append(dyld_module_sp);
target.ModulesDidLoad(modules);
+ m_dyld_module_wp = dyld_module_sp;
}
return true;
}
@@ -1342,10 +1344,21 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
if (exe_module_sp.get() != target.GetExecutableModulePointer())
{
// Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded
+ // and find out about all images that are loaded. Also when setting the
+ // executable module, it will clear the targets module list, and if we
+ // have an in memory dyld module, it will get removed from the list
+ // so we will need to add it back after setting the executable module,
+ // so we first try and see if we already have a weak pointer to the
+ // dyld module, make it into a shared pointer, then add the executable,
+ // then re-add it back to make sure it is always in the list.
+ ModuleSP dyld_module_sp(m_dyld_module_wp.lock());
+
const bool get_dependent_images = false;
m_process->GetTarget().SetExecutableModule (exe_module_sp,
get_dependent_images);
+
+ if (dyld_module_sp)
+ target.GetImages().AppendIfNeeded (dyld_module_sp);
}
}
}
Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=188246&r1=188245&r2=188246&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Mon Aug 12 20:42:25 2013
@@ -364,6 +364,7 @@ protected:
DYLDImageInfo m_dyld; // Info about the current dyld being used
+ lldb::ModuleWP m_dyld_module_wp;
lldb::addr_t m_dyld_all_image_infos_addr;
DYLDAllImageInfos m_dyld_all_image_infos;
uint32_t m_dyld_all_image_infos_stop_id;
Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=188246&r1=188245&r2=188246&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Aug 12 20:42:25 2013
@@ -1538,9 +1538,6 @@ ObjectFileMachO::ParseSymtab ()
if (section_list == NULL)
return 0;
- ProcessSP process_sp (m_process_wp.lock());
- Process *process = process_sp.get();
-
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
const ByteOrder byte_order = m_data.GetByteOrder();
bool bit_width_32 = addr_byte_size == 4;
@@ -1554,9 +1551,16 @@ ObjectFileMachO::ParseSymtab ()
const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
const addr_t strtab_data_byte_size = symtab_load_command.strsize;
addr_t strtab_addr = LLDB_INVALID_ADDRESS;
+
+ ProcessSP process_sp (m_process_wp.lock());
+ Process *process = process_sp.get();
+
if (process)
{
Target &target = process->GetTarget();
+
+ const uint32_t memory_module_load_level = target.GetMemoryModuleLoadLevel();
+
SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
// Reading mach file from memory in a process or core file...
@@ -1616,25 +1620,34 @@ ObjectFileMachO::ParseSymtab ()
if (!data_was_read)
{
- DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
- if (nlist_data_sp)
- nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
- //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
- //if (strtab_data_sp)
- // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
- if (m_dysymtab.nindirectsyms != 0)
+ if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
{
- const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
- DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
- if (indirect_syms_data_sp)
- indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
+ DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
+ if (nlist_data_sp)
+ nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
+ // Load strings individually from memory when loading from memory since shared cache
+ // string tables contain strings for all symbols from all shared cached libraries
+ //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
+ //if (strtab_data_sp)
+ // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
+ if (m_dysymtab.nindirectsyms != 0)
+ {
+ const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
+ DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
+ if (indirect_syms_data_sp)
+ indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
+ }
}
- if (function_starts_load_command.cmd)
+
+ if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
{
- const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
- DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
- if (func_start_data_sp)
- function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
+ if (function_starts_load_command.cmd)
+ {
+ const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
+ DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
+ if (func_start_data_sp)
+ function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
+ }
}
}
}
@@ -1661,14 +1674,6 @@ ObjectFileMachO::ParseSymtab ()
}
}
- if (nlist_data.GetByteSize() == 0)
- {
- if (log)
- module_sp->LogMessage(log, "failed to read nlist data");
- return 0;
- }
-
-
const bool have_strtab_data = strtab_data.GetByteSize() > 0;
if (!have_strtab_data)
{
@@ -2701,761 +2706,765 @@ ObjectFileMachO::ParseSymtab ()
// Must reset this in case it was mutated above!
nlist_data_offset = 0;
#endif
-
- // If the sym array was not created while parsing the DSC unmapped
- // symbols, create it now.
- if (sym == NULL)
+
+ if (nlist_data.GetByteSize() > 0)
{
- sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
- num_syms = symtab->GetNumSymbols();
- }
-
- if (unmapped_local_symbols_found)
- {
- assert(m_dysymtab.ilocalsym == 0);
- nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
- nlist_idx = m_dysymtab.nlocalsym;
- }
- else
- {
- nlist_idx = 0;
- }
-
- for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
- {
- struct nlist_64 nlist;
- if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
- break;
-
- nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
- nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
- nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
- nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
- nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
-
- SymbolType type = eSymbolTypeInvalid;
- const char *symbol_name = NULL;
- if (have_strtab_data)
+ // If the sym array was not created while parsing the DSC unmapped
+ // symbols, create it now.
+ if (sym == NULL)
{
- symbol_name = strtab_data.PeekCStr(nlist.n_strx);
+ sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
+ num_syms = symtab->GetNumSymbols();
+ }
- if (symbol_name == NULL)
- {
- // No symbol should be NULL, even the symbols with no
- // string values should have an offset zero which points
- // to an empty C-string
- Host::SystemLog (Host::eSystemLogError,
- "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
- nlist_idx,
- nlist.n_strx,
- module_sp->GetFileSpec().GetPath().c_str());
- continue;
- }
- if (symbol_name[0] == '\0')
- symbol_name = NULL;
+ if (unmapped_local_symbols_found)
+ {
+ assert(m_dysymtab.ilocalsym == 0);
+ nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
+ nlist_idx = m_dysymtab.nlocalsym;
}
else
{
- const addr_t str_addr = strtab_addr + nlist.n_strx;
- Error str_error;
- if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
- symbol_name = memory_symbol_name.c_str();
+ nlist_idx = 0;
}
- const char *symbol_name_non_abi_mangled = NULL;
- SectionSP symbol_section;
- lldb::addr_t symbol_byte_size = 0;
- bool add_nlist = true;
- bool is_gsym = false;
- bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
- bool demangled_is_synthesized = false;
+ for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
+ {
+ struct nlist_64 nlist;
+ if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
+ break;
- assert (sym_idx < num_syms);
+ nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
+ nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
+ nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
+ nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
+ nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
- sym[sym_idx].SetDebug (is_debug);
+ SymbolType type = eSymbolTypeInvalid;
+ const char *symbol_name = NULL;
- if (is_debug)
- {
- switch (nlist.n_type)
+ if (have_strtab_data)
{
- case StabGlobalSymbol:
- // N_GSYM -- global symbol: name,,NO_SECT,type,0
- // Sometimes the N_GSYM value contains the address.
-
- // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
- // have the same address, but we want to ensure that we always find only the real symbol,
- // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
- // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
- // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
- // same address.
-
- if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
- && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
- || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
- || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
- add_nlist = false;
- else
+ symbol_name = strtab_data.PeekCStr(nlist.n_strx);
+
+ if (symbol_name == NULL)
{
- is_gsym = true;
- sym[sym_idx].SetExternal(true);
- if (nlist.n_value != 0)
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeData;
+ // No symbol should be NULL, even the symbols with no
+ // string values should have an offset zero which points
+ // to an empty C-string
+ Host::SystemLog (Host::eSystemLogError,
+ "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
+ nlist_idx,
+ nlist.n_strx,
+ module_sp->GetFileSpec().GetPath().c_str());
+ continue;
}
- break;
+ if (symbol_name[0] == '\0')
+ symbol_name = NULL;
+ }
+ else
+ {
+ const addr_t str_addr = strtab_addr + nlist.n_strx;
+ Error str_error;
+ if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
+ symbol_name = memory_symbol_name.c_str();
+ }
+ const char *symbol_name_non_abi_mangled = NULL;
- case StabFunctionName:
- // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
+ SectionSP symbol_section;
+ lldb::addr_t symbol_byte_size = 0;
+ bool add_nlist = true;
+ bool is_gsym = false;
+ bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
+ bool demangled_is_synthesized = false;
- case StabFunction:
- // N_FUN -- procedure: name,,n_sect,linenumber,address
- if (symbol_name)
- {
- type = eSymbolTypeCode;
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ assert (sym_idx < num_syms);
- N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- N_FUN_indexes.push_back(sym_idx);
- }
- else
+ sym[sym_idx].SetDebug (is_debug);
+
+ if (is_debug)
+ {
+ switch (nlist.n_type)
{
+ case StabGlobalSymbol:
+ // N_GSYM -- global symbol: name,,NO_SECT,type,0
+ // Sometimes the N_GSYM value contains the address.
+
+ // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
+ // have the same address, but we want to ensure that we always find only the real symbol,
+ // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
+ // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
+ // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
+ // same address.
+
+ if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
+ && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
+ || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
+ || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
+ add_nlist = false;
+ else
+ {
+ is_gsym = true;
+ sym[sym_idx].SetExternal(true);
+ if (nlist.n_value != 0)
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeData;
+ }
+ break;
+
+ case StabFunctionName:
+ // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
type = eSymbolTypeCompiler;
+ break;
- if ( !N_FUN_indexes.empty() )
+ case StabFunction:
+ // N_FUN -- procedure: name,,n_sect,linenumber,address
+ if (symbol_name)
{
- // Copy the size of the function into the original STAB entry so we don't have
- // to hunt for it later
- symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
- N_FUN_indexes.pop_back();
- // We don't really need the end function STAB as it contains the size which
- // we already placed with the original symbol, so don't add it if we want a
- // minimal symbol table
- add_nlist = false;
+ type = eSymbolTypeCode;
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+
+ N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
+ // We use the current number of symbols in the symbol table in lieu of
+ // using nlist_idx in case we ever start trimming entries out
+ N_FUN_indexes.push_back(sym_idx);
}
- }
- break;
+ else
+ {
+ type = eSymbolTypeCompiler;
- case StabStaticSymbol:
- // N_STSYM -- static symbol: name,,n_sect,type,address
- N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeData;
- break;
+ if ( !N_FUN_indexes.empty() )
+ {
+ // Copy the size of the function into the original STAB entry so we don't have
+ // to hunt for it later
+ symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
+ N_FUN_indexes.pop_back();
+ // We don't really need the end function STAB as it contains the size which
+ // we already placed with the original symbol, so don't add it if we want a
+ // minimal symbol table
+ add_nlist = false;
+ }
+ }
+ break;
- case StabLocalCommon:
- // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeCommonBlock;
- break;
+ case StabStaticSymbol:
+ // N_STSYM -- static symbol: name,,n_sect,type,address
+ N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeData;
+ break;
- case StabBeginSymbol:
- // N_BNSYM
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
+ case StabLocalCommon:
+ // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeCommonBlock;
+ break;
- case StabEndSymbol:
- // N_ENSYM
- // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- break;
+ case StabBeginSymbol:
+ // N_BNSYM
+ // We use the current number of symbols in the symbol table in lieu of
+ // using nlist_idx in case we ever start trimming entries out
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
+ break;
+ case StabEndSymbol:
+ // N_ENSYM
+ // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
+ // so that we can always skip the entire symbol if we need to navigate
+ // more quickly at the source level when parsing STABS
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
+ break;
- case StabSourceFileOptions:
- // N_OPT - emitted with gcc2_compiled and in gcc source
- type = eSymbolTypeCompiler;
- break;
- case StabRegisterSymbol:
- // N_RSYM - register sym: name,,NO_SECT,type,register
- type = eSymbolTypeVariable;
- break;
+ case StabSourceFileOptions:
+ // N_OPT - emitted with gcc2_compiled and in gcc source
+ type = eSymbolTypeCompiler;
+ break;
- case StabSourceLine:
- // N_SLINE - src line: 0,,n_sect,linenumber,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
+ case StabRegisterSymbol:
+ // N_RSYM - register sym: name,,NO_SECT,type,register
+ type = eSymbolTypeVariable;
+ break;
- case StabStructureType:
- // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
- type = eSymbolTypeVariableType;
- break;
+ case StabSourceLine:
+ // N_SLINE - src line: 0,,n_sect,linenumber,address
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeLineEntry;
+ break;
- case StabSourceFileName:
- // N_SO - source file name
- type = eSymbolTypeSourceFile;
- if (symbol_name == NULL)
- {
- add_nlist = false;
- if (N_SO_index != UINT32_MAX)
+ case StabStructureType:
+ // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
+ type = eSymbolTypeVariableType;
+ break;
+
+ case StabSourceFileName:
+ // N_SO - source file name
+ type = eSymbolTypeSourceFile;
+ if (symbol_name == NULL)
{
- // Set the size of the N_SO to the terminating index of this N_SO
- // so that we can always skip the entire N_SO if we need to navigate
- // more quickly at the source level when parsing STABS
- symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
- symbol_ptr->SetByteSize(sym_idx);
- symbol_ptr->SetSizeIsSibling(true);
- }
- N_NSYM_indexes.clear();
- N_INCL_indexes.clear();
- N_BRAC_indexes.clear();
- N_COMM_indexes.clear();
- N_FUN_indexes.clear();
- N_SO_index = UINT32_MAX;
- }
- else
- {
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- const bool N_SO_has_full_path = symbol_name[0] == '/';
- if (N_SO_has_full_path)
- {
- if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
- {
- // We have two consecutive N_SO entries where the first contains a directory
- // and the second contains a full path.
- sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- add_nlist = false;
- }
- else
+ add_nlist = false;
+ if (N_SO_index != UINT32_MAX)
{
- // This is the first entry in a N_SO that contains a directory or
- // a full path to the source file
- N_SO_index = sym_idx;
+ // Set the size of the N_SO to the terminating index of this N_SO
+ // so that we can always skip the entire N_SO if we need to navigate
+ // more quickly at the source level when parsing STABS
+ symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
+ symbol_ptr->SetByteSize(sym_idx);
+ symbol_ptr->SetSizeIsSibling(true);
}
+ N_NSYM_indexes.clear();
+ N_INCL_indexes.clear();
+ N_BRAC_indexes.clear();
+ N_COMM_indexes.clear();
+ N_FUN_indexes.clear();
+ N_SO_index = UINT32_MAX;
}
- else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+ else
{
- // This is usually the second N_SO entry that contains just the filename,
- // so here we combine it with the first one if we are minimizing the symbol table
- const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
- if (so_path && so_path[0])
+ // We use the current number of symbols in the symbol table in lieu of
+ // using nlist_idx in case we ever start trimming entries out
+ const bool N_SO_has_full_path = symbol_name[0] == '/';
+ if (N_SO_has_full_path)
+ {
+ if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+ {
+ // We have two consecutive N_SO entries where the first contains a directory
+ // and the second contains a full path.
+ sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
+ m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
+ add_nlist = false;
+ }
+ else
+ {
+ // This is the first entry in a N_SO that contains a directory or
+ // a full path to the source file
+ N_SO_index = sym_idx;
+ }
+ }
+ else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
{
- std::string full_so_path (so_path);
- const size_t double_slash_pos = full_so_path.find("//");
- if (double_slash_pos != std::string::npos)
+ // This is usually the second N_SO entry that contains just the filename,
+ // so here we combine it with the first one if we are minimizing the symbol table
+ const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
+ if (so_path && so_path[0])
{
- // The linker has been generating bad N_SO entries with doubled up paths
- // in the format "%s%s" where the first stirng in the DW_AT_comp_dir,
- // and the second is the directory for the source file so you end up with
- // a path that looks like "/tmp/src//tmp/src/"
- FileSpec so_dir(so_path, false);
- if (!so_dir.Exists())
+ std::string full_so_path (so_path);
+ const size_t double_slash_pos = full_so_path.find("//");
+ if (double_slash_pos != std::string::npos)
{
- so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
- if (so_dir.Exists())
+ // The linker has been generating bad N_SO entries with doubled up paths
+ // in the format "%s%s" where the first stirng in the DW_AT_comp_dir,
+ // and the second is the directory for the source file so you end up with
+ // a path that looks like "/tmp/src//tmp/src/"
+ FileSpec so_dir(so_path, false);
+ if (!so_dir.Exists())
{
- // Trim off the incorrect path
- full_so_path.erase(0, double_slash_pos + 1);
+ so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
+ if (so_dir.Exists())
+ {
+ // Trim off the incorrect path
+ full_so_path.erase(0, double_slash_pos + 1);
+ }
}
}
+ if (*full_so_path.rbegin() != '/')
+ full_so_path += '/';
+ full_so_path += symbol_name;
+ sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
+ add_nlist = false;
+ m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
}
- if (*full_so_path.rbegin() != '/')
- full_so_path += '/';
- full_so_path += symbol_name;
- sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
- add_nlist = false;
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
+ }
+ else
+ {
+ // This could be a relative path to a N_SO
+ N_SO_index = sym_idx;
}
}
- else
- {
- // This could be a relative path to a N_SO
- N_SO_index = sym_idx;
- }
- }
- break;
+ break;
- case StabObjectFileName:
- // N_OSO - object file name: name,,0,0,st_mtime
- type = eSymbolTypeObjectFile;
- break;
-
- case StabLocalSymbol:
- // N_LSYM - local sym: name,,NO_SECT,type,offset
- type = eSymbolTypeLocal;
- break;
-
- //----------------------------------------------------------------------
- // INCL scopes
- //----------------------------------------------------------------------
- case StabBeginIncludeFileName:
- // N_BINCL - include file beginning: name,,NO_SECT,0,sum
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- N_INCL_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
+ case StabObjectFileName:
+ // N_OSO - object file name: name,,0,0,st_mtime
+ type = eSymbolTypeObjectFile;
+ break;
+
+ case StabLocalSymbol:
+ // N_LSYM - local sym: name,,NO_SECT,type,offset
+ type = eSymbolTypeLocal;
+ break;
+
+ //----------------------------------------------------------------------
+ // INCL scopes
+ //----------------------------------------------------------------------
+ case StabBeginIncludeFileName:
+ // N_BINCL - include file beginning: name,,NO_SECT,0,sum
+ // We use the current number of symbols in the symbol table in lieu of
+ // using nlist_idx in case we ever start trimming entries out
+ N_INCL_indexes.push_back(sym_idx);
+ type = eSymbolTypeScopeBegin;
+ break;
+
+ case StabEndIncludeFile:
+ // N_EINCL - include file end: name,,NO_SECT,0,0
+ // Set the size of the N_BINCL to the terminating index of this N_EINCL
+ // so that we can always skip the entire symbol if we need to navigate
+ // more quickly at the source level when parsing STABS
+ if ( !N_INCL_indexes.empty() )
+ {
+ symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
+ symbol_ptr->SetByteSize(sym_idx + 1);
+ symbol_ptr->SetSizeIsSibling(true);
+ N_INCL_indexes.pop_back();
+ }
+ type = eSymbolTypeScopeEnd;
+ break;
- case StabEndIncludeFile:
- // N_EINCL - include file end: name,,NO_SECT,0,0
- // Set the size of the N_BINCL to the terminating index of this N_EINCL
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- if ( !N_INCL_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_INCL_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
+ case StabIncludeFileName:
+ // N_SOL - #included file name: name,,n_sect,0,address
+ type = eSymbolTypeHeaderFile;
- case StabIncludeFileName:
- // N_SOL - #included file name: name,,n_sect,0,address
- type = eSymbolTypeHeaderFile;
+ // We currently don't use the header files on darwin
+ add_nlist = false;
+ break;
- // We currently don't use the header files on darwin
- add_nlist = false;
- break;
+ case StabCompilerParameters:
+ // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- case StabCompilerParameters:
- // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
+ case StabCompilerVersion:
+ // N_VERSION - compiler version: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- case StabCompilerVersion:
- // N_VERSION - compiler version: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
+ case StabCompilerOptLevel:
+ // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- case StabCompilerOptLevel:
- // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
+ case StabParameter:
+ // N_PSYM - parameter: name,,NO_SECT,type,offset
+ type = eSymbolTypeVariable;
+ break;
- case StabParameter:
- // N_PSYM - parameter: name,,NO_SECT,type,offset
- type = eSymbolTypeVariable;
- break;
+ case StabAlternateEntry:
+ // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeLineEntry;
+ break;
- case StabAlternateEntry:
- // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
+ //----------------------------------------------------------------------
+ // Left and Right Braces
+ //----------------------------------------------------------------------
+ case StabLeftBracket:
+ // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
+ // We use the current number of symbols in the symbol table in lieu of
+ // using nlist_idx in case we ever start trimming entries out
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ N_BRAC_indexes.push_back(sym_idx);
+ type = eSymbolTypeScopeBegin;
+ break;
+
+ case StabRightBracket:
+ // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
+ // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
+ // so that we can always skip the entire symbol if we need to navigate
+ // more quickly at the source level when parsing STABS
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ if ( !N_BRAC_indexes.empty() )
+ {
+ symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
+ symbol_ptr->SetByteSize(sym_idx + 1);
+ symbol_ptr->SetSizeIsSibling(true);
+ N_BRAC_indexes.pop_back();
+ }
+ type = eSymbolTypeScopeEnd;
+ break;
- //----------------------------------------------------------------------
- // Left and Right Braces
- //----------------------------------------------------------------------
- case StabLeftBracket:
- // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- N_BRAC_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- break;
+ case StabDeletedIncludeFile:
+ // N_EXCL - deleted include file: name,,NO_SECT,0,sum
+ type = eSymbolTypeHeaderFile;
+ break;
+
+ //----------------------------------------------------------------------
+ // COMM scopes
+ //----------------------------------------------------------------------
+ case StabBeginCommon:
+ // N_BCOMM - begin common: name,,NO_SECT,0,0
+ // We use the current number of symbols in the symbol table in lieu of
+ // using nlist_idx in case we ever start trimming entries out
+ type = eSymbolTypeScopeBegin;
+ N_COMM_indexes.push_back(sym_idx);
+ break;
- case StabRightBracket:
- // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
- // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- if ( !N_BRAC_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_BRAC_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- break;
+ case StabEndCommonLocal:
+ // N_ECOML - end common (local name): 0,,n_sect,0,address
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ // Fall through
- case StabDeletedIncludeFile:
- // N_EXCL - deleted include file: name,,NO_SECT,0,sum
- type = eSymbolTypeHeaderFile;
- break;
+ case StabEndCommon:
+ // N_ECOMM - end common: name,,n_sect,0,0
+ // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
+ // so that we can always skip the entire symbol if we need to navigate
+ // more quickly at the source level when parsing STABS
+ if ( !N_COMM_indexes.empty() )
+ {
+ symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
+ symbol_ptr->SetByteSize(sym_idx + 1);
+ symbol_ptr->SetSizeIsSibling(true);
+ N_COMM_indexes.pop_back();
+ }
+ type = eSymbolTypeScopeEnd;
+ break;
- //----------------------------------------------------------------------
- // COMM scopes
- //----------------------------------------------------------------------
- case StabBeginCommon:
- // N_BCOMM - begin common: name,,NO_SECT,0,0
- // We use the current number of symbols in the symbol table in lieu of
- // using nlist_idx in case we ever start trimming entries out
- type = eSymbolTypeScopeBegin;
- N_COMM_indexes.push_back(sym_idx);
- break;
+ case StabLength:
+ // N_LENG - second stab entry with length information
+ type = eSymbolTypeAdditional;
+ break;
- case StabEndCommonLocal:
- // N_ECOML - end common (local name): 0,,n_sect,0,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- // Fall through
-
- case StabEndCommon:
- // N_ECOMM - end common: name,,n_sect,0,0
- // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
- // so that we can always skip the entire symbol if we need to navigate
- // more quickly at the source level when parsing STABS
- if ( !N_COMM_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_COMM_indexes.pop_back();
+ default: break;
}
- type = eSymbolTypeScopeEnd;
- break;
-
- case StabLength:
- // N_LENG - second stab entry with length information
- type = eSymbolTypeAdditional;
- break;
-
- default: break;
}
- }
- else
- {
- //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
- uint8_t n_type = NlistMaskType & nlist.n_type;
- sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
-
- switch (n_type)
+ else
{
- case NListTypeIndirect: // N_INDR - Fall through
- case NListTypePreboundUndefined:// N_PBUD - Fall through
- case NListTypeUndefined: // N_UNDF
- type = eSymbolTypeUndefined;
- break;
+ //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
+ uint8_t n_type = NlistMaskType & nlist.n_type;
+ sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
+
+ switch (n_type)
+ {
+ case NListTypeIndirect: // N_INDR - Fall through
+ case NListTypePreboundUndefined:// N_PBUD - Fall through
+ case NListTypeUndefined: // N_UNDF
+ type = eSymbolTypeUndefined;
+ break;
+
+ case NListTypeAbsolute: // N_ABS
+ type = eSymbolTypeAbsolute;
+ break;
- case NListTypeAbsolute: // N_ABS
- type = eSymbolTypeAbsolute;
- break;
-
- case NListTypeSection: // N_SECT
- {
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-
- if (!symbol_section)
+ case NListTypeSection: // N_SECT
{
- // TODO: warn about this?
- add_nlist = false;
- break;
- }
-
- if (TEXT_eh_frame_sectID == nlist.n_sect)
- {
- type = eSymbolTypeException;
- }
- else
- {
- uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- switch (section_type)
+ if (!symbol_section)
{
- case SectionTypeRegular: break; // regular section
- //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
- case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
- case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
- case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
- case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
- case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
- case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
- case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
- case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
- case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
- //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
- //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
- case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
- case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
- case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
- case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
- default: break;
+ // TODO: warn about this?
+ add_nlist = false;
+ break;
}
- if (type == eSymbolTypeInvalid)
+ if (TEXT_eh_frame_sectID == nlist.n_sect)
+ {
+ type = eSymbolTypeException;
+ }
+ else
{
- const char *symbol_sect_name = symbol_section->GetName().AsCString();
- if (symbol_section->IsDescendant (text_section_sp.get()))
+ uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
+
+ switch (section_type)
{
- if (symbol_section->IsClear(SectionAttrUserPureInstructions |
- SectionAttrUserSelfModifyingCode |
- SectionAttrSytemSomeInstructions))
- type = eSymbolTypeData;
- else
- type = eSymbolTypeCode;
+ case SectionTypeRegular: break; // regular section
+ //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
+ case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
+ case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
+ case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
+ case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
+ case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
+ case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
+ case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
+ case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
+ case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
+ //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
+ //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
+ case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
+ case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
+ case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
+ case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
+ default: break;
}
- else
- if (symbol_section->IsDescendant(data_section_sp.get()))
+
+ if (type == eSymbolTypeInvalid)
{
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
+ const char *symbol_sect_name = symbol_section->GetName().AsCString();
+ if (symbol_section->IsDescendant (text_section_sp.get()))
{
- type = eSymbolTypeRuntime;
-
- if (symbol_name &&
- symbol_name[0] == '_' &&
- symbol_name[1] == 'O' &&
- symbol_name[2] == 'B')
+ if (symbol_section->IsClear(SectionAttrUserPureInstructions |
+ SectionAttrUserSelfModifyingCode |
+ SectionAttrSytemSomeInstructions))
+ type = eSymbolTypeData;
+ else
+ type = eSymbolTypeCode;
+ }
+ else
+ if (symbol_section->IsDescendant(data_section_sp.get()))
+ {
+ if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
{
- llvm::StringRef symbol_name_ref(symbol_name);
- static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
- if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
- {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- }
- else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
+ type = eSymbolTypeRuntime;
+
+ if (symbol_name &&
+ symbol_name[0] == '_' &&
+ symbol_name[1] == 'O' &&
+ symbol_name[2] == 'B')
{
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
+ llvm::StringRef symbol_name_ref(symbol_name);
+ static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
+ static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
+ static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
+ if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
+ {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+ }
+ else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
+ {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
+ type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
+ }
+ else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
+ {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
+ type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
+ }
}
}
+ else
+ if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
+ {
+ type = eSymbolTypeException;
+ }
+ else
+ {
+ type = eSymbolTypeData;
+ }
}
else
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
+ if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
{
- type = eSymbolTypeException;
+ type = eSymbolTypeTrampoline;
}
else
+ if (symbol_section->IsDescendant(objc_section_sp.get()))
{
- type = eSymbolTypeData;
- }
- }
- else
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
- {
- type = eSymbolTypeTrampoline;
- }
- else
- if (symbol_section->IsDescendant(objc_section_sp.get()))
- {
- type = eSymbolTypeRuntime;
- if (symbol_name && symbol_name[0] == '.')
- {
- llvm::StringRef symbol_name_ref(symbol_name);
- static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
- if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
+ type = eSymbolTypeRuntime;
+ if (symbol_name && symbol_name[0] == '.')
{
- symbol_name_non_abi_mangled = symbol_name;
- symbol_name = symbol_name + g_objc_v1_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
+ llvm::StringRef symbol_name_ref(symbol_name);
+ static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
+ if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
+ {
+ symbol_name_non_abi_mangled = symbol_name;
+ symbol_name = symbol_name + g_objc_v1_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+ }
}
}
}
}
}
+ break;
}
- break;
}
- }
- if (add_nlist)
- {
- uint64_t symbol_value = nlist.n_value;
-
- if (symbol_name_non_abi_mangled)
+ if (add_nlist)
{
- sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
- sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
- }
- else
- {
- bool symbol_name_is_mangled = false;
+ uint64_t symbol_value = nlist.n_value;
- if (symbol_name && symbol_name[0] == '_')
+ if (symbol_name_non_abi_mangled)
{
- symbol_name_is_mangled = symbol_name[1] == '_';
- symbol_name++; // Skip the leading underscore
+ sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
+ sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
}
-
- if (symbol_name)
+ else
{
- ConstString const_symbol_name(symbol_name);
- sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
- if (is_gsym && is_debug)
+ bool symbol_name_is_mangled = false;
+
+ if (symbol_name && symbol_name[0] == '_')
{
- N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
+ symbol_name_is_mangled = symbol_name[1] == '_';
+ symbol_name++; // Skip the leading underscore
}
- }
- }
- if (symbol_section)
- {
- const addr_t section_file_addr = symbol_section->GetFileAddress();
- if (symbol_byte_size == 0 && function_starts_count > 0)
- {
- addr_t symbol_lookup_file_addr = nlist.n_value;
- // Do an exact address match for non-ARM addresses, else get the closest since
- // the symbol might be a thumb symbol which has an address with bit zero set
- FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
- if (is_arm && func_start_entry)
+
+ if (symbol_name)
{
- // Verify that the function start address is the symbol address (ARM)
- // or the symbol address + 1 (thumb)
- if (func_start_entry->addr != symbol_lookup_file_addr &&
- func_start_entry->addr != (symbol_lookup_file_addr + 1))
+ ConstString const_symbol_name(symbol_name);
+ sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
+ if (is_gsym && is_debug)
{
- // Not the right entry, NULL it out...
- func_start_entry = NULL;
+ N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
}
}
- if (func_start_entry)
+ }
+ if (symbol_section)
+ {
+ const addr_t section_file_addr = symbol_section->GetFileAddress();
+ if (symbol_byte_size == 0 && function_starts_count > 0)
{
- func_start_entry->data = true;
-
- addr_t symbol_file_addr = func_start_entry->addr;
- if (is_arm)
- symbol_file_addr &= 0xfffffffffffffffeull;
-
- const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
- const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
- if (next_func_start_entry)
+ addr_t symbol_lookup_file_addr = nlist.n_value;
+ // Do an exact address match for non-ARM addresses, else get the closest since
+ // the symbol might be a thumb symbol which has an address with bit zero set
+ FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
+ if (is_arm && func_start_entry)
{
- addr_t next_symbol_file_addr = next_func_start_entry->addr;
- // Be sure the clear the Thumb address bit when we calculate the size
- // from the current and next address
- if (is_arm)
- next_symbol_file_addr &= 0xfffffffffffffffeull;
- symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
+ // Verify that the function start address is the symbol address (ARM)
+ // or the symbol address + 1 (thumb)
+ if (func_start_entry->addr != symbol_lookup_file_addr &&
+ func_start_entry->addr != (symbol_lookup_file_addr + 1))
+ {
+ // Not the right entry, NULL it out...
+ func_start_entry = NULL;
+ }
}
- else
+ if (func_start_entry)
{
- symbol_byte_size = section_end_file_addr - symbol_file_addr;
+ func_start_entry->data = true;
+
+ addr_t symbol_file_addr = func_start_entry->addr;
+ if (is_arm)
+ symbol_file_addr &= 0xfffffffffffffffeull;
+
+ const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
+ const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
+ if (next_func_start_entry)
+ {
+ addr_t next_symbol_file_addr = next_func_start_entry->addr;
+ // Be sure the clear the Thumb address bit when we calculate the size
+ // from the current and next address
+ if (is_arm)
+ next_symbol_file_addr &= 0xfffffffffffffffeull;
+ symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
+ }
+ else
+ {
+ symbol_byte_size = section_end_file_addr - symbol_file_addr;
+ }
}
}
+ symbol_value -= section_file_addr;
}
- symbol_value -= section_file_addr;
- }
- if (is_debug == false)
- {
- if (type == eSymbolTypeCode)
+ if (is_debug == false)
{
- // See if we can find a N_FUN entry for any code symbols.
- // If we do find a match, and the name matches, then we
- // can merge the two into just the function symbol to avoid
- // duplicate entries in the symbol table
- ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
- if (pos != N_FUN_addr_to_sym_idx.end())
+ if (type == eSymbolTypeCode)
{
- if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
+ // See if we can find a N_FUN entry for any code symbols.
+ // If we do find a match, and the name matches, then we
+ // can merge the two into just the function symbol to avoid
+ // duplicate entries in the symbol table
+ ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
+ if (pos != N_FUN_addr_to_sym_idx.end())
{
- m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
- // We just need the flags from the linker symbol, so put these flags
- // into the N_FUN flags to avoid duplicate symbols in the symbol table
- sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- sym[sym_idx].Clear();
- continue;
+ if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
+ {
+ m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
+ // We just need the flags from the linker symbol, so put these flags
+ // into the N_FUN flags to avoid duplicate symbols in the symbol table
+ sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
+ sym[sym_idx].Clear();
+ continue;
+ }
}
}
- }
- else if (type == eSymbolTypeData)
- {
- // See if we can find a N_STSYM entry for any data symbols.
- // If we do find a match, and the name matches, then we
- // can merge the two into just the Static symbol to avoid
- // duplicate entries in the symbol table
- ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
- if (pos != N_STSYM_addr_to_sym_idx.end())
+ else if (type == eSymbolTypeData)
{
- if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
+ // See if we can find a N_STSYM entry for any data symbols.
+ // If we do find a match, and the name matches, then we
+ // can merge the two into just the Static symbol to avoid
+ // duplicate entries in the symbol table
+ ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
+ if (pos != N_STSYM_addr_to_sym_idx.end())
{
- m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
- // We just need the flags from the linker symbol, so put these flags
- // into the N_STSYM flags to avoid duplicate symbols in the symbol table
- sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- sym[sym_idx].Clear();
- continue;
+ if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
+ {
+ m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
+ // We just need the flags from the linker symbol, so put these flags
+ // into the N_STSYM flags to avoid duplicate symbols in the symbol table
+ sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
+ sym[sym_idx].Clear();
+ continue;
+ }
}
- }
- else
- {
- // Combine N_GSYM stab entries with the non stab symbol
- ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
- if (pos != N_GSYM_name_to_sym_idx.end())
+ else
{
- const uint32_t GSYM_sym_idx = pos->second;
- m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
- // Copy the address, because often the N_GSYM address has an invalid address of zero
- // when the global is a common symbol
- sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
- sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
- // We just need the flags from the linker symbol, so put these flags
- // into the N_STSYM flags to avoid duplicate symbols in the symbol table
- sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- sym[sym_idx].Clear();
- continue;
+ // Combine N_GSYM stab entries with the non stab symbol
+ ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
+ if (pos != N_GSYM_name_to_sym_idx.end())
+ {
+ const uint32_t GSYM_sym_idx = pos->second;
+ m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
+ // Copy the address, because often the N_GSYM address has an invalid address of zero
+ // when the global is a common symbol
+ sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
+ sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
+ // We just need the flags from the linker symbol, so put these flags
+ // into the N_STSYM flags to avoid duplicate symbols in the symbol table
+ sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
+ sym[sym_idx].Clear();
+ continue;
+ }
}
}
}
- }
- sym[sym_idx].SetID (nlist_idx);
- sym[sym_idx].SetType (type);
- sym[sym_idx].GetAddress().SetSection (symbol_section);
- sym[sym_idx].GetAddress().SetOffset (symbol_value);
- sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
+ sym[sym_idx].SetID (nlist_idx);
+ sym[sym_idx].SetType (type);
+ sym[sym_idx].GetAddress().SetSection (symbol_section);
+ sym[sym_idx].GetAddress().SetOffset (symbol_value);
+ sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
- if (symbol_byte_size > 0)
- sym[sym_idx].SetByteSize(symbol_byte_size);
+ if (symbol_byte_size > 0)
+ sym[sym_idx].SetByteSize(symbol_byte_size);
- if (demangled_is_synthesized)
- sym[sym_idx].SetDemangledNameIsSynthesized(true);
+ if (demangled_is_synthesized)
+ sym[sym_idx].SetDemangledNameIsSynthesized(true);
- ++sym_idx;
- }
- else
- {
- sym[sym_idx].Clear();
- }
+ ++sym_idx;
+ }
+ else
+ {
+ sym[sym_idx].Clear();
+ }
- }
+ }
- // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
- // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
- // such entries by figuring out what the address for the global is by looking up this non-STAB
- // entry and copying the value into the debug symbol's value to save us the hassle in the
- // debug symbol parser.
-
- Symbol *global_symbol = NULL;
- for (nlist_idx = 0;
- nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
- nlist_idx++)
- {
- if (global_symbol->GetAddress().GetFileAddress() == 0)
+ // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
+ // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
+ // such entries by figuring out what the address for the global is by looking up this non-STAB
+ // entry and copying the value into the debug symbol's value to save us the hassle in the
+ // debug symbol parser.
+
+ Symbol *global_symbol = NULL;
+ for (nlist_idx = 0;
+ nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
+ nlist_idx++)
{
- std::vector<uint32_t> indexes;
- if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
+ if (global_symbol->GetAddress().GetFileAddress() == 0)
{
- std::vector<uint32_t>::const_iterator pos;
- std::vector<uint32_t>::const_iterator end = indexes.end();
- for (pos = indexes.begin(); pos != end; ++pos)
+ std::vector<uint32_t> indexes;
+ if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
{
- symbol_ptr = symtab->SymbolAtIndex(*pos);
- if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
+ std::vector<uint32_t>::const_iterator pos;
+ std::vector<uint32_t>::const_iterator end = indexes.end();
+ for (pos = indexes.begin(); pos != end; ++pos)
{
- global_symbol->GetAddress() = symbol_ptr->GetAddress();
- break;
+ symbol_ptr = symtab->SymbolAtIndex(*pos);
+ if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
+ {
+ global_symbol->GetAddress() = symbol_ptr->GetAddress();
+ break;
+ }
}
}
}
Modified: lldb/trunk/source/Target/SectionLoadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/SectionLoadList.cpp?rev=188246&r1=188245&r2=188246&view=diff
==============================================================================
--- lldb/trunk/source/Target/SectionLoadList.cpp (original)
+++ lldb/trunk/source/Target/SectionLoadList.cpp Mon Aug 12 20:42:25 2013
@@ -61,70 +61,88 @@ SectionLoadList::SetSectionLoadAddress (
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));
- if (log)
+ ModuleSP module_sp (section->GetModule());
+
+ if (module_sp)
{
- const FileSpec &module_file_spec (section->GetModule()->GetFileSpec());
- log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ")",
- __FUNCTION__,
- section.get(),
- module_file_spec.GetPath().c_str(),
- section->GetName().AsCString(),
- load_addr);
- }
+ if (log)
+ {
+ const FileSpec &module_file_spec (module_sp->GetFileSpec());
+ log->Printf ("SectionLoadList::%s (section = %p (%s.%s), load_addr = 0x%16.16" PRIx64 ") module = %p",
+ __FUNCTION__,
+ section.get(),
+ module_file_spec.GetPath().c_str(),
+ section->GetName().AsCString(),
+ load_addr,
+ module_sp.get());
+ }
- if (section->GetByteSize() == 0)
- return false; // No change
+ if (section->GetByteSize() == 0)
+ return false; // No change
- // Fill in the section -> load_addr map
- Mutex::Locker locker(m_mutex);
- sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section.get());
- if (sta_pos != m_sect_to_addr.end())
- {
- if (load_addr == sta_pos->second)
- return false; // No change...
+ // Fill in the section -> load_addr map
+ Mutex::Locker locker(m_mutex);
+ sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section.get());
+ if (sta_pos != m_sect_to_addr.end())
+ {
+ if (load_addr == sta_pos->second)
+ return false; // No change...
+ else
+ sta_pos->second = load_addr;
+ }
else
- sta_pos->second = load_addr;
- }
- else
- m_sect_to_addr[section.get()] = load_addr;
+ m_sect_to_addr[section.get()] = load_addr;
- // Fill in the load_addr -> section map
- addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
- if (ats_pos != m_addr_to_sect.end())
- {
- // Some sections are ok to overlap, and for others we should warn. When
- // we have multiple load addresses that correspond to a section, we will
- // allways attribute the section to the be last section that claims it
- // exists at that address. Sometimes it is ok for more that one section
- // to be loaded at a specific load address, and other times it isn't.
- // The "warn_multiple" parameter tells us if we should warn in this case
- // or not. The DynamicLoader plug-in subclasses should know which
- // sections should warn and which shouldn't (darwin shared cache modules
- // all shared the same "__LINKEDIT" sections, so the dynamic loader can
- // pass false for "warn_multiple").
- if (warn_multiple && section != ats_pos->second)
+ // Fill in the load_addr -> section map
+ addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
+ if (ats_pos != m_addr_to_sect.end())
{
- ModuleSP module_sp (section->GetModule());
- if (module_sp)
+ // Some sections are ok to overlap, and for others we should warn. When
+ // we have multiple load addresses that correspond to a section, we will
+ // allways attribute the section to the be last section that claims it
+ // exists at that address. Sometimes it is ok for more that one section
+ // to be loaded at a specific load address, and other times it isn't.
+ // The "warn_multiple" parameter tells us if we should warn in this case
+ // or not. The DynamicLoader plug-in subclasses should know which
+ // sections should warn and which shouldn't (darwin shared cache modules
+ // all shared the same "__LINKEDIT" sections, so the dynamic loader can
+ // pass false for "warn_multiple").
+ if (warn_multiple && section != ats_pos->second)
{
- ModuleSP curr_module_sp (ats_pos->second->GetModule());
- if (curr_module_sp)
+ ModuleSP module_sp (section->GetModule());
+ if (module_sp)
{
- module_sp->ReportWarning ("address 0x%16.16" PRIx64 " maps to more than one section: %s.%s and %s.%s",
- load_addr,
- module_sp->GetFileSpec().GetFilename().GetCString(),
- section->GetName().GetCString(),
- curr_module_sp->GetFileSpec().GetFilename().GetCString(),
- ats_pos->second->GetName().GetCString());
+ ModuleSP curr_module_sp (ats_pos->second->GetModule());
+ if (curr_module_sp)
+ {
+ module_sp->ReportWarning ("address 0x%16.16" PRIx64 " maps to more than one section: %s.%s and %s.%s",
+ load_addr,
+ module_sp->GetFileSpec().GetFilename().GetCString(),
+ section->GetName().GetCString(),
+ curr_module_sp->GetFileSpec().GetFilename().GetCString(),
+ ats_pos->second->GetName().GetCString());
+ }
}
}
+ ats_pos->second = section;
}
- ats_pos->second = section;
+ else
+ m_addr_to_sect[load_addr] = section;
+ return true; // Changed
+
}
else
- m_addr_to_sect[load_addr] = section;
-
- return true; // Changed
+ {
+ if (log)
+ {
+ log->Printf ("SectionLoadList::%s (section = %p (%s), load_addr = 0x%16.16" PRIx64 ") error: module has been deleted",
+ __FUNCTION__,
+ section.get(),
+ section->GetName().AsCString(),
+ load_addr);
+ }
+ }
+ return false;
}
size_t
Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=188246&r1=188245&r2=188246&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Mon Aug 12 20:42:25 2013
@@ -2313,6 +2313,16 @@ g_load_script_from_sym_file_values[] =
{ 0, NULL, NULL }
};
+
+static OptionEnumValueElement
+g_memory_module_load_level_values[] =
+{
+ { eMemoryModuleLoadLevelMinimal, "minimal" , "Load minimal information when loading modules from memory which currently loads sections only, no symbols."},
+ { eMemoryModuleLoadLevelPartial, "partial" , "Load partial information when loading modules from memory. Currently this setting loads sections and function bounds."},
+ { eMemoryModuleLoadLevelComplete, "complete", "Load complete information when loading modules from memory. Currently this setting loads sections and all symbols."},
+ { 0, NULL, NULL }
+};
+
static PropertyDefinition
g_properties[] =
{
@@ -2354,6 +2364,7 @@ g_properties[] =
{ "hex-immediate-style" , OptionValue::eTypeEnum , false, Disassembler::eHexStyleC, NULL, g_hex_immediate_style_values, "Which style to use for printing hexadecimal disassembly values." },
{ "use-fast-stepping" , OptionValue::eTypeBoolean , false, true, NULL, NULL, "Use a fast stepping algorithm based on running from branch to branch rather than instruction single-stepping." },
{ "load-script-from-symbol-file" , OptionValue::eTypeEnum , false, eLoadScriptFromSymFileWarn, NULL, g_load_script_from_sym_file_values, "Allow LLDB to load scripting resources embedded in symbol files when available." },
+ { "memory-module-load-level" , OptionValue::eTypeEnum , false, eMemoryModuleLoadLevelComplete, NULL, g_memory_module_load_level_values, "Control how much information gets loaded when loading modules from memory. The less information that is gathered, the faster memory modules will be loaded." },
{ NULL , OptionValue::eTypeInvalid , false, 0 , NULL, NULL, NULL }
};
enum
@@ -2385,6 +2396,7 @@ enum
ePropertyHexImmediateStyle,
ePropertyUseFastStepping,
ePropertyLoadScriptFromSymbolFile,
+ ePropertyMemoryModuleLoadLevel
};
@@ -2774,6 +2786,14 @@ TargetProperties::GetHexImmediateStyle (
return (Disassembler::HexImmediateStyle)m_collection_sp->GetPropertyAtIndexAsEnumeration(NULL, idx, g_properties[idx].default_uint_value);
}
+MemoryModuleLoadLevel
+TargetProperties::GetMemoryModuleLoadLevel() const
+{
+ const uint32_t idx = ePropertyMemoryModuleLoadLevel;
+ return (MemoryModuleLoadLevel)m_collection_sp->GetPropertyAtIndexAsEnumeration(NULL, idx, g_properties[idx].default_uint_value);
+}
+
+
const TargetPropertiesSP &
Target::GetGlobalProperties()
{
More information about the lldb-commits
mailing list