2075 llvm::StringRef file_name = file.
GetFilename().nonEmptyOr(
"<Unknown>");
2077 file_name.str().c_str());
2078 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2079 Progress progress(
"Parsing symbol table", file_name.str());
2094 llvm::DenseSet<addr_t> symbols_added;
2098 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2102 symbols_added.insert(file_addr);
2104 FunctionStarts function_starts;
2110 for (i = 0; i <
m_header.ncmds; ++i) {
2113 llvm::MachO::load_command lc;
2114 if (
m_data_nsp->GetU32(&offset, &lc, 2) ==
nullptr)
2119 llvm::MachO::symtab_command lc_obj;
2120 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2121 lc_obj.cmd = lc.cmd;
2122 lc_obj.cmdsize = lc.cmdsize;
2123 symtab_load_command = lc_obj;
2128 case LC_DYLD_INFO_ONLY: {
2129 llvm::MachO::dyld_info_command lc_obj;
2130 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2131 lc_obj.cmd = lc.cmd;
2132 lc_obj.cmdsize = lc.cmdsize;
2138 case LC_LOAD_WEAK_DYLIB:
2139 case LC_REEXPORT_DYLIB:
2141 case LC_LOAD_UPWARD_DYLIB: {
2142 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2143 const char *path =
m_data_nsp->PeekCStr(name_offset);
2151 if (lc.cmd == LC_REEXPORT_DYLIB) {
2155 dylib_files.
Append(file_spec);
2159 case LC_DYLD_EXPORTS_TRIE: {
2160 llvm::MachO::linkedit_data_command lc_obj;
2161 lc_obj.cmd = lc.cmd;
2162 lc_obj.cmdsize = lc.cmdsize;
2163 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2164 exports_trie_load_command = lc_obj;
2166 case LC_FUNCTION_STARTS: {
2167 llvm::MachO::linkedit_data_command lc_obj;
2168 lc_obj.cmd = lc.cmd;
2169 lc_obj.cmdsize = lc.cmdsize;
2170 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2171 function_starts_load_command = lc_obj;
2175 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2178 image_uuid =
UUID(uuid_bytes, 16);
2185 offset = cmd_offset + lc.cmdsize;
2188 if (!symtab_load_command.
cmd)
2192 if (section_list ==
nullptr)
2195 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2197 bool bit_width_32 = addr_byte_size == 4;
2198 const size_t nlist_byte_size =
2199 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2201 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2202 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2203 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2204 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2206 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2208 const
addr_t nlist_data_byte_size =
2209 symtab_load_command.nsyms * nlist_byte_size;
2210 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2213 ProcessSP process_sp(m_process_wp.lock());
2214 Process *process = process_sp.get();
2218 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2228 section_list->FindSectionByName(g_segment_name_TEXT));
2230 section_list->FindSectionByName(g_segment_name_DATA));
2232 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2234 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2236 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2238 section_list->FindSectionByName(g_segment_name_OBJC));
2241 if (text_section_sp.get()) {
2242 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2243 g_section_name_eh_frame);
2244 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2245 g_section_name_lldb_no_nlist);
2247 eh_frame_section_sp =
2249 lldb_no_nlist_section_sp =
2253 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2254 !is_local_shared_cache_image) {
2255 Target &target = process->GetTarget();
2264 if (lldb_no_nlist_section_sp)
2269 if (linkedit_section_sp) {
2270 addr_t linkedit_load_addr =
2271 linkedit_section_sp->GetLoadBaseAddress(&target);
2281 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2282 const addr_t symoff_addr = linkedit_load_addr +
2283 symtab_load_command.
symoff -
2284 linkedit_file_offset;
2285 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2286 linkedit_file_offset;
2294 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2296 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2298 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2300 const addr_t indirect_syms_addr = linkedit_load_addr +
2302 linkedit_file_offset;
2304 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2305 if (indirect_syms_data_sp)
2306 indirect_symbol_index_data.SetData(
2307 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2317 if (!is_shared_cache_image) {
2319 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2320 if (strtab_data_sp) {
2321 strtab_data.SetData(strtab_data_sp, 0,
2322 strtab_data_sp->GetByteSize());
2327 if (function_starts_load_command.
cmd) {
2328 const addr_t func_start_addr =
2329 linkedit_load_addr + function_starts_load_command.
dataoff -
2330 linkedit_file_offset;
2333 function_starts_load_command.
datasize));
2334 if (func_start_data_sp)
2335 function_starts_data.SetData(func_start_data_sp, 0,
2336 func_start_data_sp->GetByteSize());
2342 if (is_local_shared_cache_image && linkedit_section_sp) {
2350 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2353 symtab_load_command.
symoff += linkedit_slide;
2354 symtab_load_command.
stroff += linkedit_slide;
2357 function_starts_load_command.
dataoff += linkedit_slide;
2358 exports_trie_load_command.
dataoff += linkedit_slide;
2362 nlist_data_byte_size);
2363 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2364 strtab_data_byte_size);
2369 && (exports_trie_load_command.
datasize > 0)));
2373 }
else if (exports_trie_load_command.
datasize > 0) {
2376 exports_trie_load_command.
datasize);
2380 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2383 if (function_starts_load_command.
cmd) {
2384 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2385 function_starts_load_command.
dataoff,
2386 function_starts_load_command.
datasize);
2390 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2392 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2409 if (text_section_sp && function_starts_data.GetByteSize()) {
2410 FunctionStarts::Entry function_start_entry;
2411 function_start_entry.data =
false;
2413 function_start_entry.addr = text_section_sp->GetFileAddress();
2415 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2418 function_start_entry.addr += delta;
2420 if (function_start_entry.addr & 1) {
2422 function_start_entry.data =
true;
2423 }
else if (always_thumb) {
2424 function_start_entry.data =
true;
2427 function_starts.Append(function_start_entry);
2435 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2441 addr_t text_base_addr = text_section_sp->GetFileAddress();
2442 size_t count = functions.
GetSize();
2443 for (
size_t i = 0; i < count; ++i) {
2447 FunctionStarts::Entry function_start_entry;
2448 function_start_entry.addr = func->
base - text_base_addr;
2450 if (function_start_entry.addr & 1) {
2452 function_start_entry.data =
true;
2453 }
else if (always_thumb) {
2454 function_start_entry.data =
true;
2457 function_starts.Append(function_start_entry);
2463 const size_t function_starts_count = function_starts.GetSize();
2478 if (unwind_or_symbol_log)
2479 module_sp->LogMessage(
2480 unwind_or_symbol_log,
2481 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2484 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2485 ? eh_frame_section_sp->GetID()
2491 std::vector<uint32_t> N_FUN_indexes;
2492 std::vector<uint32_t> N_NSYM_indexes;
2493 std::vector<uint32_t> N_INCL_indexes;
2494 std::vector<uint32_t> N_BRAC_indexes;
2495 std::vector<uint32_t> N_COMM_indexes;
2496 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2497 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2498 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2499 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2500 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2501 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2504 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2505 uint32_t nlist_idx = 0;
2506 Symbol *symbol_ptr =
nullptr;
2508 uint32_t sym_idx = 0;
2510 size_t num_syms = 0;
2511 std::string memory_symbol_name;
2512 uint32_t unmapped_local_symbols_found = 0;
2514 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2515 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2516 std::set<lldb::addr_t> resolver_addresses;
2518 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2519 if (dyld_trie_data_size > 0) {
2520 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2524 if (text_segment_sp)
2525 text_segment_file_addr = text_segment_sp->GetFileAddress();
2527 resolver_addresses, reexport_trie_entries,
2528 external_sym_trie_entries);
2531 typedef std::set<ConstString> IndirectSymbols;
2532 IndirectSymbols indirect_symbol_names;
2555 UUID process_shared_cache_uuid;
2556 addr_t process_shared_cache_base_addr;
2560 process_shared_cache_uuid);
2563 __block
bool found_image =
false;
2564 __block
void *nlist_buffer =
nullptr;
2565 __block
unsigned nlist_count = 0;
2566 __block
char *string_table =
nullptr;
2567 __block vm_offset_t vm_nlist_memory = 0;
2568 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2569 __block vm_offset_t vm_string_memory = 0;
2570 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2572 llvm::scope_exit _(^{
2573 if (vm_nlist_memory)
2574 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2575 if (vm_string_memory)
2576 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2579 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2580 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2581 UndefinedNameToDescMap undefined_name_to_desc;
2582 SymbolIndexToName reexport_shlib_needs_fixup;
2590 if (process_shared_cache_uuid.
IsValid() &&
2591 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2600 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2607 dyld_image_local_nlist_content_4Symbolication(
2608 image, ^(
const void *nlistStart, uint64_t nlistCount,
2609 const char *stringTable) {
2610 if (!nlistStart || !nlistCount)
2618 nlist_byte_size * nlistCount, &vm_nlist_memory,
2619 &vm_nlist_bytes_read);
2622 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2627 vm_address_t string_address = (vm_address_t)stringTable;
2628 vm_size_t region_size;
2629 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2630 vm_region_basic_info_data_t info;
2631 memory_object_name_t object;
2633 ®ion_size, VM_REGION_BASIC_INFO_64,
2634 (vm_region_info_t)&info, &info_count, &
object);
2640 ((vm_address_t)stringTable - string_address),
2641 &vm_string_memory, &vm_string_bytes_read);
2645 nlist_buffer = (
void *)vm_nlist_memory;
2646 string_table = (
char *)vm_string_memory;
2647 nlist_count = nlistCount;
2653 nlist_count * nlist_byte_size,
2654 byte_order, addr_byte_size);
2655 unmapped_local_symbols_found = nlist_count;
2661 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2666 for (uint32_t nlist_index = 0;
2667 nlist_index < nlist_count;
2671 std::optional<struct nlist_64> nlist_maybe =
2672 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2676 struct nlist_64 nlist = *nlist_maybe;
2679 const char *symbol_name = string_table + nlist.n_strx;
2681 if (symbol_name == NULL) {
2686 "DSC unmapped local symbol[{0}] has invalid "
2687 "string table offset {1:x} in {2}, ignoring symbol",
2688 nlist_index, nlist.n_strx,
2689 module_sp->GetFileSpec().GetPath()));
2692 if (symbol_name[0] ==
'\0')
2695 const char *symbol_name_non_abi_mangled = NULL;
2698 bool add_nlist =
true;
2699 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2700 bool demangled_is_synthesized =
false;
2701 bool is_gsym =
false;
2702 bool set_value =
true;
2704 assert(sym_idx < num_syms);
2709 switch (nlist.n_type) {
2729 symbol_name, symbol_name_non_abi_mangled,
2731 demangled_is_synthesized =
true;
2733 if (nlist.n_value != 0)
2735 nlist.n_sect, nlist.n_value);
2751 nlist.n_sect, nlist.n_value);
2753 N_FUN_addr_to_sym_idx.insert(
2754 std::make_pair(nlist.n_value, sym_idx));
2758 N_FUN_indexes.push_back(sym_idx);
2762 if (!N_FUN_indexes.empty()) {
2769 N_FUN_indexes.pop_back();
2781 N_STSYM_addr_to_sym_idx.insert(
2782 std::make_pair(nlist.n_value, sym_idx));
2783 symbol_section = section_info.
GetSection(nlist.n_sect,
2785 if (symbol_name && symbol_name[0]) {
2793 symbol_section = section_info.
GetSection(nlist.n_sect,
2827 symbol_section = section_info.
GetSection(nlist.n_sect,
2840 if (symbol_name == NULL) {
2851 N_NSYM_indexes.clear();
2852 N_INCL_indexes.clear();
2853 N_BRAC_indexes.clear();
2854 N_COMM_indexes.clear();
2855 N_FUN_indexes.clear();
2861 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2862 if (N_SO_has_full_path) {
2863 if ((N_SO_index == sym_idx - 1) &&
2864 ((sym_idx - 1) < num_syms)) {
2870 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2876 N_SO_index = sym_idx;
2878 }
else if ((N_SO_index == sym_idx - 1) &&
2879 ((sym_idx - 1) < num_syms)) {
2884 const char *so_path = sym[sym_idx - 1]
2888 if (so_path && so_path[0]) {
2889 std::string full_so_path(so_path);
2890 const size_t double_slash_pos =
2891 full_so_path.find(
"//");
2892 if (double_slash_pos != std::string::npos) {
2903 &full_so_path[double_slash_pos + 1],
2904 FileSpec::Style::native);
2907 full_so_path.erase(0, double_slash_pos + 1);
2911 if (*full_so_path.rbegin() !=
'/')
2912 full_so_path +=
'/';
2913 full_so_path += symbol_name;
2917 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2921 N_SO_index = sym_idx;
2942 N_INCL_indexes.push_back(sym_idx);
2952 if (!N_INCL_indexes.empty()) {
2957 N_INCL_indexes.pop_back();
2992 symbol_section = section_info.
GetSection(nlist.n_sect,
3003 symbol_section = section_info.
GetSection(nlist.n_sect,
3005 N_BRAC_indexes.push_back(sym_idx);
3015 symbol_section = section_info.
GetSection(nlist.n_sect,
3017 if (!N_BRAC_indexes.empty()) {
3022 N_BRAC_indexes.pop_back();
3039 N_COMM_indexes.push_back(sym_idx);
3044 symbol_section = section_info.
GetSection(nlist.n_sect,
3055 if (!N_COMM_indexes.empty()) {
3060 N_COMM_indexes.pop_back();
3075 uint8_t n_type = N_TYPE & nlist.n_type;
3076 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3080 const char *reexport_name_cstr =
3081 strtab_data.PeekCStr(nlist.n_value);
3082 if (reexport_name_cstr && reexport_name_cstr[0]) {
3085 reexport_name_cstr +
3086 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3089 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3091 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3097 if (symbol_name && symbol_name[0]) {
3099 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3100 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3112 symbol_section = section_info.
GetSection(nlist.n_sect,
3115 if (symbol_section == NULL) {
3121 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3124 uint32_t section_type =
3125 symbol_section->Get() & SECTION_TYPE;
3127 switch (section_type) {
3128 case S_CSTRING_LITERALS:
3131 case S_4BYTE_LITERALS:
3134 case S_8BYTE_LITERALS:
3137 case S_LITERAL_POINTERS:
3140 case S_NON_LAZY_SYMBOL_POINTERS:
3144 case S_LAZY_SYMBOL_POINTERS:
3147 case S_SYMBOL_STUBS:
3151 case S_MOD_INIT_FUNC_POINTERS:
3155 case S_MOD_TERM_FUNC_POINTERS:
3163 case S_16BYTE_LITERALS:
3169 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3173 switch (symbol_section->GetType()) {
3200 llvm::StringRef symbol_sect_name =
3201 symbol_section->GetName();
3202 if (symbol_section->IsDescendant(
3203 text_section_sp.get())) {
3204 if (symbol_section->IsClear(
3205 S_ATTR_PURE_INSTRUCTIONS |
3206 S_ATTR_SELF_MODIFYING_CODE |
3207 S_ATTR_SOME_INSTRUCTIONS))
3211 }
else if (symbol_section->IsDescendant(
3212 data_section_sp.get()) ||
3213 symbol_section->IsDescendant(
3214 data_dirty_section_sp.get()) ||
3215 symbol_section->IsDescendant(
3216 data_const_section_sp.get())) {
3217 if (symbol_sect_name.starts_with(
"__objc")) {
3222 symbol_name_non_abi_mangled, type))
3223 demangled_is_synthesized =
true;
3224 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
3229 }
else if (symbol_sect_name.starts_with(
"__IMPORT"))
3231 }
else if (symbol_section->IsDescendant(
3232 objc_section_sp.get())) {
3234 if (symbol_name && symbol_name[0] ==
'.') {
3235 llvm::StringRef symbol_name_ref(symbol_name);
3237 g_objc_v1_prefix_class(
".objc_class_name_");
3238 if (symbol_name_ref.starts_with(
3239 g_objc_v1_prefix_class)) {
3240 symbol_name_non_abi_mangled = symbol_name;
3241 symbol_name = symbol_name +
3242 g_objc_v1_prefix_class.size();
3244 demangled_is_synthesized =
true;
3255 uint64_t symbol_value = nlist.n_value;
3256 if (symbol_name_non_abi_mangled) {
3262 if (symbol_name && symbol_name[0] ==
'_') {
3269 if (is_gsym && is_debug) {
3270 const char *gsym_name =
3276 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3280 if (symbol_section) {
3281 const addr_t section_file_addr =
3282 symbol_section->GetFileAddress();
3283 symbol_value -= section_file_addr;
3286 if (is_debug ==
false) {
3294 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3295 if (range.first != range.second) {
3296 bool found_it =
false;
3297 for (
auto pos = range.first; pos != range.second;
3299 if (sym[sym_idx].GetMangled().
GetName(
3303 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3309 sym[sym_idx].IsExternal());
3310 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3312 if (resolver_addresses.find(nlist.n_value) !=
3313 resolver_addresses.end())
3315 sym[sym_idx].
Clear();
3323 if (resolver_addresses.find(nlist.n_value) !=
3324 resolver_addresses.end())
3336 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3338 if (range.first != range.second) {
3339 bool found_it =
false;
3340 for (
auto pos = range.first; pos != range.second;
3342 if (sym[sym_idx].GetMangled().
GetName(
3346 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3352 sym[sym_idx].IsExternal());
3353 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3355 sym[sym_idx].
Clear();
3363 const char *gsym_name =
3371 ConstNameToSymbolIndexMap::const_iterator pos =
3372 N_GSYM_name_to_sym_idx.find(gsym_name);
3373 if (pos != N_GSYM_name_to_sym_idx.end()) {
3374 const uint32_t GSYM_sym_idx = pos->second;
3375 m_nlist_idx_to_sym_idx[nlist_idx] =
3381 Address(symbol_section, symbol_value);
3382 add_symbol_addr(sym[GSYM_sym_idx]
3389 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3391 sym[sym_idx].
Clear();
3399 sym[sym_idx].
SetID(nlist_idx);
3403 Address(symbol_section, symbol_value);
3405 sym[sym_idx].GetAddress().GetFileAddress());
3407 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3409 if (demangled_is_synthesized)
3413 sym[sym_idx].
Clear();
3420 for (
const auto &pos : reexport_shlib_needs_fixup) {
3421 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3422 if (undef_pos != undefined_name_to_desc.end()) {
3423 const uint8_t dylib_ordinal =
3424 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3425 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3435 if (nlist_data.GetByteSize() > 0) {
3439 if (sym ==
nullptr) {
3441 symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3442 num_syms = symtab.GetNumSymbols();
3445 if (unmapped_local_symbols_found) {
3446 assert(m_dysymtab.ilocalsym == 0);
3447 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3448 nlist_idx = m_dysymtab.nlocalsym;
3453 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3454 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3455 UndefinedNameToDescMap undefined_name_to_desc;
3456 SymbolIndexToName reexport_shlib_needs_fixup;
3464 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3466 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3467 if (is_debug != debug_only)
3470 const char *symbol_name_non_abi_mangled =
nullptr;
3471 const char *symbol_name =
nullptr;
3473 if (have_strtab_data) {
3474 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3476 if (symbol_name ==
nullptr) {
3480 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3482 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3485 if (symbol_name[0] ==
'\0')
3486 symbol_name =
nullptr;
3488 const addr_t str_addr = strtab_addr + nlist.n_strx;
3490 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3492 symbol_name = memory_symbol_name.c_str();
3497 bool add_nlist =
true;
3498 bool is_gsym =
false;
3499 bool demangled_is_synthesized =
false;
3500 bool set_value =
true;
3502 assert(sym_idx < num_syms);
3503 sym[sym_idx].SetDebug(is_debug);
3506 switch (nlist.n_type) {
3521 sym[sym_idx].SetExternal(
true);
3524 symbol_name_non_abi_mangled, type)) {
3525 demangled_is_synthesized =
true;
3527 if (nlist.n_value != 0)
3529 section_info.GetSection(nlist.n_sect, nlist.n_value);
3545 section_info.GetSection(nlist.n_sect, nlist.n_value);
3547 N_FUN_addr_to_sym_idx.insert(
3548 std::make_pair(nlist.n_value, sym_idx));
3552 N_FUN_indexes.push_back(sym_idx);
3556 if (!N_FUN_indexes.empty()) {
3559 symtab.SymbolAtIndex(N_FUN_indexes.back())
3560 ->SetByteSize(nlist.n_value);
3561 N_FUN_indexes.pop_back();
3572 N_STSYM_addr_to_sym_idx.insert(
3573 std::make_pair(nlist.n_value, sym_idx));
3574 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3575 if (symbol_name && symbol_name[0]) {
3583 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3614 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3626 if (symbol_name ==
nullptr) {
3633 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3634 symbol_ptr->SetByteSize(sym_idx);
3635 symbol_ptr->SetSizeIsSibling(
true);
3637 N_NSYM_indexes.clear();
3638 N_INCL_indexes.clear();
3639 N_BRAC_indexes.clear();
3640 N_COMM_indexes.clear();
3641 N_FUN_indexes.clear();
3647 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3648 if (N_SO_has_full_path) {
3649 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3652 sym[sym_idx - 1].GetMangled().SetValue(
3654 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3659 N_SO_index = sym_idx;
3661 }
else if ((N_SO_index == sym_idx - 1) &&
3662 ((sym_idx - 1) < num_syms)) {
3666 llvm::StringRef so_path = sym[sym_idx - 1]
3670 if (!so_path.empty()) {
3671 std::string full_so_path(so_path);
3672 const size_t double_slash_pos = full_so_path.find(
"//");
3673 if (double_slash_pos != std::string::npos) {
3681 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3682 FileSpec::Style::native);
3685 full_so_path.erase(0, double_slash_pos + 1);
3689 if (*full_so_path.rbegin() !=
'/')
3690 full_so_path +=
'/';
3691 full_so_path += symbol_name;
3692 sym[sym_idx - 1].GetMangled().SetValue(
3695 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3699 N_SO_index = sym_idx;
3719 N_INCL_indexes.push_back(sym_idx);
3728 if (!N_INCL_indexes.empty()) {
3729 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3730 symbol_ptr->SetByteSize(sym_idx + 1);
3731 symbol_ptr->SetSizeIsSibling(
true);
3732 N_INCL_indexes.pop_back();
3767 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3776 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3777 N_BRAC_indexes.push_back(sym_idx);
3786 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3787 if (!N_BRAC_indexes.empty()) {
3788 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3789 symbol_ptr->SetByteSize(sym_idx + 1);
3790 symbol_ptr->SetSizeIsSibling(
true);
3791 N_BRAC_indexes.pop_back();
3807 N_COMM_indexes.push_back(sym_idx);
3812 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3821 if (!N_COMM_indexes.empty()) {
3822 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3823 symbol_ptr->SetByteSize(sym_idx + 1);
3824 symbol_ptr->SetSizeIsSibling(
true);
3825 N_COMM_indexes.pop_back();
3839 uint8_t n_type = N_TYPE & nlist.n_type;
3840 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3844 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3845 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3848 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3849 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3851 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3852 indirect_symbol_names.insert(
3853 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3859 if (symbol_name && symbol_name[0]) {
3861 ((symbol_name[0] ==
'_') ? 1 : 0));
3862 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3875 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3877 if (!symbol_section) {
3883 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3886 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3888 switch (section_type) {
3889 case S_CSTRING_LITERALS:
3892 case S_4BYTE_LITERALS:
3895 case S_8BYTE_LITERALS:
3898 case S_LITERAL_POINTERS:
3901 case S_NON_LAZY_SYMBOL_POINTERS:
3904 case S_LAZY_SYMBOL_POINTERS:
3907 case S_SYMBOL_STUBS:
3911 case S_MOD_INIT_FUNC_POINTERS:
3914 case S_MOD_TERM_FUNC_POINTERS:
3921 case S_16BYTE_LITERALS:
3927 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3931 switch (symbol_section->GetType()) {
3953 llvm::StringRef symbol_sect_name = symbol_section->GetName();
3954 if (symbol_section->IsDescendant(text_section_sp.get())) {
3955 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3956 S_ATTR_SELF_MODIFYING_CODE |
3957 S_ATTR_SOME_INSTRUCTIONS))
3961 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3962 symbol_section->IsDescendant(
3963 data_dirty_section_sp.get()) ||
3964 symbol_section->IsDescendant(
3965 data_const_section_sp.get())) {
3966 if (symbol_sect_name.starts_with(
"__objc")) {
3970 symbol_name, symbol_name_non_abi_mangled, type))
3971 demangled_is_synthesized =
true;
3972 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
3977 }
else if (symbol_sect_name.starts_with(
"__IMPORT")) {
3979 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
3981 if (symbol_name && symbol_name[0] ==
'.') {
3982 llvm::StringRef symbol_name_ref(symbol_name);
3983 llvm::StringRef g_objc_v1_prefix_class(
3984 ".objc_class_name_");
3985 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
3986 symbol_name_non_abi_mangled = symbol_name;
3987 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
3989 demangled_is_synthesized =
true;
4000 sym[sym_idx].Clear();
4004 uint64_t symbol_value = nlist.n_value;
4006 if (symbol_name_non_abi_mangled) {
4007 sym[sym_idx].GetMangled().SetMangledName(
4009 sym[sym_idx].GetMangled().SetDemangledName(
ConstString(symbol_name));
4012 if (symbol_name && symbol_name[0] ==
'_') {
4018 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4023 const char *gsym_name = sym[sym_idx]
4028 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4031 if (symbol_section) {
4032 const addr_t section_file_addr = symbol_section->GetFileAddress();
4033 symbol_value -= section_file_addr;
4042 std::pair<ValueToSymbolIndexMap::const_iterator,
4043 ValueToSymbolIndexMap::const_iterator>
4045 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4046 if (range.first != range.second) {
4047 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4048 pos != range.second; ++pos) {
4050 sym[pos->second].GetMangled().GetName(
4052 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4056 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4057 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4058 if (resolver_addresses.find(nlist.n_value) !=
4059 resolver_addresses.end())
4061 sym[sym_idx].Clear();
4066 if (resolver_addresses.find(nlist.n_value) !=
4067 resolver_addresses.end())
4077 std::pair<ValueToSymbolIndexMap::const_iterator,
4078 ValueToSymbolIndexMap::const_iterator>
4080 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4081 if (range.first != range.second) {
4082 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4083 pos != range.second; ++pos) {
4085 sym[pos->second].GetMangled().GetName(
4087 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4091 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4092 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4093 sym[sym_idx].Clear();
4099 const char *gsym_name = sym[sym_idx]
4104 ConstNameToSymbolIndexMap::const_iterator pos =
4105 N_GSYM_name_to_sym_idx.find(gsym_name);
4106 if (pos != N_GSYM_name_to_sym_idx.end()) {
4107 const uint32_t GSYM_sym_idx = pos->second;
4108 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4111 sym[GSYM_sym_idx].GetAddressRef() =
4112 Address(symbol_section, symbol_value);
4114 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4118 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4119 sym[sym_idx].Clear();
4127 sym[sym_idx].SetID(nlist_idx);
4128 sym[sym_idx].SetType(type);
4130 sym[sym_idx].GetAddressRef() =
Address(symbol_section, symbol_value);
4132 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4134 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4135 if (nlist.n_desc & N_WEAK_REF)
4136 sym[sym_idx].SetIsWeak(
true);
4138 if (demangled_is_synthesized)
4139 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4147 std::vector<struct nlist_64> nlists;
4148 nlists.reserve(symtab_load_command.nsyms);
4149 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4151 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4152 nlists.push_back(*nlist);
4162 for (
auto &nlist : nlists) {
4163 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4169 for (
auto &nlist : nlists) {
4174 for (
const auto &pos : reexport_shlib_needs_fixup) {
4175 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4176 if (undef_pos != undefined_name_to_desc.end()) {
4177 const uint8_t dylib_ordinal =
4178 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4179 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4180 sym[pos.first].SetReExportedSymbolSharedLibrary(
4181 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4187 int trie_symbol_table_augment_count = 0;
4188 for (
auto &e : external_sym_trie_entries) {
4189 if (!symbols_added.contains(e.entry.address))
4190 trie_symbol_table_augment_count++;
4193 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4194 num_syms = sym_idx + trie_symbol_table_augment_count;
4195 sym = symtab.Resize(num_syms);
4197 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4200 for (
auto &e : external_sym_trie_entries) {
4201 if (symbols_added.contains(e.entry.address))
4207 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4209 const char *symbol_name = e.entry.name.GetCString();
4210 bool demangled_is_synthesized =
false;
4212 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4213 data_section_sp, data_dirty_section_sp,
4214 data_const_section_sp, symbol_section);
4216 sym[sym_idx].SetType(type);
4217 if (symbol_section) {
4218 sym[sym_idx].SetID(synthetic_sym_id++);
4219 sym[sym_idx].GetMangled().SetMangledName(
ConstString(symbol_name));
4220 if (demangled_is_synthesized)
4221 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4222 sym[sym_idx].SetIsSynthetic(
true);
4223 sym[sym_idx].SetExternal(
true);
4224 sym[sym_idx].GetAddressRef() = symbol_addr;
4233 if (function_starts_count > 0) {
4234 uint32_t num_synthetic_function_symbols = 0;
4235 for (i = 0; i < function_starts_count; ++i) {
4236 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4237 ++num_synthetic_function_symbols;
4240 if (num_synthetic_function_symbols > 0) {
4241 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4242 num_syms = sym_idx + num_synthetic_function_symbols;
4243 sym = symtab.Resize(num_syms);
4245 for (i = 0; i < function_starts_count; ++i) {
4246 const FunctionStarts::Entry *func_start_entry =
4247 function_starts.GetEntryAtIndex(i);
4248 if (!symbols_added.contains(func_start_entry->addr)) {
4249 addr_t symbol_file_addr = func_start_entry->addr;
4250 uint32_t symbol_flags = 0;
4251 if (func_start_entry->data)
4254 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4256 if (symbol_section) {
4257 sym[sym_idx].SetID(synthetic_sym_id++);
4261 sym[sym_idx].GetMangled().SetDemangledName(
ConstString());
4263 sym[sym_idx].SetIsSynthetic(
true);
4264 sym[sym_idx].GetAddressRef() = symbol_addr;
4267 sym[sym_idx].SetFlags(symbol_flags);
4278 if (sym_idx < num_syms) {
4280 sym = symtab.Resize(num_syms);
4284 if (m_dysymtab.nindirectsyms != 0) {
4285 if (indirect_symbol_index_data.GetByteSize()) {
4286 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4287 m_nlist_idx_to_sym_idx.end();
4289 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4291 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4293 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4294 if (symbol_stub_byte_size == 0)
4297 const uint32_t num_symbol_stubs =
4298 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4300 if (num_symbol_stubs == 0)
4303 const uint32_t symbol_stub_index_offset =
4304 m_mach_sections[sect_idx].reserved1;
4305 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4306 const uint32_t symbol_stub_index =
4307 symbol_stub_index_offset + stub_idx;
4309 m_mach_sections[sect_idx].addr +
4310 (stub_idx * symbol_stub_byte_size);
4312 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4313 symbol_stub_offset, 4)) {
4314 const uint32_t stub_sym_id =
4315 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4316 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4319 NListIndexToSymbolIndexMap::const_iterator index_pos =
4320 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4321 Symbol *stub_symbol =
nullptr;
4322 if (index_pos != end_index_pos) {
4325 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4329 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4333 Address so_addr(symbol_stub_addr, section_list);
4340 if (resolver_addresses.find(symbol_stub_addr) ==
4341 resolver_addresses.end())
4351 if (sym_idx >= num_syms) {
4352 sym = symtab.Resize(++num_syms);
4353 stub_symbol =
nullptr;
4355 sym[sym_idx].SetID(synthetic_sym_id++);
4356 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4357 if (resolver_addresses.find(symbol_stub_addr) ==
4358 resolver_addresses.end())
4362 sym[sym_idx].SetIsSynthetic(
true);
4363 sym[sym_idx].GetAddressRef() = so_addr;
4364 add_symbol_addr(so_addr.GetFileAddress());
4365 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4370 "warning: symbol stub referencing symbol table "
4371 "symbol %u that isn't in our minimal symbol table, "
4382 if (!reexport_trie_entries.empty()) {
4383 for (
const auto &e : reexport_trie_entries) {
4384 if (e.entry.import_name) {
4387 if (indirect_symbol_names.find(e.entry.name) ==
4388 indirect_symbol_names.end()) {
4390 if (sym_idx >= num_syms)
4391 sym = symtab.Resize(++num_syms);
4392 sym[sym_idx].SetID(synthetic_sym_id++);
4393 sym[sym_idx].GetMangled() =
Mangled(e.entry.name);
4395 sym[sym_idx].SetIsSynthetic(
true);
4396 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4397 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4398 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4399 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));