2213 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2214 Progress progress(
"Parsing symbol table", file_name);
2229 llvm::DenseSet<addr_t> symbols_added;
2233 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2237 symbols_added.insert(file_addr);
2239 FunctionStarts function_starts;
2245 for (i = 0; i <
m_header.ncmds; ++i) {
2248 llvm::MachO::load_command lc;
2249 if (
m_data_nsp->GetU32(&offset, &lc, 2) ==
nullptr)
2254 llvm::MachO::symtab_command lc_obj;
2255 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2256 lc_obj.cmd = lc.cmd;
2257 lc_obj.cmdsize = lc.cmdsize;
2258 symtab_load_command = lc_obj;
2263 case LC_DYLD_INFO_ONLY: {
2264 llvm::MachO::dyld_info_command lc_obj;
2265 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2266 lc_obj.cmd = lc.cmd;
2267 lc_obj.cmdsize = lc.cmdsize;
2273 case LC_LOAD_WEAK_DYLIB:
2274 case LC_REEXPORT_DYLIB:
2276 case LC_LOAD_UPWARD_DYLIB: {
2277 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2278 const char *path =
m_data_nsp->PeekCStr(name_offset);
2286 if (lc.cmd == LC_REEXPORT_DYLIB) {
2290 dylib_files.
Append(file_spec);
2294 case LC_DYLD_EXPORTS_TRIE: {
2295 llvm::MachO::linkedit_data_command lc_obj;
2296 lc_obj.cmd = lc.cmd;
2297 lc_obj.cmdsize = lc.cmdsize;
2298 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2299 exports_trie_load_command = lc_obj;
2301 case LC_FUNCTION_STARTS: {
2302 llvm::MachO::linkedit_data_command lc_obj;
2303 lc_obj.cmd = lc.cmd;
2304 lc_obj.cmdsize = lc.cmdsize;
2305 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2306 function_starts_load_command = lc_obj;
2310 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2313 image_uuid =
UUID(uuid_bytes, 16);
2320 offset = cmd_offset + lc.cmdsize;
2323 if (!symtab_load_command.
cmd)
2327 if (section_list ==
nullptr)
2330 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2332 bool bit_width_32 = addr_byte_size == 4;
2333 const size_t nlist_byte_size =
2334 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2336 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2337 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2338 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2339 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2341 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2343 const
addr_t nlist_data_byte_size =
2344 symtab_load_command.nsyms * nlist_byte_size;
2345 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2348 ProcessSP process_sp(m_process_wp.lock());
2349 Process *process = process_sp.get();
2353 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2363 section_list->FindSectionByName(g_segment_name_TEXT));
2365 section_list->FindSectionByName(g_segment_name_DATA));
2367 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2369 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2371 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2373 section_list->FindSectionByName(g_segment_name_OBJC));
2376 if (text_section_sp.get()) {
2377 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2378 g_section_name_eh_frame);
2379 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2380 g_section_name_lldb_no_nlist);
2382 eh_frame_section_sp =
2384 lldb_no_nlist_section_sp =
2388 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2389 !is_local_shared_cache_image) {
2390 Target &target = process->GetTarget();
2399 if (lldb_no_nlist_section_sp)
2404 if (linkedit_section_sp) {
2405 addr_t linkedit_load_addr =
2406 linkedit_section_sp->GetLoadBaseAddress(&target);
2416 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2417 const addr_t symoff_addr = linkedit_load_addr +
2418 symtab_load_command.
symoff -
2419 linkedit_file_offset;
2420 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2421 linkedit_file_offset;
2429 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2431 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2433 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2435 const addr_t indirect_syms_addr = linkedit_load_addr +
2437 linkedit_file_offset;
2439 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2440 if (indirect_syms_data_sp)
2441 indirect_symbol_index_data.SetData(
2442 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2452 if (!is_shared_cache_image) {
2454 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2455 if (strtab_data_sp) {
2456 strtab_data.SetData(strtab_data_sp, 0,
2457 strtab_data_sp->GetByteSize());
2462 if (function_starts_load_command.
cmd) {
2463 const addr_t func_start_addr =
2464 linkedit_load_addr + function_starts_load_command.
dataoff -
2465 linkedit_file_offset;
2468 function_starts_load_command.
datasize));
2469 if (func_start_data_sp)
2470 function_starts_data.SetData(func_start_data_sp, 0,
2471 func_start_data_sp->GetByteSize());
2477 if (is_local_shared_cache_image) {
2485 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2488 symtab_load_command.
symoff += linkedit_slide;
2489 symtab_load_command.
stroff += linkedit_slide;
2492 function_starts_load_command.
dataoff += linkedit_slide;
2493 exports_trie_load_command.
dataoff += linkedit_slide;
2497 nlist_data_byte_size);
2499 strtab_data_byte_size);
2504 && (exports_trie_load_command.
datasize > 0)));
2508 }
else if (exports_trie_load_command.
datasize > 0) {
2510 exports_trie_load_command.
dataoff,
2511 exports_trie_load_command.
datasize);
2515 indirect_symbol_index_data.SetData(*
m_data_nsp.get(),
2519 if (function_starts_load_command.
cmd) {
2520 function_starts_data.SetData(*
m_data_nsp.get(),
2521 function_starts_load_command.
dataoff,
2522 function_starts_load_command.
datasize);
2526 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2528 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2545 if (text_section_sp && function_starts_data.GetByteSize()) {
2546 FunctionStarts::Entry function_start_entry;
2547 function_start_entry.data =
false;
2549 function_start_entry.addr = text_section_sp->GetFileAddress();
2551 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2554 function_start_entry.addr += delta;
2556 if (function_start_entry.addr & 1) {
2558 function_start_entry.data =
true;
2559 }
else if (always_thumb) {
2560 function_start_entry.data =
true;
2563 function_starts.Append(function_start_entry);
2571 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2577 addr_t text_base_addr = text_section_sp->GetFileAddress();
2578 size_t count = functions.
GetSize();
2579 for (
size_t i = 0; i < count; ++i) {
2583 FunctionStarts::Entry function_start_entry;
2584 function_start_entry.addr = func->
base - text_base_addr;
2586 if (function_start_entry.addr & 1) {
2588 function_start_entry.data =
true;
2589 }
else if (always_thumb) {
2590 function_start_entry.data =
true;
2593 function_starts.Append(function_start_entry);
2599 const size_t function_starts_count = function_starts.GetSize();
2614 if (unwind_or_symbol_log)
2615 module_sp->LogMessage(
2616 unwind_or_symbol_log,
2617 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2620 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2621 ? eh_frame_section_sp->GetID()
2627 std::vector<uint32_t> N_FUN_indexes;
2628 std::vector<uint32_t> N_NSYM_indexes;
2629 std::vector<uint32_t> N_INCL_indexes;
2630 std::vector<uint32_t> N_BRAC_indexes;
2631 std::vector<uint32_t> N_COMM_indexes;
2632 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2633 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2634 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2635 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2636 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2637 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2640 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2641 uint32_t nlist_idx = 0;
2642 Symbol *symbol_ptr =
nullptr;
2644 uint32_t sym_idx = 0;
2646 size_t num_syms = 0;
2647 std::string memory_symbol_name;
2648 uint32_t unmapped_local_symbols_found = 0;
2650 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2651 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2652 std::set<lldb::addr_t> resolver_addresses;
2654 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2655 if (dyld_trie_data_size > 0) {
2656 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2660 if (text_segment_sp)
2661 text_segment_file_addr = text_segment_sp->GetFileAddress();
2662 std::vector<llvm::StringRef> nameSlices;
2664 nameSlices, resolver_addresses, reexport_trie_entries,
2665 external_sym_trie_entries);
2668 typedef std::set<ConstString> IndirectSymbols;
2669 IndirectSymbols indirect_symbol_names;
2692 UUID process_shared_cache_uuid;
2693 addr_t process_shared_cache_base_addr;
2697 process_shared_cache_uuid);
2700 __block
bool found_image =
false;
2701 __block
void *nlist_buffer =
nullptr;
2702 __block
unsigned nlist_count = 0;
2703 __block
char *string_table =
nullptr;
2704 __block vm_offset_t vm_nlist_memory = 0;
2705 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2706 __block vm_offset_t vm_string_memory = 0;
2707 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2709 auto _ = llvm::make_scope_exit(^{
2710 if (vm_nlist_memory)
2711 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2712 if (vm_string_memory)
2713 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2716 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2717 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2718 UndefinedNameToDescMap undefined_name_to_desc;
2719 SymbolIndexToName reexport_shlib_needs_fixup;
2721 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2723 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2727 if (process_shared_cache_uuid.
IsValid() &&
2728 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2731 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2736 dyld_image_copy_uuid(image, &dsc_image_uuid);
2737 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2744 dyld_image_local_nlist_content_4Symbolication(
2745 image, ^(
const void *nlistStart, uint64_t nlistCount,
2746 const char *stringTable) {
2747 if (!nlistStart || !nlistCount)
2755 nlist_byte_size * nlistCount, &vm_nlist_memory,
2756 &vm_nlist_bytes_read);
2759 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2764 vm_address_t string_address = (vm_address_t)stringTable;
2765 vm_size_t region_size;
2766 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2767 vm_region_basic_info_data_t info;
2768 memory_object_name_t object;
2770 ®ion_size, VM_REGION_BASIC_INFO_64,
2771 (vm_region_info_t)&info, &info_count, &
object);
2777 ((vm_address_t)stringTable - string_address),
2778 &vm_string_memory, &vm_string_bytes_read);
2782 nlist_buffer = (
void *)vm_nlist_memory;
2783 string_table = (
char *)vm_string_memory;
2784 nlist_count = nlistCount;
2790 nlist_count * nlist_byte_size,
2791 byte_order, addr_byte_size);
2792 unmapped_local_symbols_found = nlist_count;
2798 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2803 for (uint32_t nlist_index = 0;
2804 nlist_index < nlist_count;
2808 std::optional<struct nlist_64> nlist_maybe =
2809 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2813 struct nlist_64 nlist = *nlist_maybe;
2816 const char *symbol_name = string_table + nlist.n_strx;
2818 if (symbol_name == NULL) {
2823 "DSC unmapped local symbol[{0}] has invalid "
2824 "string table offset {1:x} in {2}, ignoring symbol",
2825 nlist_index, nlist.n_strx,
2826 module_sp->GetFileSpec().GetPath()));
2829 if (symbol_name[0] ==
'\0')
2832 const char *symbol_name_non_abi_mangled = NULL;
2835 bool add_nlist =
true;
2836 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2837 bool demangled_is_synthesized =
false;
2838 bool is_gsym =
false;
2839 bool set_value =
true;
2841 assert(sym_idx < num_syms);
2846 switch (nlist.n_type) {
2866 symbol_name, symbol_name_non_abi_mangled,
2868 demangled_is_synthesized =
true;
2870 if (nlist.n_value != 0)
2872 nlist.n_sect, nlist.n_value);
2888 nlist.n_sect, nlist.n_value);
2890 N_FUN_addr_to_sym_idx.insert(
2891 std::make_pair(nlist.n_value, sym_idx));
2895 N_FUN_indexes.push_back(sym_idx);
2899 if (!N_FUN_indexes.empty()) {
2906 N_FUN_indexes.pop_back();
2918 N_STSYM_addr_to_sym_idx.insert(
2919 std::make_pair(nlist.n_value, sym_idx));
2920 symbol_section = section_info.
GetSection(nlist.n_sect,
2922 if (symbol_name && symbol_name[0]) {
2930 symbol_section = section_info.
GetSection(nlist.n_sect,
2964 symbol_section = section_info.
GetSection(nlist.n_sect,
2977 if (symbol_name == NULL) {
2988 N_NSYM_indexes.clear();
2989 N_INCL_indexes.clear();
2990 N_BRAC_indexes.clear();
2991 N_COMM_indexes.clear();
2992 N_FUN_indexes.clear();
2998 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2999 if (N_SO_has_full_path) {
3000 if ((N_SO_index == sym_idx - 1) &&
3001 ((sym_idx - 1) < num_syms)) {
3007 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3013 N_SO_index = sym_idx;
3015 }
else if ((N_SO_index == sym_idx - 1) &&
3016 ((sym_idx - 1) < num_syms)) {
3021 const char *so_path = sym[sym_idx - 1]
3025 if (so_path && so_path[0]) {
3026 std::string full_so_path(so_path);
3027 const size_t double_slash_pos =
3028 full_so_path.find(
"//");
3029 if (double_slash_pos != std::string::npos) {
3040 &full_so_path[double_slash_pos + 1],
3041 FileSpec::Style::native);
3044 full_so_path.erase(0, double_slash_pos + 1);
3048 if (*full_so_path.rbegin() !=
'/')
3049 full_so_path +=
'/';
3050 full_so_path += symbol_name;
3054 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3058 N_SO_index = sym_idx;
3079 N_INCL_indexes.push_back(sym_idx);
3089 if (!N_INCL_indexes.empty()) {
3094 N_INCL_indexes.pop_back();
3129 symbol_section = section_info.
GetSection(nlist.n_sect,
3140 symbol_section = section_info.
GetSection(nlist.n_sect,
3142 N_BRAC_indexes.push_back(sym_idx);
3152 symbol_section = section_info.
GetSection(nlist.n_sect,
3154 if (!N_BRAC_indexes.empty()) {
3159 N_BRAC_indexes.pop_back();
3176 N_COMM_indexes.push_back(sym_idx);
3181 symbol_section = section_info.
GetSection(nlist.n_sect,
3192 if (!N_COMM_indexes.empty()) {
3197 N_COMM_indexes.pop_back();
3212 uint8_t n_type = N_TYPE & nlist.n_type;
3213 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3217 const char *reexport_name_cstr =
3218 strtab_data.PeekCStr(nlist.n_value);
3219 if (reexport_name_cstr && reexport_name_cstr[0]) {
3222 reexport_name_cstr +
3223 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3226 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3228 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3234 if (symbol_name && symbol_name[0]) {
3236 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3237 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3249 symbol_section = section_info.
GetSection(nlist.n_sect,
3252 if (symbol_section == NULL) {
3258 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3261 uint32_t section_type =
3262 symbol_section->Get() & SECTION_TYPE;
3264 switch (section_type) {
3265 case S_CSTRING_LITERALS:
3268 case S_4BYTE_LITERALS:
3271 case S_8BYTE_LITERALS:
3274 case S_LITERAL_POINTERS:
3277 case S_NON_LAZY_SYMBOL_POINTERS:
3281 case S_LAZY_SYMBOL_POINTERS:
3284 case S_SYMBOL_STUBS:
3288 case S_MOD_INIT_FUNC_POINTERS:
3292 case S_MOD_TERM_FUNC_POINTERS:
3300 case S_16BYTE_LITERALS:
3306 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3310 switch (symbol_section->GetType()) {
3337 const char *symbol_sect_name =
3338 symbol_section->GetName().AsCString();
3339 if (symbol_section->IsDescendant(
3340 text_section_sp.get())) {
3341 if (symbol_section->IsClear(
3342 S_ATTR_PURE_INSTRUCTIONS |
3343 S_ATTR_SELF_MODIFYING_CODE |
3344 S_ATTR_SOME_INSTRUCTIONS))
3348 }
else if (symbol_section->IsDescendant(
3349 data_section_sp.get()) ||
3350 symbol_section->IsDescendant(
3351 data_dirty_section_sp.get()) ||
3352 symbol_section->IsDescendant(
3353 data_const_section_sp.get())) {
3354 if (symbol_sect_name &&
3355 ::strstr(symbol_sect_name,
"__objc") ==
3361 symbol_name_non_abi_mangled, type))
3362 demangled_is_synthesized =
true;
3363 }
else if (symbol_sect_name &&
3364 ::strstr(symbol_sect_name,
3365 "__gcc_except_tab") ==
3371 }
else if (symbol_sect_name &&
3372 ::strstr(symbol_sect_name,
"__IMPORT") ==
3375 }
else if (symbol_section->IsDescendant(
3376 objc_section_sp.get())) {
3378 if (symbol_name && symbol_name[0] ==
'.') {
3379 llvm::StringRef symbol_name_ref(symbol_name);
3381 g_objc_v1_prefix_class(
".objc_class_name_");
3382 if (symbol_name_ref.starts_with(
3383 g_objc_v1_prefix_class)) {
3384 symbol_name_non_abi_mangled = symbol_name;
3385 symbol_name = symbol_name +
3386 g_objc_v1_prefix_class.size();
3388 demangled_is_synthesized =
true;
3399 uint64_t symbol_value = nlist.n_value;
3400 if (symbol_name_non_abi_mangled) {
3406 if (symbol_name && symbol_name[0] ==
'_') {
3413 if (is_gsym && is_debug) {
3414 const char *gsym_name =
3420 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3424 if (symbol_section) {
3425 const addr_t section_file_addr =
3426 symbol_section->GetFileAddress();
3427 symbol_value -= section_file_addr;
3430 if (is_debug ==
false) {
3438 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3439 if (range.first != range.second) {
3440 bool found_it =
false;
3441 for (
auto pos = range.first; pos != range.second;
3443 if (sym[sym_idx].GetMangled().
GetName(
3447 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3453 sym[sym_idx].IsExternal());
3454 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3456 if (resolver_addresses.find(nlist.n_value) !=
3457 resolver_addresses.end())
3459 sym[sym_idx].
Clear();
3467 if (resolver_addresses.find(nlist.n_value) !=
3468 resolver_addresses.end())
3480 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3482 if (range.first != range.second) {
3483 bool found_it =
false;
3484 for (
auto pos = range.first; pos != range.second;
3486 if (sym[sym_idx].GetMangled().
GetName(
3490 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3496 sym[sym_idx].IsExternal());
3497 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3499 sym[sym_idx].
Clear();
3507 const char *gsym_name =
3515 ConstNameToSymbolIndexMap::const_iterator pos =
3516 N_GSYM_name_to_sym_idx.find(gsym_name);
3517 if (pos != N_GSYM_name_to_sym_idx.end()) {
3518 const uint32_t GSYM_sym_idx = pos->second;
3519 m_nlist_idx_to_sym_idx[nlist_idx] =
3528 add_symbol_addr(sym[GSYM_sym_idx]
3535 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3537 sym[sym_idx].
Clear();
3545 sym[sym_idx].
SetID(nlist_idx);
3551 sym[sym_idx].GetAddress().GetFileAddress());
3553 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3555 if (demangled_is_synthesized)
3559 sym[sym_idx].
Clear();
3566 for (
const auto &pos : reexport_shlib_needs_fixup) {
3567 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3568 if (undef_pos != undefined_name_to_desc.end()) {
3569 const uint8_t dylib_ordinal =
3570 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3571 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3581 if (nlist_data.GetByteSize() > 0) {
3585 if (sym ==
nullptr) {
3591 if (unmapped_local_symbols_found) {
3593 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3599 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3600 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3601 UndefinedNameToDescMap undefined_name_to_desc;
3602 SymbolIndexToName reexport_shlib_needs_fixup;
3610 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3612 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3613 if (is_debug != debug_only)
3616 const char *symbol_name_non_abi_mangled =
nullptr;
3617 const char *symbol_name =
nullptr;
3619 if (have_strtab_data) {
3620 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3622 if (symbol_name ==
nullptr) {
3626 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3628 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3631 if (symbol_name[0] ==
'\0')
3632 symbol_name =
nullptr;
3634 const addr_t str_addr = strtab_addr + nlist.n_strx;
3636 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3638 symbol_name = memory_symbol_name.c_str();
3643 bool add_nlist =
true;
3644 bool is_gsym =
false;
3645 bool demangled_is_synthesized =
false;
3646 bool set_value =
true;
3648 assert(sym_idx < num_syms);
3652 switch (nlist.n_type) {
3670 symbol_name_non_abi_mangled, type)) {
3671 demangled_is_synthesized =
true;
3673 if (nlist.n_value != 0)
3675 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3691 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3693 N_FUN_addr_to_sym_idx.insert(
3694 std::make_pair(nlist.n_value, sym_idx));
3698 N_FUN_indexes.push_back(sym_idx);
3702 if (!N_FUN_indexes.empty()) {
3707 N_FUN_indexes.pop_back();
3718 N_STSYM_addr_to_sym_idx.insert(
3719 std::make_pair(nlist.n_value, sym_idx));
3720 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3721 if (symbol_name && symbol_name[0]) {
3729 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3760 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3772 if (symbol_name ==
nullptr) {
3783 N_NSYM_indexes.clear();
3784 N_INCL_indexes.clear();
3785 N_BRAC_indexes.clear();
3786 N_COMM_indexes.clear();
3787 N_FUN_indexes.clear();
3793 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3794 if (N_SO_has_full_path) {
3795 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3800 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3805 N_SO_index = sym_idx;
3807 }
else if ((N_SO_index == sym_idx - 1) &&
3808 ((sym_idx - 1) < num_syms)) {
3812 const char *so_path =
3814 if (so_path && so_path[0]) {
3815 std::string full_so_path(so_path);
3816 const size_t double_slash_pos = full_so_path.find(
"//");
3817 if (double_slash_pos != std::string::npos) {
3825 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3826 FileSpec::Style::native);
3829 full_so_path.erase(0, double_slash_pos + 1);
3833 if (*full_so_path.rbegin() !=
'/')
3834 full_so_path +=
'/';
3835 full_so_path += symbol_name;
3839 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3843 N_SO_index = sym_idx;
3863 N_INCL_indexes.push_back(sym_idx);
3872 if (!N_INCL_indexes.empty()) {
3876 N_INCL_indexes.pop_back();
3911 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3920 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3921 N_BRAC_indexes.push_back(sym_idx);
3930 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3931 if (!N_BRAC_indexes.empty()) {
3935 N_BRAC_indexes.pop_back();
3951 N_COMM_indexes.push_back(sym_idx);
3956 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3965 if (!N_COMM_indexes.empty()) {
3969 N_COMM_indexes.pop_back();
3983 uint8_t n_type = N_TYPE & nlist.n_type;
3984 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3988 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3989 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3992 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3995 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3996 indirect_symbol_names.insert(
3997 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
4003 if (symbol_name && symbol_name[0]) {
4005 ((symbol_name[0] ==
'_') ? 1 : 0));
4006 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4019 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4021 if (!symbol_section) {
4027 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4030 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4032 switch (section_type) {
4033 case S_CSTRING_LITERALS:
4036 case S_4BYTE_LITERALS:
4039 case S_8BYTE_LITERALS:
4042 case S_LITERAL_POINTERS:
4045 case S_NON_LAZY_SYMBOL_POINTERS:
4048 case S_LAZY_SYMBOL_POINTERS:
4051 case S_SYMBOL_STUBS:
4055 case S_MOD_INIT_FUNC_POINTERS:
4058 case S_MOD_TERM_FUNC_POINTERS:
4065 case S_16BYTE_LITERALS:
4071 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4075 switch (symbol_section->GetType()) {
4097 const char *symbol_sect_name =
4098 symbol_section->GetName().AsCString();
4099 if (symbol_section->IsDescendant(text_section_sp.get())) {
4100 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4101 S_ATTR_SELF_MODIFYING_CODE |
4102 S_ATTR_SOME_INSTRUCTIONS))
4106 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4107 symbol_section->IsDescendant(
4108 data_dirty_section_sp.get()) ||
4109 symbol_section->IsDescendant(
4110 data_const_section_sp.get())) {
4111 if (symbol_sect_name &&
4112 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4116 symbol_name, symbol_name_non_abi_mangled, type))
4117 demangled_is_synthesized =
true;
4118 }
else if (symbol_sect_name &&
4119 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4125 }
else if (symbol_sect_name &&
4126 ::strstr(symbol_sect_name,
"__IMPORT") ==
4129 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4131 if (symbol_name && symbol_name[0] ==
'.') {
4132 llvm::StringRef symbol_name_ref(symbol_name);
4133 llvm::StringRef g_objc_v1_prefix_class(
4134 ".objc_class_name_");
4135 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4136 symbol_name_non_abi_mangled = symbol_name;
4137 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4139 demangled_is_synthesized =
true;
4150 sym[sym_idx].
Clear();
4154 uint64_t symbol_value = nlist.n_value;
4156 if (symbol_name_non_abi_mangled) {
4162 if (symbol_name && symbol_name[0] ==
'_') {
4173 const char *gsym_name = sym[sym_idx]
4178 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4181 if (symbol_section) {
4182 const addr_t section_file_addr = symbol_section->GetFileAddress();
4183 symbol_value -= section_file_addr;
4192 std::pair<ValueToSymbolIndexMap::const_iterator,
4193 ValueToSymbolIndexMap::const_iterator>
4195 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4196 if (range.first != range.second) {
4197 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4198 pos != range.second; ++pos) {
4202 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4206 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4207 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4208 if (resolver_addresses.find(nlist.n_value) !=
4209 resolver_addresses.end())
4211 sym[sym_idx].
Clear();
4216 if (resolver_addresses.find(nlist.n_value) !=
4217 resolver_addresses.end())
4227 std::pair<ValueToSymbolIndexMap::const_iterator,
4228 ValueToSymbolIndexMap::const_iterator>
4230 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4231 if (range.first != range.second) {
4232 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4233 pos != range.second; ++pos) {
4237 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4241 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4242 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4243 sym[sym_idx].
Clear();
4249 const char *gsym_name = sym[sym_idx]
4254 ConstNameToSymbolIndexMap::const_iterator pos =
4255 N_GSYM_name_to_sym_idx.find(gsym_name);
4256 if (pos != N_GSYM_name_to_sym_idx.end()) {
4257 const uint32_t GSYM_sym_idx = pos->second;
4258 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4264 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4268 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4269 sym[sym_idx].
Clear();
4277 sym[sym_idx].
SetID(nlist_idx);
4283 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4285 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4286 if (nlist.n_desc & N_WEAK_REF)
4289 if (demangled_is_synthesized)
4298 std::vector<struct nlist_64> nlists;
4299 nlists.reserve(symtab_load_command.
nsyms);
4300 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4302 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4303 nlists.push_back(*nlist);
4313 for (
auto &nlist : nlists) {
4314 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4320 for (
auto &nlist : nlists) {
4325 for (
const auto &pos : reexport_shlib_needs_fixup) {
4326 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4327 if (undef_pos != undefined_name_to_desc.end()) {
4328 const uint8_t dylib_ordinal =
4329 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4330 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4338 int trie_symbol_table_augment_count = 0;
4339 for (
auto &e : external_sym_trie_entries) {
4340 if (!symbols_added.contains(e.entry.address))
4341 trie_symbol_table_augment_count++;
4344 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4345 num_syms = sym_idx + trie_symbol_table_augment_count;
4346 sym = symtab.
Resize(num_syms);
4348 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4351 for (
auto &e : external_sym_trie_entries) {
4352 if (symbols_added.contains(e.entry.address))
4358 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4360 const char *symbol_name = e.entry.name.GetCString();
4361 bool demangled_is_synthesized =
false;
4363 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4364 data_section_sp, data_dirty_section_sp,
4365 data_const_section_sp, symbol_section);
4368 if (symbol_section) {
4369 sym[sym_idx].
SetID(synthetic_sym_id++);
4371 if (demangled_is_synthesized)
4384 if (function_starts_count > 0) {
4385 uint32_t num_synthetic_function_symbols = 0;
4386 for (i = 0; i < function_starts_count; ++i) {
4387 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4388 ++num_synthetic_function_symbols;
4391 if (num_synthetic_function_symbols > 0) {
4392 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4393 num_syms = sym_idx + num_synthetic_function_symbols;
4394 sym = symtab.
Resize(num_syms);
4396 for (i = 0; i < function_starts_count; ++i) {
4397 const FunctionStarts::Entry *func_start_entry =
4398 function_starts.GetEntryAtIndex(i);
4399 if (!symbols_added.contains(func_start_entry->addr)) {
4400 addr_t symbol_file_addr = func_start_entry->addr;
4401 uint32_t symbol_flags = 0;
4402 if (func_start_entry->data)
4405 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4407 if (symbol_section) {
4408 sym[sym_idx].
SetID(synthetic_sym_id++);
4418 sym[sym_idx].
SetFlags(symbol_flags);
4429 if (sym_idx < num_syms) {
4431 sym = symtab.
Resize(num_syms);
4436 if (indirect_symbol_index_data.GetByteSize()) {
4437 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4438 m_nlist_idx_to_sym_idx.end();
4445 if (symbol_stub_byte_size == 0)
4448 const uint32_t num_symbol_stubs =
4451 if (num_symbol_stubs == 0)
4454 const uint32_t symbol_stub_index_offset =
4456 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4457 const uint32_t symbol_stub_index =
4458 symbol_stub_index_offset + stub_idx;
4461 (stub_idx * symbol_stub_byte_size);
4463 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4464 symbol_stub_offset, 4)) {
4465 const uint32_t stub_sym_id =
4466 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4467 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4470 NListIndexToSymbolIndexMap::const_iterator index_pos =
4471 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4472 Symbol *stub_symbol =
nullptr;
4473 if (index_pos != end_index_pos) {
4484 Address so_addr(symbol_stub_addr, section_list);
4491 if (resolver_addresses.find(symbol_stub_addr) ==
4492 resolver_addresses.end())
4502 if (sym_idx >= num_syms) {
4503 sym = symtab.
Resize(++num_syms);
4504 stub_symbol =
nullptr;
4506 sym[sym_idx].
SetID(synthetic_sym_id++);
4507 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4508 if (resolver_addresses.find(symbol_stub_addr) ==
4509 resolver_addresses.end())
4521 log->
Warning(
"symbol stub referencing symbol table symbol "
4522 "%u that isn't in our minimal symbol table, "
4533 if (!reexport_trie_entries.empty()) {
4534 for (
const auto &e : reexport_trie_entries) {
4535 if (e.entry.import_name) {
4538 if (indirect_symbol_names.find(e.entry.name) ==
4539 indirect_symbol_names.end()) {
4541 if (sym_idx >= num_syms)
4542 sym = symtab.
Resize(++num_syms);
4543 sym[sym_idx].
SetID(synthetic_sym_id++);
4548 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
6343 Target &target = process_sp->GetTarget();
6345 const llvm::Triple &target_triple = target_arch.
GetTriple();
6346 if (target_triple.getVendor() == llvm::Triple::Apple &&
6347 (target_triple.getOS() == llvm::Triple::MacOSX ||
6348 target_triple.getOS() == llvm::Triple::IOS ||
6349 target_triple.getOS() == llvm::Triple::WatchOS ||
6350 target_triple.getOS() == llvm::Triple::TvOS ||
6351 target_triple.getOS() == llvm::Triple::BridgeOS ||
6352 target_triple.getOS() == llvm::Triple::XROS)) {
6353 bool make_core =
false;
6355 case llvm::Triple::aarch64:
6356 case llvm::Triple::aarch64_32:
6357 case llvm::Triple::arm:
6358 case llvm::Triple::thumb:
6359 case llvm::Triple::x86:
6360 case llvm::Triple::x86_64:
6365 "unsupported core architecture: %s", target_triple.str().c_str());
6371 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6372 if (
error.Success()) {
6375 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6376 for (
const auto &core_range_info : core_ranges) {
6378 const auto &core_range = core_range_info.data;
6379 uint32_t cmd_type = LC_SEGMENT_64;
6380 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6381 if (addr_byte_size == 4) {
6382 cmd_type = LC_SEGMENT;
6383 segment_size =
sizeof(llvm::MachO::segment_command);
6387 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6389 uint32_t vm_prot = 0;
6390 if (core_range.lldb_permissions & ePermissionsReadable)
6391 vm_prot |= VM_PROT_READ;
6392 if (core_range.lldb_permissions & ePermissionsWritable)
6393 vm_prot |= VM_PROT_WRITE;
6394 if (core_range.lldb_permissions & ePermissionsExecutable)
6395 vm_prot |= VM_PROT_EXECUTE;
6396 const addr_t vm_addr = core_range.range.start();
6397 const addr_t vm_size = core_range.range.size();
6398 llvm::MachO::segment_command_64 segment = {
6410 segment_load_commands.push_back(segment);
6415 llvm::MachO::mach_header_64 mach_header;
6416 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6419 mach_header.filetype = MH_CORE;
6420 mach_header.ncmds = segment_load_commands.size();
6421 mach_header.flags = 0;
6422 mach_header.reserved = 0;
6423 ThreadList &thread_list = process_sp->GetThreadList();
6424 const uint32_t num_threads = thread_list.
GetSize();
6430 std::vector<StreamString> LC_THREAD_datas(num_threads);
6431 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6433 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6434 LC_THREAD_data.SetByteOrder(byte_order);
6436 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6439 switch (mach_header.cputype) {
6440 case llvm::MachO::CPU_TYPE_ARM64:
6441 case llvm::MachO::CPU_TYPE_ARM64_32:
6443 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6446 case llvm::MachO::CPU_TYPE_ARM:
6448 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6451 case llvm::MachO::CPU_TYPE_X86_64:
6453 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6456 case llvm::MachO::CPU_TYPE_RISCV:
6458 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6465 if (addr_byte_size == 8) {
6466 mach_header.sizeofcmds = segment_load_commands.size() *
6467 sizeof(llvm::MachO::segment_command_64);
6469 mach_header.sizeofcmds = segment_load_commands.size() *
6470 sizeof(llvm::MachO::segment_command);
6474 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6475 ++mach_header.ncmds;
6476 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6481 uint64_t address_mask = process_sp->GetCodeAddressMask();
6484 mach_header.ncmds++;
6485 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6489 mach_header.ncmds++;
6490 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6493 mach_header.ncmds++;
6494 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6497 buffer.
PutHex32(mach_header.magic);
6498 buffer.
PutHex32(mach_header.cputype);
6499 buffer.
PutHex32(mach_header.cpusubtype);
6500 buffer.
PutHex32(mach_header.filetype);
6501 buffer.
PutHex32(mach_header.ncmds);
6502 buffer.
PutHex32(mach_header.sizeofcmds);
6503 buffer.
PutHex32(mach_header.flags);
6504 if (addr_byte_size == 8) {
6505 buffer.
PutHex32(mach_header.reserved);
6510 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6512 file_offset = llvm::alignTo(file_offset, 16);
6513 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6517 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6519 addrable_bits_lcnote_up->name =
"addrable bits";
6520 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6521 int bits = std::bitset<64>(~address_mask).count();
6522 addrable_bits_lcnote_up->payload.PutHex32(4);
6523 addrable_bits_lcnote_up->payload.PutHex32(
6525 addrable_bits_lcnote_up->payload.PutHex32(
6527 addrable_bits_lcnote_up->payload.PutHex32(0);
6529 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6531 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6535 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6537 thread_extrainfo_lcnote_up->name =
"process metadata";
6538 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6541 std::make_shared<StructuredData::Dictionary>());
6543 std::make_shared<StructuredData::Array>());
6545 process_sp->CalculateCoreFileThreadList(options)) {
6547 std::make_shared<StructuredData::Dictionary>());
6548 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6549 threads->AddItem(thread);
6551 dict->AddItem(
"threads", threads);
6553 dict->Dump(strm,
false);
6554 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.
GetData(),
6557 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6558 file_offset = llvm::alignTo(file_offset, 16);
6559 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6562 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6564 all_image_infos_lcnote_up->name =
"all image infos";
6565 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6567 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6569 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6572 for (
auto &lcnote : lc_notes) {
6575 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6577 memset(namebuf, 0,
sizeof(namebuf));
6583 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6585 buffer.
PutHex64(lcnote->payload_file_offset);
6586 buffer.
PutHex64(lcnote->payload.GetSize());
6590 file_offset = llvm::alignTo(file_offset, 4096);
6592 for (
auto &segment : segment_load_commands) {
6593 segment.fileoff = file_offset;
6594 file_offset += segment.filesize;
6598 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6599 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6601 buffer.
PutHex32(8 + LC_THREAD_data_size);
6602 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6606 for (
const auto &segment : segment_load_commands) {
6609 buffer.
PutRawBytes(segment.segname,
sizeof(segment.segname));
6610 if (addr_byte_size == 8) {
6616 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmaddr));
6617 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmsize));
6618 buffer.
PutHex32(
static_cast<uint32_t
>(segment.fileoff));
6619 buffer.
PutHex32(
static_cast<uint32_t
>(segment.filesize));
6627 std::string core_file_path(outfile.
GetPath());
6635 uint8_t bytes[0x1000];
6637 size_t bytes_written = buffer.
GetString().size();
6639 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6640 if (
error.Success()) {
6642 for (
auto &lcnote : lc_notes) {
6643 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6646 "Unable to seek to corefile pos "
6647 "to write '%s' LC_NOTE payload",
6648 lcnote->name.c_str());
6651 bytes_written = lcnote->payload.GetSize();
6652 error = core_file.get()->Write(lcnote->payload.GetData(),
6654 if (!
error.Success())
6659 for (
const auto &segment : segment_load_commands) {
6660 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6662 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6663 segment.fileoff, core_file_path.c_str());
6669 " bytes of data for memory region at 0x%" PRIx64
"\n",
6670 segment.vmsize, segment.vmaddr);
6671 addr_t bytes_left = segment.vmsize;
6672 addr_t addr = segment.vmaddr;
6674 while (bytes_left > 0 &&
error.Success()) {
6675 const size_t bytes_to_read =
6676 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6681 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6684 if (bytes_read == bytes_to_read) {
6685 size_t bytes_written = bytes_read;
6686 error = core_file.get()->Write(bytes, bytes_written);
6687 bytes_left -= bytes_read;
6692 memset(bytes, 0, bytes_to_read);
6693 size_t bytes_written = bytes_to_read;
6694 error = core_file.get()->Write(bytes, bytes_written);
6695 bytes_left -= bytes_to_read;
6696 addr += bytes_to_read;