summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp')
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp1601
1 files changed, 871 insertions, 730 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index ac03b177c1b..479d0d82878 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1142,887 +1142,1028 @@ ObjectFileMachO::ParseSymtab (bool minimize)
Timer scoped_timer(__PRETTY_FUNCTION__,
"ObjectFileMachO::ParseSymtab () module = %s",
m_file.GetFilename().AsCString(""));
- struct symtab_command symtab_load_command;
+ ModuleSP module_sp (GetModule());
+ if (!module_sp)
+ return 0;
+
+ struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
+ struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
+ typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
+ FunctionStarts function_starts;
uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
-
+
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
for (i=0; i<m_header.ncmds; ++i)
{
const uint32_t cmd_offset = offset;
// Read in the load command and load command size
- if (m_data.GetU32(&offset, &symtab_load_command, 2) == NULL)
+ struct load_command lc;
+ if (m_data.GetU32(&offset, &lc, 2) == NULL)
break;
// Watch for the symbol table load command
- if (symtab_load_command.cmd == LoadCommandSymtab)
+ switch (lc.cmd)
{
+ case LoadCommandSymtab:
+ symtab_load_command.cmd = lc.cmd;
+ symtab_load_command.cmdsize = lc.cmdsize;
// Read in the rest of the symtab load command
- if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4)) // fill in symoff, nsyms, stroff, strsize fields
+ if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
+ return 0;
+ if (symtab_load_command.symoff == 0)
{
- if (symtab_load_command.symoff == 0)
- {
- if (log)
- GetModule()->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
- return 0;
- }
-
- if (symtab_load_command.stroff == 0)
- {
- if (log)
- GetModule()->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
- return 0;
- }
-
- if (symtab_load_command.nsyms == 0)
- {
- if (log)
- GetModule()->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
- return 0;
- }
-
- if (symtab_load_command.strsize == 0)
- {
- if (log)
- GetModule()->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
- return 0;
- }
+ if (log)
+ module_sp->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
+ return 0;
+ }
- Symtab *symtab = m_symtab_ap.get();
- SectionList *section_list = GetSectionList();
- if (section_list == NULL)
- return 0;
+ if (symtab_load_command.stroff == 0)
+ {
+ if (log)
+ module_sp->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
+ return 0;
+ }
+
+ if (symtab_load_command.nsyms == 0)
+ {
+ if (log)
+ module_sp->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
+ return 0;
+ }
+
+ if (symtab_load_command.strsize == 0)
+ {
+ if (log)
+ module_sp->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
+ return 0;
+ }
+ break;
- ProcessSP process_sp (m_process_wp.lock());
+ case LoadCommandFunctionStarts:
+ function_starts_load_command.cmd = lc.cmd;
+ function_starts_load_command.cmdsize = lc.cmdsize;
+ if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
+ bzero (&function_starts_load_command, sizeof(function_starts_load_command));
+ break;
- const size_t addr_byte_size = m_data.GetAddressByteSize();
- bool bit_width_32 = addr_byte_size == 4;
- const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
+ default:
+ break;
+ }
+ offset = cmd_offset + lc.cmdsize;
+ }
- DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
- DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ if (symtab_load_command.cmd)
+ {
+ Symtab *symtab = m_symtab_ap.get();
+ SectionList *section_list = GetSectionList();
+ if (section_list == NULL)
+ return 0;
- 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;
- if (process_sp)
- {
- Target &target = process_sp->GetTarget();
- SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
- // Reading mach file from memory in a process or core file...
+ ProcessSP process_sp (m_process_wp.lock());
- if (linkedit_section_sp)
- {
- const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
- const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
- const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
- const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
- 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, stroff_addr, strtab_data_byte_size));
- if (strtab_data_sp)
- strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
- }
- }
- else
- {
- nlist_data.SetData (m_data,
- symtab_load_command.symoff,
- nlist_data_byte_size);
- strtab_data.SetData (m_data,
- symtab_load_command.stroff,
- strtab_data_byte_size);
+ const size_t addr_byte_size = m_data.GetAddressByteSize();
+ bool bit_width_32 = addr_byte_size == 4;
+ const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
- }
+ DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+
+ 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;
+ if (process_sp)
+ {
+ Target &target = process_sp->GetTarget();
+ SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
+ // Reading mach file from memory in a process or core file...
- if (nlist_data.GetByteSize() == 0)
+ if (linkedit_section_sp)
+ {
+ const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
+ const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
+ const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
+ const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
+ 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, stroff_addr, strtab_data_byte_size));
+ if (strtab_data_sp)
+ strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
+ if (function_starts_load_command.cmd)
{
- if (log)
- GetModule()->LogMessage(log.get(), "failed to read nlist data");
- return 0;
+ 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());
}
+ }
+ }
+ else
+ {
+ nlist_data.SetData (m_data,
+ symtab_load_command.symoff,
+ nlist_data_byte_size);
+ strtab_data.SetData (m_data,
+ symtab_load_command.stroff,
+ strtab_data_byte_size);
+ if (function_starts_load_command.cmd)
+ {
+ function_starts_data.SetData (m_data,
+ function_starts_load_command.dataoff,
+ function_starts_load_command.datasize);
+ }
+ }
+ if (nlist_data.GetByteSize() == 0)
+ {
+ if (log)
+ module_sp->LogMessage(log.get(), "failed to read nlist data");
+ return 0;
+ }
- if (strtab_data.GetByteSize() == 0)
- {
- if (log)
- GetModule()->LogMessage(log.get(), "failed to read strtab data");
- return 0;
- }
- const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
- const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
- const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
- const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
- SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
- SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
- SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
- SectionSP eh_frame_section_sp;
- if (text_section_sp.get())
- eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
- else
- eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
-
- uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
-
- uint32_t nlist_data_offset = 0;
-
- uint32_t N_SO_index = UINT32_MAX;
-
- MachSymtabSectionInfo section_info (section_list);
- std::vector<uint32_t> N_FUN_indexes;
- std::vector<uint32_t> N_NSYM_indexes;
- std::vector<uint32_t> N_INCL_indexes;
- std::vector<uint32_t> N_BRAC_indexes;
- std::vector<uint32_t> N_COMM_indexes;
- typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
- typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
- ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
- ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
- // Any symbols that get merged into another will get an entry
- // in this map so we know
- NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
- uint32_t nlist_idx = 0;
- Symbol *symbol_ptr = NULL;
-
- uint32_t sym_idx = 0;
- Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
- uint32_t num_syms = symtab->GetNumSymbols();
-
- //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
- for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
+ if (strtab_data.GetByteSize() == 0)
+ {
+ if (log)
+ module_sp->LogMessage(log.get(), "failed to read strtab data");
+ return 0;
+ }
+
+ const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
+ const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
+ const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
+ const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
+ SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
+ SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
+ SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
+ SectionSP eh_frame_section_sp;
+ if (text_section_sp.get())
+ eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
+ else
+ eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
+
+
+ if (text_section_sp && function_starts_data.GetByteSize())
+ {
+ FunctionStarts::Entry function_start_entry;
+ function_start_entry.data = false;
+ uint32_t function_start_offset = 0;
+ function_start_entry.addr = text_section_sp->GetFileAddress();
+ uint64_t delta;
+ while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
+ {
+ // Now append the current entry
+ function_start_entry.addr += delta;
+ function_starts.Append(function_start_entry);
+ }
+ }
+
+ const uint32_t function_starts_count = function_starts.GetSize();
+
+ uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
+
+ uint32_t nlist_data_offset = 0;
+
+ uint32_t N_SO_index = UINT32_MAX;
+
+ MachSymtabSectionInfo section_info (section_list);
+ std::vector<uint32_t> N_FUN_indexes;
+ std::vector<uint32_t> N_NSYM_indexes;
+ std::vector<uint32_t> N_INCL_indexes;
+ std::vector<uint32_t> N_BRAC_indexes;
+ std::vector<uint32_t> N_COMM_indexes;
+ typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
+ typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
+ ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
+ ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
+ // Any symbols that get merged into another will get an entry
+ // in this map so we know
+ NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
+ uint32_t nlist_idx = 0;
+ Symbol *symbol_ptr = NULL;
+
+ uint32_t sym_idx = 0;
+ Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
+ uint32_t num_syms = symtab->GetNumSymbols();
+
+ //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
+ for (nlist_idx = 0; 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 = strtab_data.PeekCStr(nlist.n_strx);
+ 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/%s, ignoring symbol\n",
+ nlist_idx,
+ nlist.n_strx,
+ module_sp->GetFileSpec().GetDirectory().GetCString(),
+ module_sp->GetFileSpec().GetFilename().GetCString());
+ continue;
+ }
+ const char *symbol_name_non_abi_mangled = NULL;
+
+ if (symbol_name[0] == '\0')
+ symbol_name = NULL;
+ SectionSP symbol_section;
+ uint32_t symbol_byte_size = 0;
+ bool add_nlist = true;
+ bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
+
+ assert (sym_idx < num_syms);
+
+ sym[sym_idx].SetDebug (is_debug);
+
+ if (is_debug)
+ {
+ switch (nlist.n_type)
{
- struct nlist_64 nlist;
- if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
- break;
+ 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
+ {
+ sym[sym_idx].SetExternal(true);
+ if (nlist.n_value != 0)
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ type = eSymbolTypeData;
+ }
+ 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);
+ case StabFunctionName:
+ // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- SymbolType type = eSymbolTypeInvalid;
- const char *symbol_name = strtab_data.PeekCStr(nlist.n_strx);
- if (symbol_name == NULL)
+ 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);
+
+ 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
{
- ModuleSP module_sp (GetModule());
- // No symbol should be NULL, even the symbols with no
- // string values should have an offset zero which points
- // to an empty C-string
- if (module_sp)
+ type = eSymbolTypeCompiler;
+
+ if ( !N_FUN_indexes.empty() )
{
- Host::SystemLog (Host::eSystemLogError,
- "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
- nlist_idx,
- nlist.n_strx,
- module_sp->GetFileSpec().GetDirectory().GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ // 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
+ if (minimize)
+ add_nlist = false;
}
- continue;
}
- const char *symbol_name_non_abi_mangled = NULL;
+ break;
- if (symbol_name[0] == '\0')
- symbol_name = NULL;
- SectionSP symbol_section;
- bool add_nlist = true;
- bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
+ 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;
- assert (sym_idx < num_syms);
+ 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;
- sym[sym_idx].SetDebug (is_debug);
+ 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
+ if (minimize)
+ {
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
+ }
+ else
+ {
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ N_NSYM_indexes.push_back(sym_idx);
+ type = eSymbolTypeScopeBegin;
+ }
+ break;
- if (is_debug)
+ 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
+ if (minimize)
{
- switch (nlist.n_type)
+ // Skip these if we want minimal symbol tables
+ add_nlist = false;
+ }
+ else
+ {
+ if ( !N_NSYM_indexes.empty() )
{
- 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
- {
- 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;
+ symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
+ symbol_ptr->SetByteSize(sym_idx + 1);
+ symbol_ptr->SetSizeIsSibling(true);
+ N_NSYM_indexes.pop_back();
+ }
+ type = eSymbolTypeScopeEnd;
+ }
+ break;
- 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);
-
- 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
- {
- type = eSymbolTypeCompiler;
- 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
- if (minimize)
- add_nlist = false;
- }
- }
- break;
+ case StabSourceFileOptions:
+ // N_OPT - emitted with gcc2_compiled and in gcc source
+ type = eSymbolTypeCompiler;
+ 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 StabRegisterSymbol:
+ // N_RSYM - register sym: name,,NO_SECT,type,register
+ type = eSymbolTypeVariable;
+ 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 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 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
- if (minimize)
- {
- // Skip these if we want minimal symbol tables
- add_nlist = false;
- }
- else
- {
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- N_NSYM_indexes.push_back(sym_idx);
- type = eSymbolTypeScopeBegin;
- }
- break;
+ case StabStructureType:
+ // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
+ type = eSymbolTypeVariableType;
+ 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
+ case StabSourceFileName:
+ // N_SO - source file name
+ type = eSymbolTypeSourceFile;
+ if (symbol_name == NULL)
+ {
+ if (minimize)
+ add_nlist = false;
+ if (N_SO_index != UINT32_MAX)
+ {
+ // 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
- if (minimize)
+ symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
+ symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
+ 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
+ if (symbol_name[0] == '/')
+ N_SO_index = sym_idx;
+ else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
+ {
+ const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
+ if (so_path && so_path[0])
{
- // Skip these if we want minimal symbol tables
+ std::string full_so_path (so_path);
+ if (*full_so_path.rbegin() != '/')
+ full_so_path += '/';
+ full_so_path += symbol_name;
+ sym[sym_idx - 1].GetMangled().SetValue(full_so_path.c_str(), false);
add_nlist = false;
+ m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
}
- else
- {
- if ( !N_NSYM_indexes.empty() )
- {
- symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
- symbol_ptr->SetByteSize(sym_idx + 1);
- symbol_ptr->SetSizeIsSibling(true);
- N_NSYM_indexes.pop_back();
- }
- type = eSymbolTypeScopeEnd;
- }
- 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 StabSourceLine:
- // N_SLINE - src line: 0,,n_sect,linenumber,address
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- type = eSymbolTypeLineEntry;
- break;
+ }
+ }
+
+ break;
- case StabStructureType:
- // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
- type = eSymbolTypeVariableType;
- break;
+ case StabObjectFileName:
+ // N_OSO - object file name: name,,0,0,st_mtime
+ type = eSymbolTypeObjectFile;
+ break;
- case StabSourceFileName:
- // N_SO - source file name
- type = eSymbolTypeSourceFile;
- if (symbol_name == NULL)
- {
- if (minimize)
- add_nlist = false;
- if (N_SO_index != UINT32_MAX)
- {
- // 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 + (minimize ? 0 : 1));
- 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
- if (symbol_name[0] == '/')
- N_SO_index = sym_idx;
- else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
- {
- const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
- if (so_path && so_path[0])
- {
- std::string full_so_path (so_path);
- if (*full_so_path.rbegin() != '/')
- full_so_path += '/';
- full_so_path += symbol_name;
- sym[sym_idx - 1].GetMangled().SetValue(full_so_path.c_str(), false);
- add_nlist = false;
- m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
- }
- }
- }
-
- break;
+ case StabLocalSymbol:
+ // N_LSYM - local sym: name,,NO_SECT,type,offset
+ type = eSymbolTypeLocal;
+ break;
- case StabObjectFileName:
- // N_OSO - object file name: name,,0,0,st_mtime
- type = eSymbolTypeObjectFile;
- 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 StabLocalSymbol:
- // N_LSYM - local sym: name,,NO_SECT,type,offset
- type = eSymbolTypeLocal;
- 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;
- //----------------------------------------------------------------------
- // 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 StabIncludeFileName:
+ // N_SOL - #included file name: name,,n_sect,0,address
+ type = eSymbolTypeHeaderFile;
- 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;
+ // We currently don't use the header files on darwin
+ if (minimize)
+ add_nlist = false;
+ break;
- case StabIncludeFileName:
- // N_SOL - #included file name: name,,n_sect,0,address
- type = eSymbolTypeHeaderFile;
+ case StabCompilerParameters:
+ // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- // We currently don't use the header files on darwin
- if (minimize)
- add_nlist = false;
- break;
+ case StabCompilerVersion:
+ // N_VERSION - compiler version: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- case StabCompilerParameters:
- // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
+ case StabCompilerOptLevel:
+ // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
+ type = eSymbolTypeCompiler;
+ break;
- case StabCompilerVersion:
- // N_VERSION - compiler version: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- break;
+ case StabParameter:
+ // N_PSYM - parameter: name,,NO_SECT,type,offset
+ type = eSymbolTypeVariable;
+ break;
- case StabCompilerOptLevel:
- // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
- type = eSymbolTypeCompiler;
- 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 StabParameter:
- // N_PSYM - parameter: name,,NO_SECT,type,offset
- type = eSymbolTypeVariable;
- 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 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 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;
- 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;
+ //----------------------------------------------------------------------
+ // 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 StabDeletedIncludeFile:
- // N_EXCL - deleted include file: name,,NO_SECT,0,sum
- type = eSymbolTypeHeaderFile;
- 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();
+ }
+ 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
+ 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);
- 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;
+ switch (n_type)
+ {
+ case NListTypeIndirect: // N_INDR - Fall through
+ case NListTypePreboundUndefined:// N_PBUD - Fall through
+ case NListTypeUndefined: // N_UNDF
+ type = eSymbolTypeUndefined;
+ break;
- case StabLength:
- // N_LENG - second stab entry with length information
- type = eSymbolTypeAdditional;
- break;
+ case NListTypeAbsolute: // N_ABS
+ type = eSymbolTypeAbsolute;
+ break;
- default: break;
- }
- }
- else
+ case NListTypeSection: // N_SECT
{
- //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);
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- switch (n_type)
+ if (symbol_section == NULL)
{
- 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;
+ // TODO: warn about this?
+ add_nlist = false;
break;
+ }
- case NListTypeSection: // N_SECT
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
+ if (TEXT_eh_frame_sectID == nlist.n_sect)
+ {
+ type = eSymbolTypeException;
+ }
+ else
+ {
+ uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
- if (symbol_section == NULL)
+ switch (section_type)
{
- // TODO: warn about this?
- add_nlist = false;
- break;
+ 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;
}
- if (TEXT_eh_frame_sectID == nlist.n_sect)
+ if (type == eSymbolTypeInvalid)
{
- type = eSymbolTypeException;
- }
- else
- {
- uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
-
- switch (section_type)
+ const char *symbol_sect_name = symbol_section->GetName().AsCString();
+ if (symbol_section->IsDescendant (text_section_sp.get()))
{
- 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;
+ if (symbol_section->IsClear(SectionAttrUserPureInstructions |
+ SectionAttrUserSelfModifyingCode |
+ SectionAttrSytemSomeInstructions))
+ type = eSymbolTypeData;
+ else
+ type = eSymbolTypeCode;
}
-
- if (type == eSymbolTypeInvalid)
+ else
+ if (symbol_section->IsDescendant(data_section_sp.get()))
{
- const char *symbol_sect_name = symbol_section->GetName().AsCString();
- if (symbol_section->IsDescendant (text_section_sp.get()))
+ if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
{
- 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)
- {
- type = eSymbolTypeRuntime;
+ type = eSymbolTypeRuntime;
- if (symbol_name &&
- symbol_name[0] == '_' &&
- symbol_name[1] == 'O' &&
- symbol_name[2] == 'B')
+ if (symbol_name &&
+ symbol_name[0] == '_' &&
+ symbol_name[1] == 'O' &&
+ symbol_name[2] == 'B')
+ {
+ 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))
{
- 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;
- }
- 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;
- }
- 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;
- }
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ }
+ 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;
+ }
+ 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;
}
- }
- 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, "__IMPORT") == symbol_sect_name)
+ if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
{
- type = eSymbolTypeTrampoline;
+ type = eSymbolTypeException;
}
else
- if (symbol_section->IsDescendant(objc_section_sp.get()))
{
- type = eSymbolTypeRuntime;
- if (symbol_name && symbol_name[0] == '.')
+ 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))
{
- 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;
- }
+ symbol_name_non_abi_mangled = symbol_name;
+ symbol_name = symbol_name + g_objc_v1_prefix_class.size();
+ type = eSymbolTypeObjCClass;
}
}
}
}
- break;
- }
+ }
}
+ break;
+ }
+ }
+
+ if (add_nlist)
+ {
+ uint64_t symbol_value = nlist.n_value;
+ bool symbol_name_is_mangled = false;
- if (add_nlist)
+ if (symbol_name_non_abi_mangled)
+ {
+ sym[sym_idx].GetMangled().SetMangledName (symbol_name_non_abi_mangled);
+ sym[sym_idx].GetMangled().SetDemangledName (symbol_name);
+ }
+ else
+ {
+ if (symbol_name && symbol_name[0] == '_')
{
- uint64_t symbol_value = nlist.n_value;
- bool symbol_name_is_mangled = false;
+ symbol_name_is_mangled = symbol_name[1] == '_';
+ symbol_name++; // Skip the leading underscore
+ }
- if (symbol_name_non_abi_mangled)
- {
- sym[sym_idx].GetMangled().SetMangledName (symbol_name_non_abi_mangled);
- sym[sym_idx].GetMangled().SetDemangledName (symbol_name);
- }
- else
+ if (symbol_name)
+ {
+ sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
+ }
+ }
+
+ if (is_debug == false)
+ {
+ if (type == eSymbolTypeCode)
+ {
+ // 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 (symbol_name && symbol_name[0] == '_')
+ if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
+ (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
{
- symbol_name_is_mangled = symbol_name[1] == '_';
- symbol_name++; // Skip the leading underscore
+ 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 (symbol_name)
+ }
+ }
+ 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())
+ {
+ if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
+ (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
{
- sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
+ 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 (is_debug == false)
+ }
+ }
+ if (symbol_section)
+ {
+ const addr_t section_file_addr = symbol_section->GetFileAddress();
+ if (symbol_byte_size == 0 && function_starts_count > 0)
+ {
+ FunctionStarts::Entry *func_start_entry = function_starts.FindEntry(nlist.n_value, true);
+ if (func_start_entry)
{
- if (type == eSymbolTypeCode)
+ func_start_entry->data = true;
+ 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)
{
- // 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 ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
- (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
- {
- 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;
- }
- }
+ symbol_byte_size = std::min<lldb::addr_t>(next_func_start_entry->addr - func_start_entry->addr, section_end_file_addr - func_start_entry->addr);
}
- else if (type == eSymbolTypeData)
+ else
{
- // 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())
- {
- if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
- (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
- {
- 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;
- }
- }
+ symbol_byte_size = section_end_file_addr - func_start_entry->addr;
}
}
- if (symbol_section != NULL)
- symbol_value -= symbol_section->GetFileAddress();
+ }
+ symbol_value -= section_file_addr;
+ }
- 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);
- ++sym_idx;
- }
- else
+ if (symbol_byte_size > 0)
+ sym[sym_idx].SetByteSize(symbol_byte_size);
+
+ ++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)
+ {
+ std::vector<uint32_t> indexes;
+ if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
+ {
+ std::vector<uint32_t>::const_iterator pos;
+ std::vector<uint32_t>::const_iterator end = indexes.end();
+ for (pos = indexes.begin(); pos != end; ++pos)
{
- sym[sym_idx].Clear();
+ symbol_ptr = symtab->SymbolAtIndex(*pos);
+ if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
+ {
+ global_symbol->GetAddress() = symbol_ptr->GetAddress();
+ break;
+ }
}
-
}
+ }
+ }
+
+ uint32_t synthetic_sym_id = symtab_load_command.nsyms;
- // 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 (function_starts_count > 0)
+ {
+ char synthetic_function_symbol[PATH_MAX];
+ uint32_t num_synthetic_function_symbols = 0;
+ for (i=0; i<function_starts_count; ++i)
+ {
+ if (function_starts.GetEntryRef (i).data == false)
+ ++num_synthetic_function_symbols;
+ }
+
+ if (num_synthetic_function_symbols > 0)
+ {
+ if (num_syms < sym_idx + num_synthetic_function_symbols)
{
- if (global_symbol->GetAddress().GetFileAddress() == 0)
+ num_syms = sym_idx + num_synthetic_function_symbols;
+ sym = symtab->Resize (num_syms);
+ }
+ uint32_t synthetic_function_symbol_idx = 0;
+ for (i=0; i<function_starts_count; ++i)
+ {
+ const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
+ if (func_start_entry->data == false)
{
- std::vector<uint32_t> indexes;
- if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
+ Address symbol_addr;
+ if (module_sp->ResolveFileAddress (func_start_entry->addr, symbol_addr))
{
- std::vector<uint32_t>::const_iterator pos;
- std::vector<uint32_t>::const_iterator end = indexes.end();
- for (pos = indexes.begin(); pos != end; ++pos)
+ SectionSP symbol_section (symbol_addr.GetSection());
+ uint32_t symbol_byte_size = 0;
+ if (symbol_section)
{
- symbol_ptr = symtab->SymbolAtIndex(*pos);
- if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
+ const addr_t section_file_addr = symbol_section->GetFileAddress();
+ 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)
+ {
+ symbol_byte_size = std::min<lldb::addr_t>(next_func_start_entry->addr - func_start_entry->addr, section_end_file_addr - func_start_entry->addr);
+ }
+ else
{
- global_symbol->GetAddress() = symbol_ptr->GetAddress();
- break;
+ symbol_byte_size = section_end_file_addr - func_start_entry->addr;
}
+ snprintf (synthetic_function_symbol,
+ sizeof(synthetic_function_symbol),
+ "___lldb_unnamed_function%u$$%s",
+ ++synthetic_function_symbol_idx,
+ module_sp->GetFileSpec().GetFilename().GetCString());
+ sym[sym_idx].SetID (synthetic_sym_id++);
+ sym[sym_idx].GetMangled().SetDemangledName(synthetic_function_symbol);
+ sym[sym_idx].SetType (eSymbolTypeCode);
+ sym[sym_idx].SetIsSynthetic (true);
+ sym[sym_idx].GetAddress() = symbol_addr;
+ if (symbol_byte_size)
+ sym[sym_idx].SetByteSize (symbol_byte_size);
+ ++sym_idx;
}
}
}
}
+ }
+ }
- // Trim our symbols down to just what we ended up with after
- // removing any symbols.
- if (sym_idx < num_syms)
- {
- num_syms = sym_idx;
- sym = symtab->Resize (num_syms);
- }
+ // Trim our symbols down to just what we ended up with after
+ // removing any symbols.
+ if (sym_idx < num_syms)
+ {
+ num_syms = sym_idx;
+ sym = symtab->Resize (num_syms);
+ }
- // Now synthesize indirect symbols
- if (m_dysymtab.nindirectsyms != 0)
- {
- DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
+ // Now synthesize indirect symbols
+ if (m_dysymtab.nindirectsyms != 0)
+ {
+ DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
- if (indirect_symbol_index_data.GetByteSize())
+ if (indirect_symbol_index_data.GetByteSize())
+ {
+ NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
+
+ for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
+ {
+ if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
{
- NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
+ uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
+ if (symbol_stub_byte_size == 0)
+ continue;
- for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
- {
- if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
- {
- uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
- if (symbol_stub_byte_size == 0)
- continue;
+ const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
- const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
+ if (num_symbol_stubs == 0)
+ continue;
- if (num_symbol_stubs == 0)
+ const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
+ for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
+ {
+ const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
+ const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
+ uint32_t symbol_stub_offset = symbol_stub_index * 4;
+ if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
+ {
+ const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
+ if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
continue;
- const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
- uint32_t synthetic_stub_sym_id = symtab_load_command.nsyms;
- for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
+ NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
+ Symbol *stub_symbol = NULL;
+ if (index_pos != end_index_pos)
{
- const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
- const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
- uint32_t symbol_stub_offset = symbol_stub_index * 4;
- if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
- {
- const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
- if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
- continue;
-
- NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
- Symbol *stub_symbol = NULL;
- if (index_pos != end_index_pos)
- {
- // We have a remapping from the original nlist index to
- // a current symbol index, so just look this up by index
- stub_symbol = symtab->SymbolAtIndex (index_pos->second);
- }
- else
- {
- // We need to lookup a symbol using the original nlist
- // symbol index since this index is coming from the
- // S_SYMBOL_STUBS
- stub_symbol = symtab->FindSymbolByID (stub_sym_id);
- }
+ // We have a remapping from the original nlist index to
+ // a current symbol index, so just look this up by index
+ stub_symbol = symtab->SymbolAtIndex (index_pos->second);
+ }
+ else
+ {
+ // We need to lookup a symbol using the original nlist
+ // symbol index since this index is coming from the
+ // S_SYMBOL_STUBS
+ stub_symbol = symtab->FindSymbolByID (stub_sym_id);
+ }
- assert (stub_symbol);
- if (stub_symbol)
- {
- Address so_addr(symbol_stub_addr, section_list);
+ assert (stub_symbol);
+ if (stub_symbol)
+ {
+ Address so_addr(symbol_stub_addr, section_list);
- if (stub_symbol->GetType() == eSymbolTypeUndefined)
- {
- // Change the external symbol into a trampoline that makes sense
- // These symbols were N_UNDF N_EXT, and are useless to us, so we
- // can re-use them so we don't have to make up a synthetic symbol
- // for no good reason.
- stub_symbol->SetType (eSymbolTypeTrampoline);
- stub_symbol->SetExternal (false);
- stub_symbol->GetAddress() = so_addr;
- stub_symbol->SetByteSize (symbol_stub_byte_size);
- }
- else
- {
- // Make a synthetic symbol to describe the trampoline stub
- if (sym_idx >= num_syms)
- sym = symtab->Resize (++num_syms);
- sym[sym_idx].SetID (synthetic_stub_sym_id++);
- sym[sym_idx].GetMangled() = stub_symbol->GetMangled();
- sym[sym_idx].SetType (eSymbolTypeTrampoline);
- sym[sym_idx].SetIsSynthetic (true);
- sym[sym_idx].GetAddress() = so_addr;
- sym[sym_idx].SetByteSize (symbol_stub_byte_size);
- ++sym_idx;
- }
- }
+ if (stub_symbol->GetType() == eSymbolTypeUndefined)
+ {
+ // Change the external symbol into a trampoline that makes sense
+ // These symbols were N_UNDF N_EXT, and are useless to us, so we
+ // can re-use them so we don't have to make up a synthetic symbol
+ // for no good reason.
+ stub_symbol->SetType (eSymbolTypeTrampoline);
+ stub_symbol->SetExternal (false);
+ stub_symbol->GetAddress() = so_addr;
+ stub_symbol->SetByteSize (symbol_stub_byte_size);
+ }
+ else
+ {
+ // Make a synthetic symbol to describe the trampoline stub
+ if (sym_idx >= num_syms)
+ sym = symtab->Resize (++num_syms);
+ sym[sym_idx].SetID (synthetic_sym_id++);
+ sym[sym_idx].GetMangled() = stub_symbol->GetMangled();
+ sym[sym_idx].SetType (eSymbolTypeTrampoline);
+ sym[sym_idx].SetIsSynthetic (true);
+ sym[sym_idx].GetAddress() = so_addr;
+ sym[sym_idx].SetByteSize (symbol_stub_byte_size);
+ ++sym_idx;
}
}
}
}
}
}
- return symtab->GetNumSymbols();
}
}
- offset = cmd_offset + symtab_load_command.cmdsize;
+ return symtab->GetNumSymbols();
}
return 0;
}
OpenPOWER on IntegriCloud