summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Symbol/Symbol.h2
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp128
-rw-r--r--lldb/source/Symbol/Symbol.cpp17
3 files changed, 115 insertions, 32 deletions
diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h
index 0dd04b7112b..ed2ae3ed8e7 100644
--- a/lldb/include/lldb/Symbol/Symbol.h
+++ b/lldb/include/lldb/Symbol/Symbol.h
@@ -131,7 +131,7 @@ public:
FileSpec
GetReExportedSymbolSharedLibrary () const;
- bool
+ void
SetReExportedSymbolName(const ConstString &name);
bool
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index b4e42f4bc18..fd40a93c868 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -2751,6 +2751,11 @@ ObjectFileMachO::ParseSymtab ()
nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
uint32_t string_table_offset = local_symbols_info.stringsOffset;
+ typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
+ typedef std::map<uint32_t, ConstString> SymbolIndexToName;
+ UndefinedNameToDescMap undefined_name_to_desc;
+ SymbolIndexToName reexport_shlib_needs_fixup;
+
for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
{
/////////////////////////////
@@ -2791,6 +2796,7 @@ ObjectFileMachO::ParseSymtab ()
bool is_debug = ((nlist.n_type & N_STAB) != 0);
bool demangled_is_synthesized = false;
bool is_gsym = false;
+ bool set_value = true;
assert (sym_idx < num_syms);
@@ -3147,9 +3153,30 @@ ObjectFileMachO::ParseSymtab ()
switch (n_type)
{
- case N_INDR: // Fall through
- case N_PBUD: // Fall through
+ case N_INDR:
+ {
+ const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
+ if (reexport_name_cstr && reexport_name_cstr[0])
+ {
+ type = eSymbolTypeReExported;
+ ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
+ sym[sym_idx].SetReExportedSymbolName(reexport_name);
+ set_value = false;
+ reexport_shlib_needs_fixup[sym_idx] = reexport_name;
+ indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
+ }
+ else
+ type = eSymbolTypeUndefined;
+ }
+ break;
+
case N_UNDF:
+ {
+ ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
+ undefined_name_to_desc[undefined_name] = nlist.n_desc;
+ }
+ // Fall through
+ case N_PBUD:
type = eSymbolTypeUndefined;
break;
@@ -3467,8 +3494,11 @@ ObjectFileMachO::ParseSymtab ()
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);
+ if (set_value)
+ {
+ 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)
@@ -3489,6 +3519,17 @@ ObjectFileMachO::ParseSymtab ()
break; // No more entries to consider
}
}
+
+ for (const auto &pos :reexport_shlib_needs_fixup)
+ {
+ const auto undef_pos = undefined_name_to_desc.find(pos.second);
+ if (undef_pos != undefined_name_to_desc.end())
+ {
+ const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
+ if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
+ sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
+ }
+ }
}
}
}
@@ -3498,6 +3539,8 @@ ObjectFileMachO::ParseSymtab ()
// Must reset this in case it was mutated above!
nlist_data_offset = 0;
#endif
+ typedef std::set<ConstString> IndirectSymbols;
+ IndirectSymbols indirect_symbol_names;
if (nlist_data.GetByteSize() > 0)
{
@@ -3521,6 +3564,10 @@ ObjectFileMachO::ParseSymtab ()
nlist_idx = 0;
}
+ typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
+ typedef std::map<uint32_t, ConstString> SymbolIndexToName;
+ UndefinedNameToDescMap undefined_name_to_desc;
+ SymbolIndexToName reexport_shlib_needs_fixup;
for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
{
struct nlist_64 nlist;
@@ -3570,7 +3617,7 @@ ObjectFileMachO::ParseSymtab ()
bool is_gsym = false;
bool is_debug = ((nlist.n_type & N_STAB) != 0);
bool demangled_is_synthesized = false;
-
+ bool set_value = true;
assert (sym_idx < num_syms);
sym[sym_idx].SetDebug (is_debug);
@@ -3927,9 +3974,30 @@ ObjectFileMachO::ParseSymtab ()
switch (n_type)
{
- case N_INDR:// Fall through
- case N_PBUD:// Fall through
+ case N_INDR:
+ {
+ const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
+ if (reexport_name_cstr && reexport_name_cstr[0])
+ {
+ type = eSymbolTypeReExported;
+ ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
+ sym[sym_idx].SetReExportedSymbolName(reexport_name);
+ set_value = false;
+ reexport_shlib_needs_fixup[sym_idx] = reexport_name;
+ indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
+ }
+ else
+ type = eSymbolTypeUndefined;
+ }
+ break;
+
case N_UNDF:
+ {
+ ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
+ undefined_name_to_desc[undefined_name] = nlist.n_desc;
+ }
+ // Fall through
+ case N_PBUD:
type = eSymbolTypeUndefined;
break;
@@ -4249,8 +4317,11 @@ ObjectFileMachO::ParseSymtab ()
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);
+ if (set_value)
+ {
+ 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)
@@ -4266,6 +4337,18 @@ ObjectFileMachO::ParseSymtab ()
sym[sym_idx].Clear();
}
}
+
+ for (const auto &pos :reexport_shlib_needs_fixup)
+ {
+ const auto undef_pos = undefined_name_to_desc.find(pos.second);
+ if (undef_pos != undefined_name_to_desc.end())
+ {
+ const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
+ if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
+ sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
+ }
+ }
+
}
uint32_t synthetic_sym_id = symtab_load_command.nsyms;
@@ -4458,19 +4541,24 @@ ObjectFileMachO::ParseSymtab ()
{
if (e.entry.import_name)
{
- // Make a synthetic symbol to describe re-exported symbol.
- if (sym_idx >= num_syms)
- sym = symtab->Resize (++num_syms);
- sym[sym_idx].SetID (synthetic_sym_id++);
- sym[sym_idx].GetMangled() = Mangled(e.entry.name);
- sym[sym_idx].SetType (eSymbolTypeReExported);
- sym[sym_idx].SetIsSynthetic (true);
- sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
- if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
+ // Only add indirect symbols from the Trie entries if we
+ // didn't have a N_INDR nlist entry for this already
+ if (indirect_symbol_names.find(e.entry.name) == indirect_symbol_names.end())
{
- sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
+ // Make a synthetic symbol to describe re-exported symbol.
+ if (sym_idx >= num_syms)
+ sym = symtab->Resize (++num_syms);
+ sym[sym_idx].SetID (synthetic_sym_id++);
+ sym[sym_idx].GetMangled() = Mangled(e.entry.name);
+ sym[sym_idx].SetType (eSymbolTypeReExported);
+ sym[sym_idx].SetIsSynthetic (true);
+ sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
+ if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
+ {
+ sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
+ }
+ ++sym_idx;
}
- ++sym_idx;
}
}
}
diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp
index b6ed94610b0..39d78617bfb 100644
--- a/lldb/source/Symbol/Symbol.cpp
+++ b/lldb/source/Symbol/Symbol.cpp
@@ -209,18 +209,13 @@ Symbol::GetReExportedSymbolSharedLibrary() const
return FileSpec();
}
-bool
+void
Symbol::SetReExportedSymbolName(const ConstString &name)
{
- if (m_type == eSymbolTypeReExported)
- {
- // For eSymbolTypeReExported, the "const char *" from a ConstString
- // is used as the offset in the address range base address.
- m_addr_range.GetBaseAddress().SetOffset((intptr_t)name.GetCString());
- return true;
- }
- return false;
-
+ SetType (eSymbolTypeReExported);
+ // For eSymbolTypeReExported, the "const char *" from a ConstString
+ // is used as the offset in the address range base address.
+ m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString());
}
bool
@@ -230,7 +225,7 @@ Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
{
// For eSymbolTypeReExported, the "const char *" from a ConstString
// is used as the offset in the address range base address.
- m_addr_range.SetByteSize((intptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
+ m_addr_range.SetByteSize((uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
return true;
}
return false;
OpenPOWER on IntegriCloud