2100 llvm::StringRef file_name = file.
GetFilename().nonEmptyOr(
"<Unknown>");
2102 file_name.str().c_str());
2103 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2104 Progress progress(
"Parsing symbol table", file_name.str());
2119 llvm::DenseSet<addr_t> symbols_added;
2123 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2127 symbols_added.insert(file_addr);
2129 FunctionStarts function_starts;
2135 for (i = 0; i <
m_header.ncmds; ++i) {
2138 llvm::MachO::load_command lc;
2144 llvm::MachO::symtab_command lc_obj;
2145 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2146 lc_obj.cmd = lc.cmd;
2147 lc_obj.cmdsize = lc.cmdsize;
2148 symtab_load_command = lc_obj;
2153 case LC_DYLD_INFO_ONLY: {
2154 llvm::MachO::dyld_info_command lc_obj;
2155 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2156 lc_obj.cmd = lc.cmd;
2157 lc_obj.cmdsize = lc.cmdsize;
2163 case LC_LOAD_WEAK_DYLIB:
2164 case LC_REEXPORT_DYLIB:
2166 case LC_LOAD_UPWARD_DYLIB: {
2167 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2168 const char *path =
m_data_nsp->PeekCStr(name_offset);
2176 if (lc.cmd == LC_REEXPORT_DYLIB) {
2180 dylib_files.
Append(file_spec);
2184 case LC_DYLD_EXPORTS_TRIE: {
2185 llvm::MachO::linkedit_data_command lc_obj;
2186 lc_obj.cmd = lc.cmd;
2187 lc_obj.cmdsize = lc.cmdsize;
2188 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2189 exports_trie_load_command = lc_obj;
2191 case LC_FUNCTION_STARTS: {
2192 llvm::MachO::linkedit_data_command lc_obj;
2193 lc_obj.cmd = lc.cmd;
2194 lc_obj.cmdsize = lc.cmdsize;
2195 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2196 function_starts_load_command = lc_obj;
2200 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2203 image_uuid =
UUID(uuid_bytes, 16);
2210 offset = cmd_offset + lc.cmdsize;
2213 if (!symtab_load_command.
cmd)
2217 if (section_list ==
nullptr)
2220 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2222 bool bit_width_32 = addr_byte_size == 4;
2223 const size_t nlist_byte_size =
2224 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2226 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2227 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2228 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2229 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2231 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2233 const
addr_t nlist_data_byte_size =
2234 symtab_load_command.nsyms * nlist_byte_size;
2235 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2238 ProcessSP process_sp(m_process_wp.lock());
2239 Process *process = process_sp.get();
2243 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2253 section_list->FindSectionByName(g_segment_name_TEXT));
2255 section_list->FindSectionByName(g_segment_name_DATA));
2257 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2259 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2261 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2263 section_list->FindSectionByName(g_segment_name_OBJC));
2266 if (text_section_sp.get()) {
2267 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2268 g_section_name_eh_frame);
2269 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2270 g_section_name_lldb_no_nlist);
2272 eh_frame_section_sp =
2274 lldb_no_nlist_section_sp =
2278 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2279 !is_local_shared_cache_image) {
2280 Target &target = process->GetTarget();
2289 if (lldb_no_nlist_section_sp)
2294 if (linkedit_section_sp) {
2295 addr_t linkedit_load_addr =
2296 linkedit_section_sp->GetLoadBaseAddress(&target);
2306 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2307 const addr_t symoff_addr = linkedit_load_addr +
2308 symtab_load_command.
symoff -
2309 linkedit_file_offset;
2310 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2311 linkedit_file_offset;
2319 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2321 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2323 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2325 const addr_t indirect_syms_addr = linkedit_load_addr +
2327 linkedit_file_offset;
2329 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2330 if (indirect_syms_data_sp)
2331 indirect_symbol_index_data.SetData(
2332 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2342 if (!is_shared_cache_image) {
2344 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2345 if (strtab_data_sp) {
2346 strtab_data.SetData(strtab_data_sp, 0,
2347 strtab_data_sp->GetByteSize());
2352 if (function_starts_load_command.
cmd) {
2353 const addr_t func_start_addr =
2354 linkedit_load_addr + function_starts_load_command.
dataoff -
2355 linkedit_file_offset;
2358 function_starts_load_command.
datasize));
2359 if (func_start_data_sp)
2360 function_starts_data.SetData(func_start_data_sp, 0,
2361 func_start_data_sp->GetByteSize());
2367 if (is_local_shared_cache_image && linkedit_section_sp) {
2375 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2378 symtab_load_command.
symoff += linkedit_slide;
2379 symtab_load_command.
stroff += linkedit_slide;
2382 function_starts_load_command.
dataoff += linkedit_slide;
2383 exports_trie_load_command.
dataoff += linkedit_slide;
2387 nlist_data_byte_size);
2388 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2389 strtab_data_byte_size);
2394 && (exports_trie_load_command.
datasize > 0)));
2398 }
else if (exports_trie_load_command.
datasize > 0) {
2401 exports_trie_load_command.
datasize);
2405 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2408 if (function_starts_load_command.
cmd) {
2409 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2410 function_starts_load_command.
dataoff,
2411 function_starts_load_command.
datasize);
2415 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2417 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2434 if (text_section_sp && function_starts_data.GetByteSize()) {
2435 FunctionStarts::Entry function_start_entry;
2436 function_start_entry.data =
false;
2438 function_start_entry.addr = text_section_sp->GetFileAddress();
2440 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2443 function_start_entry.addr += delta;
2445 if (function_start_entry.addr & 1) {
2447 function_start_entry.data =
true;
2448 }
else if (always_thumb) {
2449 function_start_entry.data =
true;
2452 function_starts.Append(function_start_entry);
2460 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2466 addr_t text_base_addr = text_section_sp->GetFileAddress();
2467 size_t count = functions.
GetSize();
2468 for (
size_t i = 0; i < count; ++i) {
2472 FunctionStarts::Entry function_start_entry;
2473 function_start_entry.addr = func->
base - text_base_addr;
2475 if (function_start_entry.addr & 1) {
2477 function_start_entry.data =
true;
2478 }
else if (always_thumb) {
2479 function_start_entry.data =
true;
2482 function_starts.Append(function_start_entry);
2488 const size_t function_starts_count = function_starts.GetSize();
2503 if (unwind_or_symbol_log)
2504 module_sp->LogMessage(
2505 unwind_or_symbol_log,
2506 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2509 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2510 ? eh_frame_section_sp->GetID()
2516 std::vector<uint32_t> N_FUN_indexes;
2517 std::vector<uint32_t> N_NSYM_indexes;
2518 std::vector<uint32_t> N_INCL_indexes;
2519 std::vector<uint32_t> N_BRAC_indexes;
2520 std::vector<uint32_t> N_COMM_indexes;
2521 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2522 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2523 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2524 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2525 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2526 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2529 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2530 uint32_t nlist_idx = 0;
2531 Symbol *symbol_ptr =
nullptr;
2533 uint32_t sym_idx = 0;
2535 size_t num_syms = 0;
2536 std::string memory_symbol_name;
2537 uint32_t unmapped_local_symbols_found = 0;
2539 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2540 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2541 std::set<lldb::addr_t> resolver_addresses;
2543 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2544 if (dyld_trie_data_size > 0) {
2545 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2549 if (text_segment_sp)
2550 text_segment_file_addr = text_segment_sp->GetFileAddress();
2552 resolver_addresses, reexport_trie_entries,
2553 external_sym_trie_entries);
2556 typedef std::set<ConstString> IndirectSymbols;
2557 IndirectSymbols indirect_symbol_names;
2580 UUID process_shared_cache_uuid;
2581 addr_t process_shared_cache_base_addr;
2585 process_shared_cache_uuid);
2588 __block
bool found_image =
false;
2589 __block
void *nlist_buffer =
nullptr;
2590 __block
unsigned nlist_count = 0;
2591 __block
char *string_table =
nullptr;
2592 __block vm_offset_t vm_nlist_memory = 0;
2593 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2594 __block vm_offset_t vm_string_memory = 0;
2595 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2597 llvm::scope_exit _(^{
2598 if (vm_nlist_memory)
2599 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2600 if (vm_string_memory)
2601 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2604 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2605 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2606 UndefinedNameToDescMap undefined_name_to_desc;
2607 SymbolIndexToName reexport_shlib_needs_fixup;
2615 if (process_shared_cache_uuid.
IsValid() &&
2616 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2625 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2632 dyld_image_local_nlist_content_4Symbolication(
2633 image, ^(
const void *nlistStart, uint64_t nlistCount,
2634 const char *stringTable) {
2635 if (!nlistStart || !nlistCount)
2643 nlist_byte_size * nlistCount, &vm_nlist_memory,
2644 &vm_nlist_bytes_read);
2647 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2652 vm_address_t string_address = (vm_address_t)stringTable;
2653 vm_size_t region_size;
2654 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2655 vm_region_basic_info_data_t info;
2656 memory_object_name_t object;
2658 ®ion_size, VM_REGION_BASIC_INFO_64,
2659 (vm_region_info_t)&info, &info_count, &
object);
2665 ((vm_address_t)stringTable - string_address),
2666 &vm_string_memory, &vm_string_bytes_read);
2670 nlist_buffer = (
void *)vm_nlist_memory;
2671 string_table = (
char *)vm_string_memory;
2672 nlist_count = nlistCount;
2678 nlist_count * nlist_byte_size,
2679 byte_order, addr_byte_size);
2680 unmapped_local_symbols_found = nlist_count;
2686 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2691 for (uint32_t nlist_index = 0;
2692 nlist_index < nlist_count;
2696 std::optional<struct nlist_64> nlist_maybe =
2697 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2701 struct nlist_64 nlist = *nlist_maybe;
2704 const char *symbol_name = string_table + nlist.n_strx;
2706 if (symbol_name == NULL) {
2711 "DSC unmapped local symbol[{0}] has invalid "
2712 "string table offset {1:x} in {2}, ignoring symbol",
2713 nlist_index, nlist.n_strx,
2714 module_sp->GetFileSpec().GetPath()));
2717 if (symbol_name[0] ==
'\0')
2720 const char *symbol_name_non_abi_mangled = NULL;
2723 bool add_nlist =
true;
2724 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2725 bool demangled_is_synthesized =
false;
2726 bool is_gsym =
false;
2727 bool set_value =
true;
2729 assert(sym_idx < num_syms);
2734 switch (nlist.n_type) {
2754 symbol_name, symbol_name_non_abi_mangled,
2756 demangled_is_synthesized =
true;
2758 if (nlist.n_value != 0)
2760 nlist.n_sect, nlist.n_value);
2776 nlist.n_sect, nlist.n_value);
2778 N_FUN_addr_to_sym_idx.insert(
2779 std::make_pair(nlist.n_value, sym_idx));
2783 N_FUN_indexes.push_back(sym_idx);
2787 if (!N_FUN_indexes.empty()) {
2794 N_FUN_indexes.pop_back();
2806 N_STSYM_addr_to_sym_idx.insert(
2807 std::make_pair(nlist.n_value, sym_idx));
2808 symbol_section = section_info.
GetSection(nlist.n_sect,
2810 if (symbol_name && symbol_name[0]) {
2818 symbol_section = section_info.
GetSection(nlist.n_sect,
2852 symbol_section = section_info.
GetSection(nlist.n_sect,
2865 if (symbol_name == NULL) {
2876 N_NSYM_indexes.clear();
2877 N_INCL_indexes.clear();
2878 N_BRAC_indexes.clear();
2879 N_COMM_indexes.clear();
2880 N_FUN_indexes.clear();
2886 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2887 if (N_SO_has_full_path) {
2888 if ((N_SO_index == sym_idx - 1) &&
2889 ((sym_idx - 1) < num_syms)) {
2895 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2901 N_SO_index = sym_idx;
2903 }
else if ((N_SO_index == sym_idx - 1) &&
2904 ((sym_idx - 1) < num_syms)) {
2909 const char *so_path = sym[sym_idx - 1]
2913 if (so_path && so_path[0]) {
2914 std::string full_so_path(so_path);
2915 const size_t double_slash_pos =
2916 full_so_path.find(
"//");
2917 if (double_slash_pos != std::string::npos) {
2928 &full_so_path[double_slash_pos + 1],
2929 FileSpec::Style::native);
2932 full_so_path.erase(0, double_slash_pos + 1);
2936 if (*full_so_path.rbegin() !=
'/')
2937 full_so_path +=
'/';
2938 full_so_path += symbol_name;
2942 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2946 N_SO_index = sym_idx;
2967 N_INCL_indexes.push_back(sym_idx);
2977 if (!N_INCL_indexes.empty()) {
2982 N_INCL_indexes.pop_back();
3017 symbol_section = section_info.
GetSection(nlist.n_sect,
3028 symbol_section = section_info.
GetSection(nlist.n_sect,
3030 N_BRAC_indexes.push_back(sym_idx);
3040 symbol_section = section_info.
GetSection(nlist.n_sect,
3042 if (!N_BRAC_indexes.empty()) {
3047 N_BRAC_indexes.pop_back();
3064 N_COMM_indexes.push_back(sym_idx);
3069 symbol_section = section_info.
GetSection(nlist.n_sect,
3080 if (!N_COMM_indexes.empty()) {
3085 N_COMM_indexes.pop_back();
3100 uint8_t n_type = N_TYPE & nlist.n_type;
3101 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3105 const char *reexport_name_cstr =
3106 strtab_data.PeekCStr(nlist.n_value);
3107 if (reexport_name_cstr && reexport_name_cstr[0]) {
3110 reexport_name_cstr +
3111 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3114 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3116 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3122 if (symbol_name && symbol_name[0]) {
3124 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3125 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3137 symbol_section = section_info.
GetSection(nlist.n_sect,
3140 if (symbol_section == NULL) {
3146 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3149 uint32_t section_type =
3150 symbol_section->Get() & SECTION_TYPE;
3152 switch (section_type) {
3153 case S_CSTRING_LITERALS:
3156 case S_4BYTE_LITERALS:
3159 case S_8BYTE_LITERALS:
3162 case S_LITERAL_POINTERS:
3165 case S_NON_LAZY_SYMBOL_POINTERS:
3169 case S_LAZY_SYMBOL_POINTERS:
3172 case S_SYMBOL_STUBS:
3176 case S_MOD_INIT_FUNC_POINTERS:
3180 case S_MOD_TERM_FUNC_POINTERS:
3188 case S_16BYTE_LITERALS:
3194 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3198 switch (symbol_section->GetType()) {
3225 llvm::StringRef symbol_sect_name =
3226 symbol_section->GetName();
3227 if (symbol_section->IsDescendant(
3228 text_section_sp.get())) {
3229 if (symbol_section->IsClear(
3230 S_ATTR_PURE_INSTRUCTIONS |
3231 S_ATTR_SELF_MODIFYING_CODE |
3232 S_ATTR_SOME_INSTRUCTIONS))
3236 }
else if (symbol_section->IsDescendant(
3237 data_section_sp.get()) ||
3238 symbol_section->IsDescendant(
3239 data_dirty_section_sp.get()) ||
3240 symbol_section->IsDescendant(
3241 data_const_section_sp.get())) {
3242 if (symbol_sect_name.starts_with(
"__objc")) {
3247 symbol_name_non_abi_mangled, type))
3248 demangled_is_synthesized =
true;
3249 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
3254 }
else if (symbol_sect_name.starts_with(
"__IMPORT"))
3256 }
else if (symbol_section->IsDescendant(
3257 objc_section_sp.get())) {
3259 if (symbol_name && symbol_name[0] ==
'.') {
3260 llvm::StringRef symbol_name_ref(symbol_name);
3262 g_objc_v1_prefix_class(
".objc_class_name_");
3263 if (symbol_name_ref.starts_with(
3264 g_objc_v1_prefix_class)) {
3265 symbol_name_non_abi_mangled = symbol_name;
3266 symbol_name = symbol_name +
3267 g_objc_v1_prefix_class.size();
3269 demangled_is_synthesized =
true;
3280 uint64_t symbol_value = nlist.n_value;
3281 if (symbol_name_non_abi_mangled) {
3287 if (symbol_name && symbol_name[0] ==
'_') {
3294 if (is_gsym && is_debug) {
3295 const char *gsym_name =
3301 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3305 if (symbol_section) {
3306 const addr_t section_file_addr =
3307 symbol_section->GetFileAddress();
3308 symbol_value -= section_file_addr;
3311 if (is_debug ==
false) {
3319 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3320 if (range.first != range.second) {
3321 bool found_it =
false;
3322 for (
auto pos = range.first; pos != range.second;
3324 if (sym[sym_idx].GetMangled().
GetName(
3328 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3334 sym[sym_idx].IsExternal());
3335 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3337 if (resolver_addresses.find(nlist.n_value) !=
3338 resolver_addresses.end())
3340 sym[sym_idx].
Clear();
3348 if (resolver_addresses.find(nlist.n_value) !=
3349 resolver_addresses.end())
3361 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3363 if (range.first != range.second) {
3364 bool found_it =
false;
3365 for (
auto pos = range.first; pos != range.second;
3367 if (sym[sym_idx].GetMangled().
GetName(
3371 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3377 sym[sym_idx].IsExternal());
3378 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3380 sym[sym_idx].
Clear();
3388 const char *gsym_name =
3396 ConstNameToSymbolIndexMap::const_iterator pos =
3397 N_GSYM_name_to_sym_idx.find(gsym_name);
3398 if (pos != N_GSYM_name_to_sym_idx.end()) {
3399 const uint32_t GSYM_sym_idx = pos->second;
3400 m_nlist_idx_to_sym_idx[nlist_idx] =
3406 Address(symbol_section, symbol_value);
3407 add_symbol_addr(sym[GSYM_sym_idx]
3414 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3416 sym[sym_idx].
Clear();
3424 sym[sym_idx].
SetID(nlist_idx);
3428 Address(symbol_section, symbol_value);
3430 sym[sym_idx].GetAddress().GetFileAddress());
3432 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3434 if (demangled_is_synthesized)
3438 sym[sym_idx].
Clear();
3445 for (
const auto &pos : reexport_shlib_needs_fixup) {
3446 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3447 if (undef_pos != undefined_name_to_desc.end()) {
3448 const uint8_t dylib_ordinal =
3449 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3450 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3460 if (nlist_data.GetByteSize() > 0) {
3464 if (sym ==
nullptr) {
3466 symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3467 num_syms = symtab.GetNumSymbols();
3470 if (unmapped_local_symbols_found) {
3471 assert(m_dysymtab.ilocalsym == 0);
3472 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3473 nlist_idx = m_dysymtab.nlocalsym;
3478 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3479 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3480 UndefinedNameToDescMap undefined_name_to_desc;
3481 SymbolIndexToName reexport_shlib_needs_fixup;
3489 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3491 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3492 if (is_debug != debug_only)
3495 const char *symbol_name_non_abi_mangled =
nullptr;
3496 const char *symbol_name =
nullptr;
3498 if (have_strtab_data) {
3499 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3501 if (symbol_name ==
nullptr) {
3505 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3507 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3510 if (symbol_name[0] ==
'\0')
3511 symbol_name =
nullptr;
3513 const addr_t str_addr = strtab_addr + nlist.n_strx;
3515 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3517 symbol_name = memory_symbol_name.c_str();
3522 bool add_nlist =
true;
3523 bool is_gsym =
false;
3524 bool demangled_is_synthesized =
false;
3525 bool set_value =
true;
3527 assert(sym_idx < num_syms);
3528 sym[sym_idx].SetDebug(is_debug);
3531 switch (nlist.n_type) {
3546 sym[sym_idx].SetExternal(
true);
3549 symbol_name_non_abi_mangled, type)) {
3550 demangled_is_synthesized =
true;
3552 if (nlist.n_value != 0)
3554 section_info.GetSection(nlist.n_sect, nlist.n_value);
3570 section_info.GetSection(nlist.n_sect, nlist.n_value);
3572 N_FUN_addr_to_sym_idx.insert(
3573 std::make_pair(nlist.n_value, sym_idx));
3577 N_FUN_indexes.push_back(sym_idx);
3581 if (!N_FUN_indexes.empty()) {
3584 symtab.SymbolAtIndex(N_FUN_indexes.back())
3585 ->SetByteSize(nlist.n_value);
3586 N_FUN_indexes.pop_back();
3597 N_STSYM_addr_to_sym_idx.insert(
3598 std::make_pair(nlist.n_value, sym_idx));
3599 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3600 if (symbol_name && symbol_name[0]) {
3608 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3639 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3651 if (symbol_name ==
nullptr) {
3658 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3659 symbol_ptr->SetByteSize(sym_idx);
3660 symbol_ptr->SetSizeIsSibling(
true);
3662 N_NSYM_indexes.clear();
3663 N_INCL_indexes.clear();
3664 N_BRAC_indexes.clear();
3665 N_COMM_indexes.clear();
3666 N_FUN_indexes.clear();
3672 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3673 if (N_SO_has_full_path) {
3674 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3677 sym[sym_idx - 1].GetMangled().SetValue(
3679 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3684 N_SO_index = sym_idx;
3686 }
else if ((N_SO_index == sym_idx - 1) &&
3687 ((sym_idx - 1) < num_syms)) {
3691 llvm::StringRef so_path = sym[sym_idx - 1]
3695 if (!so_path.empty()) {
3696 std::string full_so_path(so_path);
3697 const size_t double_slash_pos = full_so_path.find(
"//");
3698 if (double_slash_pos != std::string::npos) {
3706 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3707 FileSpec::Style::native);
3710 full_so_path.erase(0, double_slash_pos + 1);
3714 if (*full_so_path.rbegin() !=
'/')
3715 full_so_path +=
'/';
3716 full_so_path += symbol_name;
3717 sym[sym_idx - 1].GetMangled().SetValue(
3720 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3724 N_SO_index = sym_idx;
3744 N_INCL_indexes.push_back(sym_idx);
3753 if (!N_INCL_indexes.empty()) {
3754 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3755 symbol_ptr->SetByteSize(sym_idx + 1);
3756 symbol_ptr->SetSizeIsSibling(
true);
3757 N_INCL_indexes.pop_back();
3792 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3801 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3802 N_BRAC_indexes.push_back(sym_idx);
3811 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3812 if (!N_BRAC_indexes.empty()) {
3813 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3814 symbol_ptr->SetByteSize(sym_idx + 1);
3815 symbol_ptr->SetSizeIsSibling(
true);
3816 N_BRAC_indexes.pop_back();
3832 N_COMM_indexes.push_back(sym_idx);
3837 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3846 if (!N_COMM_indexes.empty()) {
3847 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3848 symbol_ptr->SetByteSize(sym_idx + 1);
3849 symbol_ptr->SetSizeIsSibling(
true);
3850 N_COMM_indexes.pop_back();
3864 uint8_t n_type = N_TYPE & nlist.n_type;
3865 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3869 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3870 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3873 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3874 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3876 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3877 indirect_symbol_names.insert(
3878 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3884 if (symbol_name && symbol_name[0]) {
3886 ((symbol_name[0] ==
'_') ? 1 : 0));
3887 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3900 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3902 if (!symbol_section) {
3908 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3911 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3913 switch (section_type) {
3914 case S_CSTRING_LITERALS:
3917 case S_4BYTE_LITERALS:
3920 case S_8BYTE_LITERALS:
3923 case S_LITERAL_POINTERS:
3926 case S_NON_LAZY_SYMBOL_POINTERS:
3929 case S_LAZY_SYMBOL_POINTERS:
3932 case S_SYMBOL_STUBS:
3936 case S_MOD_INIT_FUNC_POINTERS:
3939 case S_MOD_TERM_FUNC_POINTERS:
3946 case S_16BYTE_LITERALS:
3952 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3956 switch (symbol_section->GetType()) {
3978 llvm::StringRef symbol_sect_name = symbol_section->GetName();
3979 if (symbol_section->IsDescendant(text_section_sp.get())) {
3980 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3981 S_ATTR_SELF_MODIFYING_CODE |
3982 S_ATTR_SOME_INSTRUCTIONS))
3986 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3987 symbol_section->IsDescendant(
3988 data_dirty_section_sp.get()) ||
3989 symbol_section->IsDescendant(
3990 data_const_section_sp.get())) {
3991 if (symbol_sect_name.starts_with(
"__objc")) {
3995 symbol_name, symbol_name_non_abi_mangled, type))
3996 demangled_is_synthesized =
true;
3997 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
4002 }
else if (symbol_sect_name.starts_with(
"__IMPORT")) {
4004 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4006 if (symbol_name && symbol_name[0] ==
'.') {
4007 llvm::StringRef symbol_name_ref(symbol_name);
4008 llvm::StringRef g_objc_v1_prefix_class(
4009 ".objc_class_name_");
4010 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4011 symbol_name_non_abi_mangled = symbol_name;
4012 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4014 demangled_is_synthesized =
true;
4025 sym[sym_idx].Clear();
4029 uint64_t symbol_value = nlist.n_value;
4031 if (symbol_name_non_abi_mangled) {
4032 sym[sym_idx].GetMangled().SetMangledName(
4034 sym[sym_idx].GetMangled().SetDemangledName(
ConstString(symbol_name));
4037 if (symbol_name && symbol_name[0] ==
'_') {
4043 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4048 const char *gsym_name = sym[sym_idx]
4053 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4056 if (symbol_section) {
4057 const addr_t section_file_addr = symbol_section->GetFileAddress();
4058 symbol_value -= section_file_addr;
4067 std::pair<ValueToSymbolIndexMap::const_iterator,
4068 ValueToSymbolIndexMap::const_iterator>
4070 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4071 if (range.first != range.second) {
4072 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4073 pos != range.second; ++pos) {
4075 sym[pos->second].GetMangled().GetName(
4077 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4081 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4082 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4083 if (resolver_addresses.find(nlist.n_value) !=
4084 resolver_addresses.end())
4086 sym[sym_idx].Clear();
4091 if (resolver_addresses.find(nlist.n_value) !=
4092 resolver_addresses.end())
4102 std::pair<ValueToSymbolIndexMap::const_iterator,
4103 ValueToSymbolIndexMap::const_iterator>
4105 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4106 if (range.first != range.second) {
4107 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4108 pos != range.second; ++pos) {
4110 sym[pos->second].GetMangled().GetName(
4112 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4116 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4117 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4118 sym[sym_idx].Clear();
4124 const char *gsym_name = sym[sym_idx]
4129 ConstNameToSymbolIndexMap::const_iterator pos =
4130 N_GSYM_name_to_sym_idx.find(gsym_name);
4131 if (pos != N_GSYM_name_to_sym_idx.end()) {
4132 const uint32_t GSYM_sym_idx = pos->second;
4133 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4136 sym[GSYM_sym_idx].GetAddressRef() =
4137 Address(symbol_section, symbol_value);
4139 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4143 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4144 sym[sym_idx].Clear();
4152 sym[sym_idx].SetID(nlist_idx);
4153 sym[sym_idx].SetType(type);
4155 sym[sym_idx].GetAddressRef() =
Address(symbol_section, symbol_value);
4157 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4159 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4160 if (nlist.n_desc & N_WEAK_REF)
4161 sym[sym_idx].SetIsWeak(
true);
4163 if (demangled_is_synthesized)
4164 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4172 std::vector<struct nlist_64> nlists;
4173 nlists.reserve(symtab_load_command.nsyms);
4174 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4176 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4177 nlists.push_back(*nlist);
4187 for (
auto &nlist : nlists) {
4188 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4194 for (
auto &nlist : nlists) {
4199 for (
const auto &pos : reexport_shlib_needs_fixup) {
4200 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4201 if (undef_pos != undefined_name_to_desc.end()) {
4202 const uint8_t dylib_ordinal =
4203 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4204 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4205 sym[pos.first].SetReExportedSymbolSharedLibrary(
4206 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4212 int trie_symbol_table_augment_count = 0;
4213 for (
auto &e : external_sym_trie_entries) {
4214 if (!symbols_added.contains(e.entry.address))
4215 trie_symbol_table_augment_count++;
4218 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4219 num_syms = sym_idx + trie_symbol_table_augment_count;
4220 sym = symtab.Resize(num_syms);
4222 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4225 for (
auto &e : external_sym_trie_entries) {
4226 if (symbols_added.contains(e.entry.address))
4232 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4234 const char *symbol_name = e.entry.name.GetCString();
4235 bool demangled_is_synthesized =
false;
4237 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4238 data_section_sp, data_dirty_section_sp,
4239 data_const_section_sp, symbol_section);
4241 sym[sym_idx].SetType(type);
4242 if (symbol_section) {
4243 sym[sym_idx].SetID(synthetic_sym_id++);
4244 sym[sym_idx].GetMangled().SetMangledName(
ConstString(symbol_name));
4245 if (demangled_is_synthesized)
4246 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4247 sym[sym_idx].SetIsSynthetic(
true);
4248 sym[sym_idx].SetExternal(
true);
4249 sym[sym_idx].GetAddressRef() = symbol_addr;
4258 if (function_starts_count > 0) {
4259 uint32_t num_synthetic_function_symbols = 0;
4260 for (i = 0; i < function_starts_count; ++i) {
4261 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4262 ++num_synthetic_function_symbols;
4265 if (num_synthetic_function_symbols > 0) {
4266 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4267 num_syms = sym_idx + num_synthetic_function_symbols;
4268 sym = symtab.Resize(num_syms);
4270 for (i = 0; i < function_starts_count; ++i) {
4271 const FunctionStarts::Entry *func_start_entry =
4272 function_starts.GetEntryAtIndex(i);
4273 if (!symbols_added.contains(func_start_entry->addr)) {
4274 addr_t symbol_file_addr = func_start_entry->addr;
4275 uint32_t symbol_flags = 0;
4276 if (func_start_entry->data)
4279 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4281 if (symbol_section) {
4282 sym[sym_idx].SetID(synthetic_sym_id++);
4286 sym[sym_idx].GetMangled().SetDemangledName(
ConstString());
4288 sym[sym_idx].SetIsSynthetic(
true);
4289 sym[sym_idx].GetAddressRef() = symbol_addr;
4292 sym[sym_idx].SetFlags(symbol_flags);
4303 if (sym_idx < num_syms) {
4305 sym = symtab.Resize(num_syms);
4309 if (m_dysymtab.nindirectsyms != 0) {
4310 if (indirect_symbol_index_data.GetByteSize()) {
4311 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4312 m_nlist_idx_to_sym_idx.end();
4314 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4316 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4318 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4319 if (symbol_stub_byte_size == 0)
4322 const uint32_t num_symbol_stubs =
4323 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4325 if (num_symbol_stubs == 0)
4328 const uint32_t symbol_stub_index_offset =
4329 m_mach_sections[sect_idx].reserved1;
4330 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4331 const uint32_t symbol_stub_index =
4332 symbol_stub_index_offset + stub_idx;
4334 m_mach_sections[sect_idx].addr +
4335 (stub_idx * symbol_stub_byte_size);
4337 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4338 symbol_stub_offset, 4)) {
4339 const uint32_t stub_sym_id =
4340 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4341 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4344 NListIndexToSymbolIndexMap::const_iterator index_pos =
4345 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4346 Symbol *stub_symbol =
nullptr;
4347 if (index_pos != end_index_pos) {
4350 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4354 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4358 Address so_addr(symbol_stub_addr, section_list);
4365 if (resolver_addresses.find(symbol_stub_addr) ==
4366 resolver_addresses.end())
4376 if (sym_idx >= num_syms) {
4377 sym = symtab.Resize(++num_syms);
4378 stub_symbol =
nullptr;
4380 sym[sym_idx].SetID(synthetic_sym_id++);
4381 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4382 if (resolver_addresses.find(symbol_stub_addr) ==
4383 resolver_addresses.end())
4387 sym[sym_idx].SetIsSynthetic(
true);
4388 sym[sym_idx].GetAddressRef() = so_addr;
4389 add_symbol_addr(so_addr.GetFileAddress());
4390 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4395 "warning: symbol stub referencing symbol table "
4396 "symbol %u that isn't in our minimal symbol table, "
4407 if (!reexport_trie_entries.empty()) {
4408 for (
const auto &e : reexport_trie_entries) {
4409 if (e.entry.import_name) {
4412 if (indirect_symbol_names.find(e.entry.name) ==
4413 indirect_symbol_names.end()) {
4415 if (sym_idx >= num_syms)
4416 sym = symtab.Resize(++num_syms);
4417 sym[sym_idx].SetID(synthetic_sym_id++);
4418 sym[sym_idx].GetMangled() =
Mangled(e.entry.name);
4420 sym[sym_idx].SetIsSynthetic(
true);
4421 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4422 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4423 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4424 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));