Correctly handle N_INDR nlist entries and don't rely on the trie information in order to reproduce them since this dyld trie info can be missing.
<rdar://problem/19749670> llvm-svn: 229201
This commit is contained in:
parent
845af6c46d
commit
60038bebf1
|
@ -131,7 +131,7 @@ public:
|
|||
FileSpec
|
||||
GetReExportedSymbolSharedLibrary () const;
|
||||
|
||||
bool
|
||||
void
|
||||
SetReExportedSymbolName(const ConstString &name);
|
||||
|
||||
bool
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue