2114 llvm::StringRef file_name = file.
GetFilename().nonEmptyOr(
"<Unknown>");
2116 file_name.str().c_str());
2117 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2118 Progress progress(
"Parsing symbol table", file_name.str());
2133 llvm::DenseSet<addr_t> symbols_added;
2137 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2141 symbols_added.insert(file_addr);
2143 FunctionStarts function_starts;
2149 for (i = 0; i <
m_header.ncmds; ++i) {
2152 llvm::MachO::load_command lc;
2158 llvm::MachO::symtab_command lc_obj;
2159 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2160 lc_obj.cmd = lc.cmd;
2161 lc_obj.cmdsize = lc.cmdsize;
2162 symtab_load_command = lc_obj;
2167 case LC_DYLD_INFO_ONLY: {
2168 llvm::MachO::dyld_info_command lc_obj;
2169 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2170 lc_obj.cmd = lc.cmd;
2171 lc_obj.cmdsize = lc.cmdsize;
2177 case LC_LOAD_WEAK_DYLIB:
2178 case LC_REEXPORT_DYLIB:
2180 case LC_LOAD_UPWARD_DYLIB: {
2181 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2182 const char *path =
m_data_nsp->PeekCStr(name_offset);
2190 if (lc.cmd == LC_REEXPORT_DYLIB) {
2194 dylib_files.
Append(file_spec);
2198 case LC_DYLD_EXPORTS_TRIE: {
2199 llvm::MachO::linkedit_data_command lc_obj;
2200 lc_obj.cmd = lc.cmd;
2201 lc_obj.cmdsize = lc.cmdsize;
2202 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2203 exports_trie_load_command = lc_obj;
2205 case LC_FUNCTION_STARTS: {
2206 llvm::MachO::linkedit_data_command lc_obj;
2207 lc_obj.cmd = lc.cmd;
2208 lc_obj.cmdsize = lc.cmdsize;
2209 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2210 function_starts_load_command = lc_obj;
2214 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2217 image_uuid =
UUID(uuid_bytes, 16);
2224 offset = cmd_offset + lc.cmdsize;
2227 if (!symtab_load_command.
cmd)
2231 if (section_list ==
nullptr)
2234 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2236 bool bit_width_32 = addr_byte_size == 4;
2237 const size_t nlist_byte_size =
2238 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2240 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2241 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2242 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2243 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2245 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2247 const
addr_t nlist_data_byte_size =
2248 symtab_load_command.nsyms * nlist_byte_size;
2249 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2252 ProcessSP process_sp(m_process_wp.lock());
2253 Process *process = process_sp.get();
2257 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2260 section_list->FindSectionByName(GetSegmentNameTEXT()));
2262 section_list->FindSectionByName(GetSegmentNameDATA()));
2264 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2266 section_list->FindSectionByName(GetSegmentNameDATA_DIRTY()));
2268 section_list->FindSectionByName(GetSegmentNameDATA_CONST()));
2270 section_list->FindSectionByName(GetSegmentNameOBJC()));
2275 if (text_section_sp.get()) {
2276 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2277 g_section_name_eh_frame);
2278 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2279 g_section_name_lldb_no_nlist);
2281 eh_frame_section_sp =
2283 lldb_no_nlist_section_sp =
2287 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2288 !is_local_shared_cache_image) {
2289 Target &target = process->GetTarget();
2298 if (lldb_no_nlist_section_sp)
2303 if (linkedit_section_sp) {
2304 addr_t linkedit_load_addr =
2305 linkedit_section_sp->GetLoadBaseAddress(&target);
2315 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2316 const addr_t symoff_addr = linkedit_load_addr +
2317 symtab_load_command.
symoff -
2318 linkedit_file_offset;
2319 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2320 linkedit_file_offset;
2328 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2330 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2332 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2334 const addr_t indirect_syms_addr = linkedit_load_addr +
2336 linkedit_file_offset;
2338 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2339 if (indirect_syms_data_sp)
2340 indirect_symbol_index_data.SetData(
2341 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2351 if (!is_shared_cache_image) {
2353 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2354 if (strtab_data_sp) {
2355 strtab_data.SetData(strtab_data_sp, 0,
2356 strtab_data_sp->GetByteSize());
2361 if (function_starts_load_command.
cmd) {
2362 const addr_t func_start_addr =
2363 linkedit_load_addr + function_starts_load_command.
dataoff -
2364 linkedit_file_offset;
2367 function_starts_load_command.
datasize));
2368 if (func_start_data_sp)
2369 function_starts_data.SetData(func_start_data_sp, 0,
2370 func_start_data_sp->GetByteSize());
2376 if (is_local_shared_cache_image && linkedit_section_sp) {
2384 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2387 symtab_load_command.
symoff += linkedit_slide;
2388 symtab_load_command.
stroff += linkedit_slide;
2391 function_starts_load_command.
dataoff += linkedit_slide;
2392 exports_trie_load_command.
dataoff += linkedit_slide;
2396 nlist_data_byte_size);
2397 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2398 strtab_data_byte_size);
2403 && (exports_trie_load_command.
datasize > 0)));
2407 }
else if (exports_trie_load_command.
datasize > 0) {
2410 exports_trie_load_command.
datasize);
2414 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2417 if (function_starts_load_command.
cmd) {
2418 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2419 function_starts_load_command.
dataoff,
2420 function_starts_load_command.
datasize);
2424 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2426 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2443 if (text_section_sp && function_starts_data.GetByteSize()) {
2444 FunctionStarts::Entry function_start_entry;
2445 function_start_entry.data =
false;
2447 function_start_entry.addr = text_section_sp->GetFileAddress();
2449 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2452 function_start_entry.addr += delta;
2454 if (function_start_entry.addr & 1) {
2456 function_start_entry.data =
true;
2457 }
else if (always_thumb) {
2458 function_start_entry.data =
true;
2461 function_starts.Append(function_start_entry);
2469 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2475 addr_t text_base_addr = text_section_sp->GetFileAddress();
2476 size_t count = functions.
GetSize();
2477 for (
size_t i = 0; i < count; ++i) {
2481 FunctionStarts::Entry function_start_entry;
2482 function_start_entry.addr = func->
base - text_base_addr;
2484 if (function_start_entry.addr & 1) {
2486 function_start_entry.data =
true;
2487 }
else if (always_thumb) {
2488 function_start_entry.data =
true;
2491 function_starts.Append(function_start_entry);
2497 const size_t function_starts_count = function_starts.GetSize();
2512 if (unwind_or_symbol_log)
2513 module_sp->LogMessage(
2514 unwind_or_symbol_log,
2515 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2518 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2519 ? eh_frame_section_sp->GetID()
2525 std::vector<uint32_t> N_FUN_indexes;
2526 std::vector<uint32_t> N_NSYM_indexes;
2527 std::vector<uint32_t> N_INCL_indexes;
2528 std::vector<uint32_t> N_BRAC_indexes;
2529 std::vector<uint32_t> N_COMM_indexes;
2530 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2531 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2532 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2533 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2534 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2535 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2538 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2539 uint32_t nlist_idx = 0;
2540 Symbol *symbol_ptr =
nullptr;
2542 uint32_t sym_idx = 0;
2544 size_t num_syms = 0;
2545 std::string memory_symbol_name;
2546 uint32_t unmapped_local_symbols_found = 0;
2548 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2549 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2550 std::set<lldb::addr_t> resolver_addresses;
2552 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2553 if (dyld_trie_data_size > 0) {
2554 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2558 if (text_segment_sp)
2559 text_segment_file_addr = text_segment_sp->GetFileAddress();
2561 resolver_addresses, reexport_trie_entries,
2562 external_sym_trie_entries);
2565 typedef std::set<ConstString> IndirectSymbols;
2566 IndirectSymbols indirect_symbol_names;
2589 UUID process_shared_cache_uuid;
2590 addr_t process_shared_cache_base_addr;
2594 process_shared_cache_uuid);
2597 __block
bool found_image =
false;
2598 __block
void *nlist_buffer =
nullptr;
2599 __block
unsigned nlist_count = 0;
2600 __block
char *string_table =
nullptr;
2601 __block vm_offset_t vm_nlist_memory = 0;
2602 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2603 __block vm_offset_t vm_string_memory = 0;
2604 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2606 llvm::scope_exit _(^{
2607 if (vm_nlist_memory)
2608 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2609 if (vm_string_memory)
2610 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2613 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2614 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2615 UndefinedNameToDescMap undefined_name_to_desc;
2616 SymbolIndexToName reexport_shlib_needs_fixup;
2624 if (process_shared_cache_uuid.
IsValid() &&
2625 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2634 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2641 dyld_image_local_nlist_content_4Symbolication(
2642 image, ^(
const void *nlistStart, uint64_t nlistCount,
2643 const char *stringTable) {
2644 if (!nlistStart || !nlistCount)
2652 nlist_byte_size * nlistCount, &vm_nlist_memory,
2653 &vm_nlist_bytes_read);
2656 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2661 vm_address_t string_address = (vm_address_t)stringTable;
2662 vm_size_t region_size;
2663 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2664 vm_region_basic_info_data_t info;
2665 memory_object_name_t object;
2667 ®ion_size, VM_REGION_BASIC_INFO_64,
2668 (vm_region_info_t)&info, &info_count, &
object);
2674 ((vm_address_t)stringTable - string_address),
2675 &vm_string_memory, &vm_string_bytes_read);
2679 nlist_buffer = (
void *)vm_nlist_memory;
2680 string_table = (
char *)vm_string_memory;
2681 nlist_count = nlistCount;
2687 nlist_count * nlist_byte_size,
2688 byte_order, addr_byte_size);
2689 unmapped_local_symbols_found = nlist_count;
2695 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2700 for (uint32_t nlist_index = 0;
2701 nlist_index < nlist_count;
2705 std::optional<struct nlist_64> nlist_maybe =
2706 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2710 struct nlist_64 nlist = *nlist_maybe;
2713 const char *symbol_name = string_table + nlist.n_strx;
2715 if (symbol_name == NULL) {
2720 "DSC unmapped local symbol[{0}] has invalid "
2721 "string table offset {1:x} in {2}, ignoring symbol",
2722 nlist_index, nlist.n_strx,
2723 module_sp->GetFileSpec().GetPath()));
2726 if (symbol_name[0] ==
'\0')
2729 const char *symbol_name_non_abi_mangled = NULL;
2732 bool add_nlist =
true;
2733 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2734 bool demangled_is_synthesized =
false;
2735 bool is_gsym =
false;
2736 bool set_value =
true;
2738 assert(sym_idx < num_syms);
2743 switch (nlist.n_type) {
2763 symbol_name, symbol_name_non_abi_mangled,
2765 demangled_is_synthesized =
true;
2767 if (nlist.n_value != 0)
2769 nlist.n_sect, nlist.n_value);
2785 nlist.n_sect, nlist.n_value);
2787 N_FUN_addr_to_sym_idx.insert(
2788 std::make_pair(nlist.n_value, sym_idx));
2792 N_FUN_indexes.push_back(sym_idx);
2796 if (!N_FUN_indexes.empty()) {
2803 N_FUN_indexes.pop_back();
2815 N_STSYM_addr_to_sym_idx.insert(
2816 std::make_pair(nlist.n_value, sym_idx));
2817 symbol_section = section_info.
GetSection(nlist.n_sect,
2819 if (symbol_name && symbol_name[0]) {
2827 symbol_section = section_info.
GetSection(nlist.n_sect,
2861 symbol_section = section_info.
GetSection(nlist.n_sect,
2874 if (symbol_name == NULL) {
2885 N_NSYM_indexes.clear();
2886 N_INCL_indexes.clear();
2887 N_BRAC_indexes.clear();
2888 N_COMM_indexes.clear();
2889 N_FUN_indexes.clear();
2895 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2896 if (N_SO_has_full_path) {
2897 if ((N_SO_index == sym_idx - 1) &&
2898 ((sym_idx - 1) < num_syms)) {
2904 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2910 N_SO_index = sym_idx;
2912 }
else if ((N_SO_index == sym_idx - 1) &&
2913 ((sym_idx - 1) < num_syms)) {
2918 const char *so_path = sym[sym_idx - 1]
2922 if (so_path && so_path[0]) {
2923 std::string full_so_path(so_path);
2924 const size_t double_slash_pos =
2925 full_so_path.find(
"//");
2926 if (double_slash_pos != std::string::npos) {
2937 &full_so_path[double_slash_pos + 1],
2938 FileSpec::Style::native);
2941 full_so_path.erase(0, double_slash_pos + 1);
2945 if (*full_so_path.rbegin() !=
'/')
2946 full_so_path +=
'/';
2947 full_so_path += symbol_name;
2951 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2955 N_SO_index = sym_idx;
2976 N_INCL_indexes.push_back(sym_idx);
2986 if (!N_INCL_indexes.empty()) {
2991 N_INCL_indexes.pop_back();
3026 symbol_section = section_info.
GetSection(nlist.n_sect,
3037 symbol_section = section_info.
GetSection(nlist.n_sect,
3039 N_BRAC_indexes.push_back(sym_idx);
3049 symbol_section = section_info.
GetSection(nlist.n_sect,
3051 if (!N_BRAC_indexes.empty()) {
3056 N_BRAC_indexes.pop_back();
3073 N_COMM_indexes.push_back(sym_idx);
3078 symbol_section = section_info.
GetSection(nlist.n_sect,
3089 if (!N_COMM_indexes.empty()) {
3094 N_COMM_indexes.pop_back();
3109 uint8_t n_type = N_TYPE & nlist.n_type;
3110 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3114 const char *reexport_name_cstr =
3115 strtab_data.PeekCStr(nlist.n_value);
3116 if (reexport_name_cstr && reexport_name_cstr[0]) {
3119 reexport_name_cstr +
3120 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3123 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3125 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3131 if (symbol_name && symbol_name[0]) {
3133 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3134 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3146 symbol_section = section_info.
GetSection(nlist.n_sect,
3149 if (symbol_section == NULL) {
3155 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3158 uint32_t section_type =
3159 symbol_section->Get() & SECTION_TYPE;
3161 switch (section_type) {
3162 case S_CSTRING_LITERALS:
3165 case S_4BYTE_LITERALS:
3168 case S_8BYTE_LITERALS:
3171 case S_LITERAL_POINTERS:
3174 case S_NON_LAZY_SYMBOL_POINTERS:
3178 case S_LAZY_SYMBOL_POINTERS:
3181 case S_SYMBOL_STUBS:
3185 case S_MOD_INIT_FUNC_POINTERS:
3189 case S_MOD_TERM_FUNC_POINTERS:
3197 case S_16BYTE_LITERALS:
3203 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3207 switch (symbol_section->GetType()) {
3234 llvm::StringRef symbol_sect_name =
3235 symbol_section->GetName();
3236 if (symbol_section->IsDescendant(
3237 text_section_sp.get())) {
3238 if (symbol_section->IsClear(
3239 S_ATTR_PURE_INSTRUCTIONS |
3240 S_ATTR_SELF_MODIFYING_CODE |
3241 S_ATTR_SOME_INSTRUCTIONS))
3245 }
else if (symbol_section->IsDescendant(
3246 data_section_sp.get()) ||
3247 symbol_section->IsDescendant(
3248 data_dirty_section_sp.get()) ||
3249 symbol_section->IsDescendant(
3250 data_const_section_sp.get())) {
3251 if (symbol_sect_name.starts_with(
"__objc")) {
3256 symbol_name_non_abi_mangled, type))
3257 demangled_is_synthesized =
true;
3258 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
3263 }
else if (symbol_sect_name.starts_with(
"__IMPORT"))
3265 }
else if (symbol_section->IsDescendant(
3266 objc_section_sp.get())) {
3268 if (symbol_name && symbol_name[0] ==
'.') {
3269 llvm::StringRef symbol_name_ref(symbol_name);
3271 g_objc_v1_prefix_class(
".objc_class_name_");
3272 if (symbol_name_ref.starts_with(
3273 g_objc_v1_prefix_class)) {
3274 symbol_name_non_abi_mangled = symbol_name;
3275 symbol_name = symbol_name +
3276 g_objc_v1_prefix_class.size();
3278 demangled_is_synthesized =
true;
3289 uint64_t symbol_value = nlist.n_value;
3290 if (symbol_name_non_abi_mangled) {
3296 if (symbol_name && symbol_name[0] ==
'_') {
3303 if (is_gsym && is_debug) {
3304 const char *gsym_name =
3310 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3314 if (symbol_section) {
3315 const addr_t section_file_addr =
3316 symbol_section->GetFileAddress();
3317 symbol_value -= section_file_addr;
3320 if (is_debug ==
false) {
3328 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3329 if (range.first != range.second) {
3330 bool found_it =
false;
3331 for (
auto pos = range.first; pos != range.second;
3333 if (sym[sym_idx].GetMangled().
GetName(
3337 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3343 sym[sym_idx].IsExternal());
3344 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3346 if (resolver_addresses.find(nlist.n_value) !=
3347 resolver_addresses.end())
3349 sym[sym_idx].
Clear();
3357 if (resolver_addresses.find(nlist.n_value) !=
3358 resolver_addresses.end())
3370 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3372 if (range.first != range.second) {
3373 bool found_it =
false;
3374 for (
auto pos = range.first; pos != range.second;
3376 if (sym[sym_idx].GetMangled().
GetName(
3380 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3386 sym[sym_idx].IsExternal());
3387 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3389 sym[sym_idx].
Clear();
3397 const char *gsym_name =
3405 ConstNameToSymbolIndexMap::const_iterator pos =
3406 N_GSYM_name_to_sym_idx.find(gsym_name);
3407 if (pos != N_GSYM_name_to_sym_idx.end()) {
3408 const uint32_t GSYM_sym_idx = pos->second;
3409 m_nlist_idx_to_sym_idx[nlist_idx] =
3415 Address(symbol_section, symbol_value);
3416 add_symbol_addr(sym[GSYM_sym_idx]
3423 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3425 sym[sym_idx].
Clear();
3433 sym[sym_idx].
SetID(nlist_idx);
3437 Address(symbol_section, symbol_value);
3439 sym[sym_idx].GetAddress().GetFileAddress());
3441 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3443 if (demangled_is_synthesized)
3447 sym[sym_idx].
Clear();
3454 for (
const auto &pos : reexport_shlib_needs_fixup) {
3455 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3456 if (undef_pos != undefined_name_to_desc.end()) {
3457 const uint8_t dylib_ordinal =
3458 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3459 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3469 if (nlist_data.GetByteSize() > 0) {
3473 if (sym ==
nullptr) {
3475 symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3476 num_syms = symtab.GetNumSymbols();
3479 if (unmapped_local_symbols_found) {
3480 assert(m_dysymtab.ilocalsym == 0);
3481 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3482 nlist_idx = m_dysymtab.nlocalsym;
3487 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3488 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3489 UndefinedNameToDescMap undefined_name_to_desc;
3490 SymbolIndexToName reexport_shlib_needs_fixup;
3498 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3500 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3501 if (is_debug != debug_only)
3504 const char *symbol_name_non_abi_mangled =
nullptr;
3505 const char *symbol_name =
nullptr;
3507 if (have_strtab_data) {
3508 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3510 if (symbol_name ==
nullptr) {
3514 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3516 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3519 if (symbol_name[0] ==
'\0')
3520 symbol_name =
nullptr;
3522 const addr_t str_addr = strtab_addr + nlist.n_strx;
3524 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3526 symbol_name = memory_symbol_name.c_str();
3531 bool add_nlist =
true;
3532 bool is_gsym =
false;
3533 bool demangled_is_synthesized =
false;
3534 bool set_value =
true;
3536 assert(sym_idx < num_syms);
3537 sym[sym_idx].SetDebug(is_debug);
3540 switch (nlist.n_type) {
3555 sym[sym_idx].SetExternal(
true);
3558 symbol_name_non_abi_mangled, type)) {
3559 demangled_is_synthesized =
true;
3561 if (nlist.n_value != 0)
3563 section_info.GetSection(nlist.n_sect, nlist.n_value);
3579 section_info.GetSection(nlist.n_sect, nlist.n_value);
3581 N_FUN_addr_to_sym_idx.insert(
3582 std::make_pair(nlist.n_value, sym_idx));
3586 N_FUN_indexes.push_back(sym_idx);
3590 if (!N_FUN_indexes.empty()) {
3593 symtab.SymbolAtIndex(N_FUN_indexes.back())
3594 ->SetByteSize(nlist.n_value);
3595 N_FUN_indexes.pop_back();
3606 N_STSYM_addr_to_sym_idx.insert(
3607 std::make_pair(nlist.n_value, sym_idx));
3608 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3609 if (symbol_name && symbol_name[0]) {
3617 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3648 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3660 if (symbol_name ==
nullptr) {
3667 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3668 symbol_ptr->SetByteSize(sym_idx);
3669 symbol_ptr->SetSizeIsSibling(
true);
3671 N_NSYM_indexes.clear();
3672 N_INCL_indexes.clear();
3673 N_BRAC_indexes.clear();
3674 N_COMM_indexes.clear();
3675 N_FUN_indexes.clear();
3681 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3682 if (N_SO_has_full_path) {
3683 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3686 sym[sym_idx - 1].GetMangled().SetValue(
3688 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3693 N_SO_index = sym_idx;
3695 }
else if ((N_SO_index == sym_idx - 1) &&
3696 ((sym_idx - 1) < num_syms)) {
3700 llvm::StringRef so_path = sym[sym_idx - 1]
3704 if (!so_path.empty()) {
3705 std::string full_so_path(so_path);
3706 const size_t double_slash_pos = full_so_path.find(
"//");
3707 if (double_slash_pos != std::string::npos) {
3715 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3716 FileSpec::Style::native);
3719 full_so_path.erase(0, double_slash_pos + 1);
3723 if (*full_so_path.rbegin() !=
'/')
3724 full_so_path +=
'/';
3725 full_so_path += symbol_name;
3726 sym[sym_idx - 1].GetMangled().SetValue(
3729 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3733 N_SO_index = sym_idx;
3753 N_INCL_indexes.push_back(sym_idx);
3762 if (!N_INCL_indexes.empty()) {
3763 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3764 symbol_ptr->SetByteSize(sym_idx + 1);
3765 symbol_ptr->SetSizeIsSibling(
true);
3766 N_INCL_indexes.pop_back();
3801 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3810 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3811 N_BRAC_indexes.push_back(sym_idx);
3820 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3821 if (!N_BRAC_indexes.empty()) {
3822 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3823 symbol_ptr->SetByteSize(sym_idx + 1);
3824 symbol_ptr->SetSizeIsSibling(
true);
3825 N_BRAC_indexes.pop_back();
3841 N_COMM_indexes.push_back(sym_idx);
3846 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3855 if (!N_COMM_indexes.empty()) {
3856 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3857 symbol_ptr->SetByteSize(sym_idx + 1);
3858 symbol_ptr->SetSizeIsSibling(
true);
3859 N_COMM_indexes.pop_back();
3873 uint8_t n_type = N_TYPE & nlist.n_type;
3874 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3878 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3879 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3882 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3883 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3885 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3886 indirect_symbol_names.insert(
3887 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3893 if (symbol_name && symbol_name[0]) {
3895 ((symbol_name[0] ==
'_') ? 1 : 0));
3896 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3909 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3911 if (!symbol_section) {
3917 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3920 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3922 switch (section_type) {
3923 case S_CSTRING_LITERALS:
3926 case S_4BYTE_LITERALS:
3929 case S_8BYTE_LITERALS:
3932 case S_LITERAL_POINTERS:
3935 case S_NON_LAZY_SYMBOL_POINTERS:
3938 case S_LAZY_SYMBOL_POINTERS:
3941 case S_SYMBOL_STUBS:
3945 case S_MOD_INIT_FUNC_POINTERS:
3948 case S_MOD_TERM_FUNC_POINTERS:
3955 case S_16BYTE_LITERALS:
3961 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3965 switch (symbol_section->GetType()) {
3987 llvm::StringRef symbol_sect_name = symbol_section->GetName();
3988 if (symbol_section->IsDescendant(text_section_sp.get())) {
3989 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3990 S_ATTR_SELF_MODIFYING_CODE |
3991 S_ATTR_SOME_INSTRUCTIONS))
3995 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3996 symbol_section->IsDescendant(
3997 data_dirty_section_sp.get()) ||
3998 symbol_section->IsDescendant(
3999 data_const_section_sp.get())) {
4000 if (symbol_sect_name.starts_with(
"__objc")) {
4004 symbol_name, symbol_name_non_abi_mangled, type))
4005 demangled_is_synthesized =
true;
4006 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
4011 }
else if (symbol_sect_name.starts_with(
"__IMPORT")) {
4013 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4015 if (symbol_name && symbol_name[0] ==
'.') {
4016 llvm::StringRef symbol_name_ref(symbol_name);
4017 llvm::StringRef g_objc_v1_prefix_class(
4018 ".objc_class_name_");
4019 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4020 symbol_name_non_abi_mangled = symbol_name;
4021 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4023 demangled_is_synthesized =
true;
4034 sym[sym_idx].Clear();
4038 uint64_t symbol_value = nlist.n_value;
4040 if (symbol_name_non_abi_mangled) {
4041 sym[sym_idx].GetMangled().SetMangledName(
4043 sym[sym_idx].GetMangled().SetDemangledName(
ConstString(symbol_name));
4046 if (symbol_name && symbol_name[0] ==
'_') {
4052 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4057 const char *gsym_name = sym[sym_idx]
4062 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4065 if (symbol_section) {
4066 const addr_t section_file_addr = symbol_section->GetFileAddress();
4067 symbol_value -= section_file_addr;
4076 std::pair<ValueToSymbolIndexMap::const_iterator,
4077 ValueToSymbolIndexMap::const_iterator>
4079 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4080 if (range.first != range.second) {
4081 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4082 pos != range.second; ++pos) {
4084 sym[pos->second].GetMangled().GetName(
4086 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4090 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4091 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4092 if (resolver_addresses.find(nlist.n_value) !=
4093 resolver_addresses.end())
4095 sym[sym_idx].Clear();
4100 if (resolver_addresses.find(nlist.n_value) !=
4101 resolver_addresses.end())
4111 std::pair<ValueToSymbolIndexMap::const_iterator,
4112 ValueToSymbolIndexMap::const_iterator>
4114 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4115 if (range.first != range.second) {
4116 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4117 pos != range.second; ++pos) {
4119 sym[pos->second].GetMangled().GetName(
4121 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4125 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4126 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4127 sym[sym_idx].Clear();
4133 const char *gsym_name = sym[sym_idx]
4138 ConstNameToSymbolIndexMap::const_iterator pos =
4139 N_GSYM_name_to_sym_idx.find(gsym_name);
4140 if (pos != N_GSYM_name_to_sym_idx.end()) {
4141 const uint32_t GSYM_sym_idx = pos->second;
4142 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4145 sym[GSYM_sym_idx].GetAddressRef() =
4146 Address(symbol_section, symbol_value);
4148 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4152 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4153 sym[sym_idx].Clear();
4161 sym[sym_idx].SetID(nlist_idx);
4162 sym[sym_idx].SetType(type);
4164 sym[sym_idx].GetAddressRef() =
Address(symbol_section, symbol_value);
4166 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4168 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4169 if (nlist.n_desc & N_WEAK_REF)
4170 sym[sym_idx].SetIsWeak(
true);
4172 if (demangled_is_synthesized)
4173 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4181 std::vector<struct nlist_64> nlists;
4182 nlists.reserve(symtab_load_command.nsyms);
4183 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4185 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4186 nlists.push_back(*nlist);
4196 for (
auto &nlist : nlists) {
4197 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4203 for (
auto &nlist : nlists) {
4208 for (
const auto &pos : reexport_shlib_needs_fixup) {
4209 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4210 if (undef_pos != undefined_name_to_desc.end()) {
4211 const uint8_t dylib_ordinal =
4212 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4213 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4214 sym[pos.first].SetReExportedSymbolSharedLibrary(
4215 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4221 int trie_symbol_table_augment_count = 0;
4222 for (
auto &e : external_sym_trie_entries) {
4223 if (!symbols_added.contains(e.entry.address))
4224 trie_symbol_table_augment_count++;
4227 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4228 num_syms = sym_idx + trie_symbol_table_augment_count;
4229 sym = symtab.Resize(num_syms);
4231 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4234 for (
auto &e : external_sym_trie_entries) {
4235 if (symbols_added.contains(e.entry.address))
4241 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4243 const char *symbol_name = e.entry.name.GetCString();
4244 bool demangled_is_synthesized =
false;
4246 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4247 data_section_sp, data_dirty_section_sp,
4248 data_const_section_sp, symbol_section);
4250 sym[sym_idx].SetType(type);
4251 if (symbol_section) {
4252 sym[sym_idx].SetID(synthetic_sym_id++);
4253 sym[sym_idx].GetMangled().SetMangledName(
ConstString(symbol_name));
4254 if (demangled_is_synthesized)
4255 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4256 sym[sym_idx].SetIsSynthetic(
true);
4257 sym[sym_idx].SetExternal(
true);
4258 sym[sym_idx].GetAddressRef() = symbol_addr;
4267 if (function_starts_count > 0) {
4268 uint32_t num_synthetic_function_symbols = 0;
4269 for (i = 0; i < function_starts_count; ++i) {
4270 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4271 ++num_synthetic_function_symbols;
4274 if (num_synthetic_function_symbols > 0) {
4275 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4276 num_syms = sym_idx + num_synthetic_function_symbols;
4277 sym = symtab.Resize(num_syms);
4279 for (i = 0; i < function_starts_count; ++i) {
4280 const FunctionStarts::Entry *func_start_entry =
4281 function_starts.GetEntryAtIndex(i);
4282 if (!symbols_added.contains(func_start_entry->addr)) {
4283 addr_t symbol_file_addr = func_start_entry->addr;
4284 uint32_t symbol_flags = 0;
4285 if (func_start_entry->data)
4288 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4290 if (symbol_section) {
4291 sym[sym_idx].SetID(synthetic_sym_id++);
4295 sym[sym_idx].GetMangled().SetDemangledName(
ConstString());
4297 sym[sym_idx].SetIsSynthetic(
true);
4298 sym[sym_idx].GetAddressRef() = symbol_addr;
4301 sym[sym_idx].SetFlags(symbol_flags);
4312 if (sym_idx < num_syms) {
4314 sym = symtab.Resize(num_syms);
4318 if (m_dysymtab.nindirectsyms != 0) {
4319 if (indirect_symbol_index_data.GetByteSize()) {
4320 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4321 m_nlist_idx_to_sym_idx.end();
4323 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4325 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4327 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4328 if (symbol_stub_byte_size == 0)
4331 const uint32_t num_symbol_stubs =
4332 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4334 if (num_symbol_stubs == 0)
4337 const uint32_t symbol_stub_index_offset =
4338 m_mach_sections[sect_idx].reserved1;
4339 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4340 const uint32_t symbol_stub_index =
4341 symbol_stub_index_offset + stub_idx;
4343 m_mach_sections[sect_idx].addr +
4344 (stub_idx * symbol_stub_byte_size);
4346 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4347 symbol_stub_offset, 4)) {
4348 const uint32_t stub_sym_id =
4349 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4350 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4353 NListIndexToSymbolIndexMap::const_iterator index_pos =
4354 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4355 Symbol *stub_symbol =
nullptr;
4356 if (index_pos != end_index_pos) {
4359 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4363 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4367 Address so_addr(symbol_stub_addr, section_list);
4374 if (resolver_addresses.find(symbol_stub_addr) ==
4375 resolver_addresses.end())
4385 if (sym_idx >= num_syms) {
4386 sym = symtab.Resize(++num_syms);
4387 stub_symbol =
nullptr;
4389 sym[sym_idx].SetID(synthetic_sym_id++);
4390 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4391 if (resolver_addresses.find(symbol_stub_addr) ==
4392 resolver_addresses.end())
4396 sym[sym_idx].SetIsSynthetic(
true);
4397 sym[sym_idx].GetAddressRef() = so_addr;
4398 add_symbol_addr(so_addr.GetFileAddress());
4399 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4404 "warning: symbol stub referencing symbol table "
4405 "symbol %u that isn't in our minimal symbol table, "
4416 if (!reexport_trie_entries.empty()) {
4417 for (
const auto &e : reexport_trie_entries) {
4418 if (e.entry.import_name) {
4421 if (indirect_symbol_names.find(e.entry.name) ==
4422 indirect_symbol_names.end()) {
4424 if (sym_idx >= num_syms)
4425 sym = symtab.Resize(++num_syms);
4426 sym[sym_idx].SetID(synthetic_sym_id++);
4427 sym[sym_idx].GetMangled() =
Mangled(e.entry.name);
4429 sym[sym_idx].SetIsSynthetic(
true);
4430 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4431 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4432 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4433 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));