diff options
author | Greg Clayton <gclayton@apple.com> | 2013-05-14 22:19:37 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-05-14 22:19:37 +0000 |
commit | dacc4a953df3c241f71ed7d163a427d75dce3b0c (patch) | |
tree | 4b0315a0172ed4ebd78f4991546ce0a4da1527e7 /lldb | |
parent | bc8d23956c7eeac75703490b4ce30f8d2ad16bfe (diff) | |
download | bcm5719-llvm-dacc4a953df3c241f71ed7d163a427d75dce3b0c.tar.gz bcm5719-llvm-dacc4a953df3c241f71ed7d163a427d75dce3b0c.zip |
<rdar://problem/13748253>
Combine N_GSYM stab entries with their non-stab counterpart (data symbols) to make the symbol table smaller with less duplicate named symbols.
llvm-svn: 181841
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 232 |
1 files changed, 141 insertions, 91 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index dc30be6877a..cfa54387b37 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1712,8 +1712,10 @@ ObjectFileMachO::ParseSymtab (bool minimize) std::vector<uint32_t> N_COMM_indexes; typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap; typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap; + typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap; ValueToSymbolIndexMap N_FUN_addr_to_sym_idx; ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx; + ConstNameToSymbolIndexMap N_GSYM_name_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; @@ -1970,6 +1972,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) bool add_nlist = true; bool is_debug = ((nlist.n_type & NlistMaskStab) != 0); bool demangled_is_synthesized = false; + bool is_gsym = false; assert (sym_idx < num_syms); @@ -1997,6 +2000,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) 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); @@ -2510,53 +2514,10 @@ ObjectFileMachO::ParseSymtab (bool minimize) if (symbol_name) { - sym[sym_idx].GetMangled().SetValue(ConstString(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_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; - } - } - } - 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())) - { - 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; - } - } + ConstString const_symbol_name(symbol_name); + if (is_gsym) + N_GSYM_name_to_sym_idx[const_symbol_name.GetCString()] = sym_idx; + sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled); } } if (symbol_section) @@ -2612,6 +2573,71 @@ ObjectFileMachO::ParseSymtab (bool minimize) symbol_value -= section_file_addr; } + 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_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; + } + } + } + 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())) + { + 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().GetMangledName().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); @@ -2711,6 +2737,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) 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; @@ -2740,6 +2767,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) 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); @@ -3258,8 +3286,58 @@ ObjectFileMachO::ParseSymtab (bool minimize) if (symbol_name) { - sym[sym_idx].GetMangled().SetValue(ConstString(symbol_name), symbol_name_is_mangled); + ConstString const_symbol_name(symbol_name); + if (is_gsym) + N_GSYM_name_to_sym_idx[const_symbol_name.GetCString()] = sym_idx; + sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled); + } + } + 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) + { + // 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; + } + } + if (func_start_entry) + { + 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; } if (is_debug == false) @@ -3305,54 +3383,26 @@ ObjectFileMachO::ParseSymtab (bool minimize) continue; } } - } - } - 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) + else { - // 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)) + // 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().GetMangledName().GetCString()); + if (pos != N_GSYM_name_to_sym_idx.end()) { - // Not the right entry, NULL it out... - func_start_entry = NULL; - } - } - if (func_start_entry) - { - 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; + 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; } } } - symbol_value -= section_file_addr; } sym[sym_idx].SetID (nlist_idx); |