2116 llvm::StringRef file_name = file.
GetFilename().nonEmptyOr(
"<Unknown>");
2118 file_name.str().c_str());
2119 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2120 Progress progress(
"Parsing symbol table", file_name.str());
2135 llvm::DenseSet<addr_t> symbols_added;
2139 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2143 symbols_added.insert(file_addr);
2145 FunctionStarts function_starts;
2151 for (i = 0; i <
m_header.ncmds; ++i) {
2154 llvm::MachO::load_command lc;
2160 llvm::MachO::symtab_command lc_obj;
2161 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2162 lc_obj.cmd = lc.cmd;
2163 lc_obj.cmdsize = lc.cmdsize;
2164 symtab_load_command = lc_obj;
2169 case LC_DYLD_INFO_ONLY: {
2170 llvm::MachO::dyld_info_command lc_obj;
2171 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2172 lc_obj.cmd = lc.cmd;
2173 lc_obj.cmdsize = lc.cmdsize;
2179 case LC_LOAD_WEAK_DYLIB:
2180 case LC_REEXPORT_DYLIB:
2182 case LC_LOAD_UPWARD_DYLIB: {
2183 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2184 if (std::optional<llvm::StringRef> path =
2189 if (path->starts_with(
"@"))
2192 if (lc.cmd == LC_REEXPORT_DYLIB) {
2196 dylib_files.
Append(file_spec);
2200 case LC_DYLD_EXPORTS_TRIE: {
2201 llvm::MachO::linkedit_data_command lc_obj;
2202 lc_obj.cmd = lc.cmd;
2203 lc_obj.cmdsize = lc.cmdsize;
2204 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2205 exports_trie_load_command = lc_obj;
2207 case LC_FUNCTION_STARTS: {
2208 llvm::MachO::linkedit_data_command lc_obj;
2209 lc_obj.cmd = lc.cmd;
2210 lc_obj.cmdsize = lc.cmdsize;
2211 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2212 function_starts_load_command = lc_obj;
2216 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2219 image_uuid =
UUID(uuid_bytes, 16);
2226 offset = cmd_offset + lc.cmdsize;
2229 if (!symtab_load_command.
cmd)
2233 if (section_list ==
nullptr)
2236 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2238 bool bit_width_32 = addr_byte_size == 4;
2239 const size_t nlist_byte_size =
2240 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2242 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2243 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2244 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2245 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2247 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2249 const
addr_t nlist_data_byte_size =
2250 symtab_load_command.nsyms * nlist_byte_size;
2251 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2254 ProcessSP process_sp(m_process_wp.lock());
2255 Process *process = process_sp.get();
2259 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2262 section_list->FindSectionByName(GetSegmentNameTEXT()));
2264 section_list->FindSectionByName(GetSegmentNameDATA()));
2266 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2268 section_list->FindSectionByName(GetSegmentNameDATA_DIRTY()));
2270 section_list->FindSectionByName(GetSegmentNameDATA_CONST()));
2272 section_list->FindSectionByName(GetSegmentNameOBJC()));
2277 if (text_section_sp.get()) {
2278 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2279 g_section_name_eh_frame);
2280 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2281 g_section_name_lldb_no_nlist);
2283 eh_frame_section_sp =
2285 lldb_no_nlist_section_sp =
2289 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2290 !is_local_shared_cache_image) {
2291 Target &target = process->GetTarget();
2300 if (lldb_no_nlist_section_sp)
2305 if (linkedit_section_sp) {
2306 addr_t linkedit_load_addr =
2307 linkedit_section_sp->GetLoadBaseAddress(&target);
2317 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2318 const addr_t symoff_addr = linkedit_load_addr +
2319 symtab_load_command.
symoff -
2320 linkedit_file_offset;
2321 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2322 linkedit_file_offset;
2330 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2332 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2334 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2336 const addr_t indirect_syms_addr = linkedit_load_addr +
2338 linkedit_file_offset;
2340 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2341 if (indirect_syms_data_sp)
2342 indirect_symbol_index_data.SetData(
2343 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2353 if (!is_shared_cache_image) {
2355 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2356 if (strtab_data_sp) {
2357 strtab_data.SetData(strtab_data_sp, 0,
2358 strtab_data_sp->GetByteSize());
2363 if (function_starts_load_command.
cmd) {
2364 const addr_t func_start_addr =
2365 linkedit_load_addr + function_starts_load_command.
dataoff -
2366 linkedit_file_offset;
2369 function_starts_load_command.
datasize));
2370 if (func_start_data_sp)
2371 function_starts_data.SetData(func_start_data_sp, 0,
2372 func_start_data_sp->GetByteSize());
2378 if (is_local_shared_cache_image && linkedit_section_sp) {
2386 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2389 symtab_load_command.
symoff += linkedit_slide;
2390 symtab_load_command.
stroff += linkedit_slide;
2393 function_starts_load_command.
dataoff += linkedit_slide;
2394 exports_trie_load_command.
dataoff += linkedit_slide;
2398 nlist_data_byte_size);
2399 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2400 strtab_data_byte_size);
2405 && (exports_trie_load_command.
datasize > 0)));
2409 }
else if (exports_trie_load_command.
datasize > 0) {
2412 exports_trie_load_command.
datasize);
2416 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2419 if (function_starts_load_command.
cmd) {
2420 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2421 function_starts_load_command.
dataoff,
2422 function_starts_load_command.
datasize);
2426 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2428 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2445 if (text_section_sp && function_starts_data.GetByteSize()) {
2446 FunctionStarts::Entry function_start_entry;
2447 function_start_entry.data =
false;
2449 function_start_entry.addr = text_section_sp->GetFileAddress();
2451 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2454 function_start_entry.addr += delta;
2456 if (function_start_entry.addr & 1) {
2458 function_start_entry.data =
true;
2459 }
else if (always_thumb) {
2460 function_start_entry.data =
true;
2463 function_starts.Append(function_start_entry);
2471 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2477 addr_t text_base_addr = text_section_sp->GetFileAddress();
2478 size_t count = functions.
GetSize();
2479 for (
size_t i = 0; i < count; ++i) {
2483 FunctionStarts::Entry function_start_entry;
2484 function_start_entry.addr = func->
base - text_base_addr;
2486 if (function_start_entry.addr & 1) {
2488 function_start_entry.data =
true;
2489 }
else if (always_thumb) {
2490 function_start_entry.data =
true;
2493 function_starts.Append(function_start_entry);
2499 const size_t function_starts_count = function_starts.GetSize();
2514 if (unwind_or_symbol_log)
2515 module_sp->LogMessage(
2516 unwind_or_symbol_log,
2517 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2520 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2521 ? eh_frame_section_sp->GetID()
2527 std::vector<uint32_t> N_FUN_indexes;
2528 std::vector<uint32_t> N_NSYM_indexes;
2529 std::vector<uint32_t> N_INCL_indexes;
2530 std::vector<uint32_t> N_BRAC_indexes;
2531 std::vector<uint32_t> N_COMM_indexes;
2532 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2533 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2534 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2535 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2536 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2537 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2540 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2541 uint32_t nlist_idx = 0;
2542 Symbol *symbol_ptr =
nullptr;
2544 uint32_t sym_idx = 0;
2546 size_t num_syms = 0;
2547 std::string memory_symbol_name;
2548 uint32_t unmapped_local_symbols_found = 0;
2550 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2551 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2552 std::set<lldb::addr_t> resolver_addresses;
2554 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2555 if (dyld_trie_data_size > 0) {
2556 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2560 if (text_segment_sp)
2561 text_segment_file_addr = text_segment_sp->GetFileAddress();
2563 resolver_addresses, reexport_trie_entries,
2564 external_sym_trie_entries);
2567 typedef std::set<ConstString> IndirectSymbols;
2568 IndirectSymbols indirect_symbol_names;
2591 UUID process_shared_cache_uuid;
2592 addr_t process_shared_cache_base_addr;
2596 process_shared_cache_uuid);
2599 __block
bool found_image =
false;
2600 __block
void *nlist_buffer =
nullptr;
2601 __block
unsigned nlist_count = 0;
2602 __block
char *string_table =
nullptr;
2603 __block vm_offset_t vm_nlist_memory = 0;
2604 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2605 __block vm_offset_t vm_string_memory = 0;
2606 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2608 llvm::scope_exit _(^{
2609 if (vm_nlist_memory)
2610 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2611 if (vm_string_memory)
2612 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2615 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2616 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2617 UndefinedNameToDescMap undefined_name_to_desc;
2618 SymbolIndexToName reexport_shlib_needs_fixup;
2626 if (process_shared_cache_uuid.
IsValid() &&
2627 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2636 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2643 dyld_image_local_nlist_content_4Symbolication(
2644 image, ^(
const void *nlistStart, uint64_t nlistCount,
2645 const char *stringTable) {
2646 if (!nlistStart || !nlistCount)
2654 nlist_byte_size * nlistCount, &vm_nlist_memory,
2655 &vm_nlist_bytes_read);
2658 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2663 vm_address_t string_address = (vm_address_t)stringTable;
2664 vm_size_t region_size;
2665 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2666 vm_region_basic_info_data_t info;
2667 memory_object_name_t object;
2669 ®ion_size, VM_REGION_BASIC_INFO_64,
2670 (vm_region_info_t)&info, &info_count, &
object);
2676 ((vm_address_t)stringTable - string_address),
2677 &vm_string_memory, &vm_string_bytes_read);
2681 nlist_buffer = (
void *)vm_nlist_memory;
2682 string_table = (
char *)vm_string_memory;
2683 nlist_count = nlistCount;
2689 nlist_count * nlist_byte_size,
2690 byte_order, addr_byte_size);
2691 DataExtractor dsc_string_table_data(string_table, vm_string_bytes_read,
2692 byte_order, addr_byte_size);
2693 unmapped_local_symbols_found = nlist_count;
2699 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2704 for (uint32_t nlist_index = 0;
2705 nlist_index < nlist_count;
2709 std::optional<struct nlist_64> nlist_maybe =
2710 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2714 struct nlist_64 nlist = *nlist_maybe;
2717 const char *symbol_name = NULL;
2718 std::optional<llvm::StringRef> name =
2719 dsc_string_table_data.
PeekCStr(nlist.n_strx);
2726 "DSC unmapped local symbol[{0}] has invalid or "
2727 "unterminated string table offset {1:x} in {2}, "
2729 nlist_index, nlist.n_strx,
2730 module_sp->GetFileSpec().GetPath()));
2735 symbol_name = name->data();
2737 const char *symbol_name_non_abi_mangled = NULL;
2740 bool add_nlist =
true;
2741 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2742 bool demangled_is_synthesized =
false;
2743 bool is_gsym =
false;
2744 bool set_value =
true;
2746 assert(sym_idx < num_syms);
2751 switch (nlist.n_type) {
2771 symbol_name, symbol_name_non_abi_mangled,
2773 demangled_is_synthesized =
true;
2775 if (nlist.n_value != 0)
2777 nlist.n_sect, nlist.n_value);
2793 nlist.n_sect, nlist.n_value);
2795 N_FUN_addr_to_sym_idx.insert(
2796 std::make_pair(nlist.n_value, sym_idx));
2800 N_FUN_indexes.push_back(sym_idx);
2804 if (!N_FUN_indexes.empty()) {
2811 N_FUN_indexes.pop_back();
2823 N_STSYM_addr_to_sym_idx.insert(
2824 std::make_pair(nlist.n_value, sym_idx));
2825 symbol_section = section_info.
GetSection(nlist.n_sect,
2827 if (symbol_name && symbol_name[0]) {
2835 symbol_section = section_info.
GetSection(nlist.n_sect,
2869 symbol_section = section_info.
GetSection(nlist.n_sect,
2882 if (symbol_name == NULL) {
2893 N_NSYM_indexes.clear();
2894 N_INCL_indexes.clear();
2895 N_BRAC_indexes.clear();
2896 N_COMM_indexes.clear();
2897 N_FUN_indexes.clear();
2903 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2904 if (N_SO_has_full_path) {
2905 if ((N_SO_index == sym_idx - 1) &&
2906 ((sym_idx - 1) < num_syms)) {
2912 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2918 N_SO_index = sym_idx;
2920 }
else if ((N_SO_index == sym_idx - 1) &&
2921 ((sym_idx - 1) < num_syms)) {
2926 const char *so_path = sym[sym_idx - 1]
2930 if (so_path && so_path[0]) {
2931 std::string full_so_path(so_path);
2932 const size_t double_slash_pos =
2933 full_so_path.find(
"//");
2934 if (double_slash_pos != std::string::npos) {
2945 &full_so_path[double_slash_pos + 1],
2946 FileSpec::Style::native);
2949 full_so_path.erase(0, double_slash_pos + 1);
2953 if (*full_so_path.rbegin() !=
'/')
2954 full_so_path +=
'/';
2955 full_so_path += symbol_name;
2959 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2963 N_SO_index = sym_idx;
2984 N_INCL_indexes.push_back(sym_idx);
2994 if (!N_INCL_indexes.empty()) {
2999 N_INCL_indexes.pop_back();
3034 symbol_section = section_info.
GetSection(nlist.n_sect,
3045 symbol_section = section_info.
GetSection(nlist.n_sect,
3047 N_BRAC_indexes.push_back(sym_idx);
3057 symbol_section = section_info.
GetSection(nlist.n_sect,
3059 if (!N_BRAC_indexes.empty()) {
3064 N_BRAC_indexes.pop_back();
3081 N_COMM_indexes.push_back(sym_idx);
3086 symbol_section = section_info.
GetSection(nlist.n_sect,
3097 if (!N_COMM_indexes.empty()) {
3102 N_COMM_indexes.pop_back();
3117 uint8_t n_type = N_TYPE & nlist.n_type;
3118 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3122 std::optional<llvm::StringRef> reexport_name_str =
3123 strtab_data.PeekCStr(nlist.n_value);
3124 if (reexport_name_str && !reexport_name_str->empty()) {
3127 reexport_name_str->drop_front(
3128 reexport_name_str->front() ==
'_' ? 1 : 0));
3131 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3133 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3139 if (symbol_name && symbol_name[0]) {
3141 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3142 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3154 symbol_section = section_info.
GetSection(nlist.n_sect,
3157 if (symbol_section == NULL) {
3163 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3166 uint32_t section_type =
3167 symbol_section->Get() & SECTION_TYPE;
3169 switch (section_type) {
3170 case S_CSTRING_LITERALS:
3173 case S_4BYTE_LITERALS:
3176 case S_8BYTE_LITERALS:
3179 case S_LITERAL_POINTERS:
3182 case S_NON_LAZY_SYMBOL_POINTERS:
3186 case S_LAZY_SYMBOL_POINTERS:
3189 case S_SYMBOL_STUBS:
3193 case S_MOD_INIT_FUNC_POINTERS:
3197 case S_MOD_TERM_FUNC_POINTERS:
3205 case S_16BYTE_LITERALS:
3211 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3215 switch (symbol_section->GetType()) {
3242 llvm::StringRef symbol_sect_name =
3243 symbol_section->GetName();
3244 if (symbol_section->IsDescendant(
3245 text_section_sp.get())) {
3246 if (symbol_section->IsClear(
3247 S_ATTR_PURE_INSTRUCTIONS |
3248 S_ATTR_SELF_MODIFYING_CODE |
3249 S_ATTR_SOME_INSTRUCTIONS))
3253 }
else if (symbol_section->IsDescendant(
3254 data_section_sp.get()) ||
3255 symbol_section->IsDescendant(
3256 data_dirty_section_sp.get()) ||
3257 symbol_section->IsDescendant(
3258 data_const_section_sp.get())) {
3259 if (symbol_sect_name.starts_with(
"__objc")) {
3264 symbol_name_non_abi_mangled, type))
3265 demangled_is_synthesized =
true;
3266 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
3271 }
else if (symbol_sect_name.starts_with(
"__IMPORT"))
3273 }
else if (symbol_section->IsDescendant(
3274 objc_section_sp.get())) {
3276 if (symbol_name && symbol_name[0] ==
'.') {
3277 llvm::StringRef symbol_name_ref(symbol_name);
3279 g_objc_v1_prefix_class(
".objc_class_name_");
3280 if (symbol_name_ref.starts_with(
3281 g_objc_v1_prefix_class)) {
3282 symbol_name_non_abi_mangled = symbol_name;
3283 symbol_name = symbol_name +
3284 g_objc_v1_prefix_class.size();
3286 demangled_is_synthesized =
true;
3297 uint64_t symbol_value = nlist.n_value;
3298 if (symbol_name_non_abi_mangled) {
3304 if (symbol_name && symbol_name[0] ==
'_') {
3311 if (is_gsym && is_debug) {
3312 const char *gsym_name =
3318 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3322 if (symbol_section) {
3323 const addr_t section_file_addr =
3324 symbol_section->GetFileAddress();
3325 symbol_value -= section_file_addr;
3328 if (is_debug ==
false) {
3336 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3337 if (range.first != range.second) {
3338 bool found_it =
false;
3339 for (
auto pos = range.first; pos != range.second;
3341 if (sym[sym_idx].GetMangled().
GetName(
3345 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3351 sym[sym_idx].IsExternal());
3352 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3354 if (resolver_addresses.find(nlist.n_value) !=
3355 resolver_addresses.end())
3357 sym[sym_idx].
Clear();
3365 if (resolver_addresses.find(nlist.n_value) !=
3366 resolver_addresses.end())
3378 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3380 if (range.first != range.second) {
3381 bool found_it =
false;
3382 for (
auto pos = range.first; pos != range.second;
3384 if (sym[sym_idx].GetMangled().
GetName(
3388 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3394 sym[sym_idx].IsExternal());
3395 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3397 sym[sym_idx].
Clear();
3405 const char *gsym_name =
3413 ConstNameToSymbolIndexMap::const_iterator pos =
3414 N_GSYM_name_to_sym_idx.find(gsym_name);
3415 if (pos != N_GSYM_name_to_sym_idx.end()) {
3416 const uint32_t GSYM_sym_idx = pos->second;
3417 m_nlist_idx_to_sym_idx[nlist_idx] =
3423 Address(symbol_section, symbol_value);
3424 add_symbol_addr(sym[GSYM_sym_idx]
3431 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3433 sym[sym_idx].
Clear();
3441 sym[sym_idx].
SetID(nlist_idx);
3445 Address(symbol_section, symbol_value);
3447 sym[sym_idx].GetAddress().GetFileAddress());
3449 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3451 if (demangled_is_synthesized)
3455 sym[sym_idx].
Clear();
3462 for (
const auto &pos : reexport_shlib_needs_fixup) {
3463 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3464 if (undef_pos != undefined_name_to_desc.end()) {
3465 const uint8_t dylib_ordinal =
3466 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3467 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3477 if (nlist_data.GetByteSize() > 0) {
3479 const uint64_t max_nsyms = nlist_data.GetByteSize() / nlist_byte_size;
3480 const uint64_t max_nindirectsyms =
3481 indirect_symbol_index_data.GetByteSize() /
sizeof(uint32_t);
3485 if (sym ==
nullptr) {
3486 sym = symtab.Resize(
3487 std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms) +
3488 std::min<uint64_t>(m_dysymtab.nindirectsyms, max_nindirectsyms));
3489 num_syms = symtab.GetNumSymbols();
3492 if (unmapped_local_symbols_found) {
3493 assert(m_dysymtab.ilocalsym == 0);
3494 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3495 nlist_idx = m_dysymtab.nlocalsym;
3500 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3501 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3502 UndefinedNameToDescMap undefined_name_to_desc;
3503 SymbolIndexToName reexport_shlib_needs_fixup;
3511 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3513 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3514 if (is_debug != debug_only)
3517 const char *symbol_name_non_abi_mangled =
nullptr;
3518 const char *symbol_name =
nullptr;
3520 if (have_strtab_data) {
3521 std::optional<llvm::StringRef> name =
3522 strtab_data.PeekCStr(nlist.n_strx);
3528 "symbol[{0}] has invalid or unterminated string table offset "
3529 "{1:x} in {2}, ignoring symbol",
3530 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3535 symbol_name = name->data();
3537 const addr_t str_addr = strtab_addr + nlist.n_strx;
3539 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3541 symbol_name = memory_symbol_name.c_str();
3546 bool add_nlist =
true;
3547 bool is_gsym =
false;
3548 bool demangled_is_synthesized =
false;
3549 bool set_value =
true;
3551 assert(sym_idx < num_syms);
3552 sym[sym_idx].SetDebug(is_debug);
3555 switch (nlist.n_type) {
3570 sym[sym_idx].SetExternal(
true);
3573 symbol_name_non_abi_mangled, type)) {
3574 demangled_is_synthesized =
true;
3576 if (nlist.n_value != 0)
3578 section_info.GetSection(nlist.n_sect, nlist.n_value);
3594 section_info.GetSection(nlist.n_sect, nlist.n_value);
3596 N_FUN_addr_to_sym_idx.insert(
3597 std::make_pair(nlist.n_value, sym_idx));
3601 N_FUN_indexes.push_back(sym_idx);
3605 if (!N_FUN_indexes.empty()) {
3608 symtab.SymbolAtIndex(N_FUN_indexes.back())
3609 ->SetByteSize(nlist.n_value);
3610 N_FUN_indexes.pop_back();
3621 N_STSYM_addr_to_sym_idx.insert(
3622 std::make_pair(nlist.n_value, sym_idx));
3623 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3624 if (symbol_name && symbol_name[0]) {
3632 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3663 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3675 if (symbol_name ==
nullptr) {
3682 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3683 symbol_ptr->SetByteSize(sym_idx);
3684 symbol_ptr->SetSizeIsSibling(
true);
3686 N_NSYM_indexes.clear();
3687 N_INCL_indexes.clear();
3688 N_BRAC_indexes.clear();
3689 N_COMM_indexes.clear();
3690 N_FUN_indexes.clear();
3696 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3697 if (N_SO_has_full_path) {
3698 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3701 sym[sym_idx - 1].GetMangled().SetValue(
3703 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3708 N_SO_index = sym_idx;
3710 }
else if ((N_SO_index == sym_idx - 1) &&
3711 ((sym_idx - 1) < num_syms)) {
3715 llvm::StringRef so_path = sym[sym_idx - 1]
3719 if (!so_path.empty()) {
3720 std::string full_so_path(so_path);
3721 const size_t double_slash_pos = full_so_path.find(
"//");
3722 if (double_slash_pos != std::string::npos) {
3730 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3731 FileSpec::Style::native);
3734 full_so_path.erase(0, double_slash_pos + 1);
3738 if (*full_so_path.rbegin() !=
'/')
3739 full_so_path +=
'/';
3740 full_so_path += symbol_name;
3741 sym[sym_idx - 1].GetMangled().SetValue(
3744 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3748 N_SO_index = sym_idx;
3768 N_INCL_indexes.push_back(sym_idx);
3777 if (!N_INCL_indexes.empty()) {
3778 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3779 symbol_ptr->SetByteSize(sym_idx + 1);
3780 symbol_ptr->SetSizeIsSibling(
true);
3781 N_INCL_indexes.pop_back();
3816 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3825 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3826 N_BRAC_indexes.push_back(sym_idx);
3835 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3836 if (!N_BRAC_indexes.empty()) {
3837 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3838 symbol_ptr->SetByteSize(sym_idx + 1);
3839 symbol_ptr->SetSizeIsSibling(
true);
3840 N_BRAC_indexes.pop_back();
3856 N_COMM_indexes.push_back(sym_idx);
3861 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3870 if (!N_COMM_indexes.empty()) {
3871 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3872 symbol_ptr->SetByteSize(sym_idx + 1);
3873 symbol_ptr->SetSizeIsSibling(
true);
3874 N_COMM_indexes.pop_back();
3888 uint8_t n_type = N_TYPE & nlist.n_type;
3889 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3893 std::optional<llvm::StringRef> reexport_name_str =
3894 strtab_data.PeekCStr(nlist.n_value);
3895 if (reexport_name_str && !reexport_name_str->empty() && symbol_name) {
3897 ConstString reexport_name(reexport_name_str->drop_front(
3898 reexport_name_str->front() ==
'_' ? 1 : 0));
3899 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3901 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3902 indirect_symbol_names.insert(
3903 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3909 if (symbol_name && symbol_name[0]) {
3911 ((symbol_name[0] ==
'_') ? 1 : 0));
3912 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3925 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3927 if (!symbol_section) {
3933 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3936 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3938 switch (section_type) {
3939 case S_CSTRING_LITERALS:
3942 case S_4BYTE_LITERALS:
3945 case S_8BYTE_LITERALS:
3948 case S_LITERAL_POINTERS:
3951 case S_NON_LAZY_SYMBOL_POINTERS:
3954 case S_LAZY_SYMBOL_POINTERS:
3957 case S_SYMBOL_STUBS:
3961 case S_MOD_INIT_FUNC_POINTERS:
3964 case S_MOD_TERM_FUNC_POINTERS:
3971 case S_16BYTE_LITERALS:
3977 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3981 switch (symbol_section->GetType()) {
4003 llvm::StringRef symbol_sect_name = symbol_section->GetName();
4004 if (symbol_section->IsDescendant(text_section_sp.get())) {
4005 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4006 S_ATTR_SELF_MODIFYING_CODE |
4007 S_ATTR_SOME_INSTRUCTIONS))
4011 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4012 symbol_section->IsDescendant(
4013 data_dirty_section_sp.get()) ||
4014 symbol_section->IsDescendant(
4015 data_const_section_sp.get())) {
4016 if (symbol_sect_name.starts_with(
"__objc")) {
4020 symbol_name, symbol_name_non_abi_mangled, type))
4021 demangled_is_synthesized =
true;
4022 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
4027 }
else if (symbol_sect_name.starts_with(
"__IMPORT")) {
4029 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4031 if (symbol_name && symbol_name[0] ==
'.') {
4032 llvm::StringRef symbol_name_ref(symbol_name);
4033 llvm::StringRef g_objc_v1_prefix_class(
4034 ".objc_class_name_");
4035 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4036 symbol_name_non_abi_mangled = symbol_name;
4037 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4039 demangled_is_synthesized =
true;
4050 sym[sym_idx].Clear();
4054 uint64_t symbol_value = nlist.n_value;
4056 if (symbol_name_non_abi_mangled) {
4057 sym[sym_idx].GetMangled().SetMangledName(
4059 sym[sym_idx].GetMangled().SetDemangledName(
ConstString(symbol_name));
4062 if (symbol_name && symbol_name[0] ==
'_') {
4068 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4073 const char *gsym_name = sym[sym_idx]
4078 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4081 if (symbol_section) {
4082 const addr_t section_file_addr = symbol_section->GetFileAddress();
4083 symbol_value -= section_file_addr;
4092 std::pair<ValueToSymbolIndexMap::const_iterator,
4093 ValueToSymbolIndexMap::const_iterator>
4095 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4096 if (range.first != range.second) {
4097 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4098 pos != range.second; ++pos) {
4100 sym[pos->second].GetMangled().GetName(
4102 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4106 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4107 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4108 if (resolver_addresses.find(nlist.n_value) !=
4109 resolver_addresses.end())
4111 sym[sym_idx].Clear();
4116 if (resolver_addresses.find(nlist.n_value) !=
4117 resolver_addresses.end())
4127 std::pair<ValueToSymbolIndexMap::const_iterator,
4128 ValueToSymbolIndexMap::const_iterator>
4130 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4131 if (range.first != range.second) {
4132 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4133 pos != range.second; ++pos) {
4135 sym[pos->second].GetMangled().GetName(
4137 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4141 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4142 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4143 sym[sym_idx].Clear();
4149 const char *gsym_name = sym[sym_idx]
4154 ConstNameToSymbolIndexMap::const_iterator pos =
4155 N_GSYM_name_to_sym_idx.find(gsym_name);
4156 if (pos != N_GSYM_name_to_sym_idx.end()) {
4157 const uint32_t GSYM_sym_idx = pos->second;
4158 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4161 sym[GSYM_sym_idx].GetAddressRef() =
4162 Address(symbol_section, symbol_value);
4164 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4168 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4169 sym[sym_idx].Clear();
4177 sym[sym_idx].SetID(nlist_idx);
4178 sym[sym_idx].SetType(type);
4180 sym[sym_idx].GetAddressRef() =
Address(symbol_section, symbol_value);
4182 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4184 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4185 if (nlist.n_desc & N_WEAK_REF)
4186 sym[sym_idx].SetIsWeak(
true);
4188 if (demangled_is_synthesized)
4189 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4197 std::vector<struct nlist_64> nlists;
4198 nlists.reserve(std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms));
4199 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4201 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4202 nlists.push_back(*nlist);
4212 for (
auto &nlist : nlists) {
4213 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4219 for (
auto &nlist : nlists) {
4224 for (
const auto &pos : reexport_shlib_needs_fixup) {
4225 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4226 if (undef_pos != undefined_name_to_desc.end()) {
4227 const uint8_t dylib_ordinal =
4228 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4229 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4230 sym[pos.first].SetReExportedSymbolSharedLibrary(
4231 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4237 int trie_symbol_table_augment_count = 0;
4238 for (
auto &e : external_sym_trie_entries) {
4239 if (!symbols_added.contains(e.entry.address))
4240 trie_symbol_table_augment_count++;
4243 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4244 num_syms = sym_idx + trie_symbol_table_augment_count;
4245 sym = symtab.Resize(num_syms);
4247 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4250 for (
auto &e : external_sym_trie_entries) {
4251 if (symbols_added.contains(e.entry.address))
4257 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4259 const char *symbol_name = e.entry.name.GetCString();
4260 bool demangled_is_synthesized =
false;
4262 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4263 data_section_sp, data_dirty_section_sp,
4264 data_const_section_sp, symbol_section);
4266 sym[sym_idx].SetType(type);
4267 if (symbol_section) {
4268 sym[sym_idx].SetID(synthetic_sym_id++);
4269 sym[sym_idx].GetMangled().SetMangledName(
ConstString(symbol_name));
4270 if (demangled_is_synthesized)
4271 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4272 sym[sym_idx].SetIsSynthetic(
true);
4273 sym[sym_idx].SetExternal(
true);
4274 sym[sym_idx].GetAddressRef() = symbol_addr;
4283 if (function_starts_count > 0) {
4284 uint32_t num_synthetic_function_symbols = 0;
4285 for (i = 0; i < function_starts_count; ++i) {
4286 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4287 ++num_synthetic_function_symbols;
4290 if (num_synthetic_function_symbols > 0) {
4291 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4292 num_syms = sym_idx + num_synthetic_function_symbols;
4293 sym = symtab.Resize(num_syms);
4295 for (i = 0; i < function_starts_count; ++i) {
4296 const FunctionStarts::Entry *func_start_entry =
4297 function_starts.GetEntryAtIndex(i);
4298 if (!symbols_added.contains(func_start_entry->addr)) {
4299 addr_t symbol_file_addr = func_start_entry->addr;
4300 uint32_t symbol_flags = 0;
4301 if (func_start_entry->data)
4304 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4306 if (symbol_section) {
4307 sym[sym_idx].SetID(synthetic_sym_id++);
4311 sym[sym_idx].GetMangled().SetDemangledName(
ConstString());
4313 sym[sym_idx].SetIsSynthetic(
true);
4314 sym[sym_idx].GetAddressRef() = symbol_addr;
4317 sym[sym_idx].SetFlags(symbol_flags);
4328 if (sym_idx < num_syms) {
4330 sym = symtab.Resize(num_syms);
4334 if (m_dysymtab.nindirectsyms != 0) {
4335 if (indirect_symbol_index_data.GetByteSize()) {
4336 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4337 m_nlist_idx_to_sym_idx.end();
4339 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4341 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4343 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4344 if (symbol_stub_byte_size == 0)
4347 const uint32_t num_symbol_stubs =
4348 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4350 if (num_symbol_stubs == 0)
4353 const uint32_t symbol_stub_index_offset =
4354 m_mach_sections[sect_idx].reserved1;
4355 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4356 const uint32_t symbol_stub_index =
4357 symbol_stub_index_offset + stub_idx;
4359 m_mach_sections[sect_idx].addr +
4360 (stub_idx * symbol_stub_byte_size);
4362 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4363 symbol_stub_offset, 4)) {
4364 const uint32_t stub_sym_id =
4365 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4366 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4369 NListIndexToSymbolIndexMap::const_iterator index_pos =
4370 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4371 Symbol *stub_symbol =
nullptr;
4372 if (index_pos != end_index_pos) {
4375 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4379 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4383 Address so_addr(symbol_stub_addr, section_list);
4390 if (resolver_addresses.find(symbol_stub_addr) ==
4391 resolver_addresses.end())
4401 if (sym_idx >= num_syms) {
4402 sym = symtab.Resize(++num_syms);
4403 stub_symbol =
nullptr;
4405 sym[sym_idx].SetID(synthetic_sym_id++);
4406 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4407 if (resolver_addresses.find(symbol_stub_addr) ==
4408 resolver_addresses.end())
4412 sym[sym_idx].SetIsSynthetic(
true);
4413 sym[sym_idx].GetAddressRef() = so_addr;
4414 add_symbol_addr(so_addr.GetFileAddress());
4415 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4420 "warning: symbol stub referencing symbol table "
4421 "symbol %u that isn't in our minimal symbol table, "
4432 if (!reexport_trie_entries.empty()) {
4433 for (
const auto &e : reexport_trie_entries) {
4434 if (e.entry.import_name) {
4437 if (indirect_symbol_names.find(e.entry.name) ==
4438 indirect_symbol_names.end()) {
4440 if (sym_idx >= num_syms)
4441 sym = symtab.Resize(++num_syms);
4442 sym[sym_idx].SetID(synthetic_sym_id++);
4443 sym[sym_idx].GetMangled() =
Mangled(e.entry.name);
4445 sym[sym_idx].SetIsSynthetic(
true);
4446 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4447 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4448 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4449 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));