2215 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2216 Progress progress(
"Parsing symbol table", file_name);
2231 llvm::DenseSet<addr_t> symbols_added;
2235 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2239 symbols_added.insert(file_addr);
2241 FunctionStarts function_starts;
2247 for (i = 0; i <
m_header.ncmds; ++i) {
2250 llvm::MachO::load_command lc;
2251 if (
m_data_nsp->GetU32(&offset, &lc, 2) ==
nullptr)
2256 llvm::MachO::symtab_command lc_obj;
2257 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2258 lc_obj.cmd = lc.cmd;
2259 lc_obj.cmdsize = lc.cmdsize;
2260 symtab_load_command = lc_obj;
2265 case LC_DYLD_INFO_ONLY: {
2266 llvm::MachO::dyld_info_command lc_obj;
2267 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2268 lc_obj.cmd = lc.cmd;
2269 lc_obj.cmdsize = lc.cmdsize;
2275 case LC_LOAD_WEAK_DYLIB:
2276 case LC_REEXPORT_DYLIB:
2278 case LC_LOAD_UPWARD_DYLIB: {
2279 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2280 const char *path =
m_data_nsp->PeekCStr(name_offset);
2288 if (lc.cmd == LC_REEXPORT_DYLIB) {
2292 dylib_files.
Append(file_spec);
2296 case LC_DYLD_EXPORTS_TRIE: {
2297 llvm::MachO::linkedit_data_command lc_obj;
2298 lc_obj.cmd = lc.cmd;
2299 lc_obj.cmdsize = lc.cmdsize;
2300 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2301 exports_trie_load_command = lc_obj;
2303 case LC_FUNCTION_STARTS: {
2304 llvm::MachO::linkedit_data_command lc_obj;
2305 lc_obj.cmd = lc.cmd;
2306 lc_obj.cmdsize = lc.cmdsize;
2307 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2308 function_starts_load_command = lc_obj;
2312 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2315 image_uuid =
UUID(uuid_bytes, 16);
2322 offset = cmd_offset + lc.cmdsize;
2325 if (!symtab_load_command.
cmd)
2329 if (section_list ==
nullptr)
2332 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2334 bool bit_width_32 = addr_byte_size == 4;
2335 const size_t nlist_byte_size =
2336 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2338 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2339 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2340 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2341 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2343 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2345 const
addr_t nlist_data_byte_size =
2346 symtab_load_command.nsyms * nlist_byte_size;
2347 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2350 ProcessSP process_sp(m_process_wp.lock());
2351 Process *process = process_sp.get();
2355 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2365 section_list->FindSectionByName(g_segment_name_TEXT));
2367 section_list->FindSectionByName(g_segment_name_DATA));
2369 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2371 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2373 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2375 section_list->FindSectionByName(g_segment_name_OBJC));
2378 if (text_section_sp.get()) {
2379 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2380 g_section_name_eh_frame);
2381 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2382 g_section_name_lldb_no_nlist);
2384 eh_frame_section_sp =
2386 lldb_no_nlist_section_sp =
2390 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2391 !is_local_shared_cache_image) {
2392 Target &target = process->GetTarget();
2401 if (lldb_no_nlist_section_sp)
2406 if (linkedit_section_sp) {
2407 addr_t linkedit_load_addr =
2408 linkedit_section_sp->GetLoadBaseAddress(&target);
2418 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2419 const addr_t symoff_addr = linkedit_load_addr +
2420 symtab_load_command.
symoff -
2421 linkedit_file_offset;
2422 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2423 linkedit_file_offset;
2431 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2433 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2435 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2437 const addr_t indirect_syms_addr = linkedit_load_addr +
2439 linkedit_file_offset;
2441 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2442 if (indirect_syms_data_sp)
2443 indirect_symbol_index_data.SetData(
2444 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2454 if (!is_shared_cache_image) {
2456 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2457 if (strtab_data_sp) {
2458 strtab_data.SetData(strtab_data_sp, 0,
2459 strtab_data_sp->GetByteSize());
2464 if (function_starts_load_command.
cmd) {
2465 const addr_t func_start_addr =
2466 linkedit_load_addr + function_starts_load_command.
dataoff -
2467 linkedit_file_offset;
2470 function_starts_load_command.
datasize));
2471 if (func_start_data_sp)
2472 function_starts_data.SetData(func_start_data_sp, 0,
2473 func_start_data_sp->GetByteSize());
2479 if (is_local_shared_cache_image) {
2487 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2490 symtab_load_command.
symoff += linkedit_slide;
2491 symtab_load_command.
stroff += linkedit_slide;
2494 function_starts_load_command.
dataoff += linkedit_slide;
2495 exports_trie_load_command.
dataoff += linkedit_slide;
2499 nlist_data_byte_size);
2500 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2501 strtab_data_byte_size);
2506 && (exports_trie_load_command.
datasize > 0)));
2510 }
else if (exports_trie_load_command.
datasize > 0) {
2513 exports_trie_load_command.
datasize);
2517 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2520 if (function_starts_load_command.
cmd) {
2521 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2522 function_starts_load_command.
dataoff,
2523 function_starts_load_command.
datasize);
2527 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2529 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2546 if (text_section_sp && function_starts_data.GetByteSize()) {
2547 FunctionStarts::Entry function_start_entry;
2548 function_start_entry.data =
false;
2550 function_start_entry.addr = text_section_sp->GetFileAddress();
2552 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2555 function_start_entry.addr += delta;
2557 if (function_start_entry.addr & 1) {
2559 function_start_entry.data =
true;
2560 }
else if (always_thumb) {
2561 function_start_entry.data =
true;
2564 function_starts.Append(function_start_entry);
2572 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2578 addr_t text_base_addr = text_section_sp->GetFileAddress();
2579 size_t count = functions.
GetSize();
2580 for (
size_t i = 0; i < count; ++i) {
2584 FunctionStarts::Entry function_start_entry;
2585 function_start_entry.addr = func->
base - text_base_addr;
2587 if (function_start_entry.addr & 1) {
2589 function_start_entry.data =
true;
2590 }
else if (always_thumb) {
2591 function_start_entry.data =
true;
2594 function_starts.Append(function_start_entry);
2600 const size_t function_starts_count = function_starts.GetSize();
2615 if (unwind_or_symbol_log)
2616 module_sp->LogMessage(
2617 unwind_or_symbol_log,
2618 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2621 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2622 ? eh_frame_section_sp->GetID()
2628 std::vector<uint32_t> N_FUN_indexes;
2629 std::vector<uint32_t> N_NSYM_indexes;
2630 std::vector<uint32_t> N_INCL_indexes;
2631 std::vector<uint32_t> N_BRAC_indexes;
2632 std::vector<uint32_t> N_COMM_indexes;
2633 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2634 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2635 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2636 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2637 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2638 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2641 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2642 uint32_t nlist_idx = 0;
2643 Symbol *symbol_ptr =
nullptr;
2645 uint32_t sym_idx = 0;
2647 size_t num_syms = 0;
2648 std::string memory_symbol_name;
2649 uint32_t unmapped_local_symbols_found = 0;
2651 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2652 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2653 std::set<lldb::addr_t> resolver_addresses;
2655 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2656 if (dyld_trie_data_size > 0) {
2657 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2661 if (text_segment_sp)
2662 text_segment_file_addr = text_segment_sp->GetFileAddress();
2663 std::vector<llvm::StringRef> nameSlices;
2665 nameSlices, resolver_addresses, reexport_trie_entries,
2666 external_sym_trie_entries);
2669 typedef std::set<ConstString> IndirectSymbols;
2670 IndirectSymbols indirect_symbol_names;
2693 UUID process_shared_cache_uuid;
2694 addr_t process_shared_cache_base_addr;
2698 process_shared_cache_uuid);
2701 __block
bool found_image =
false;
2702 __block
void *nlist_buffer =
nullptr;
2703 __block
unsigned nlist_count = 0;
2704 __block
char *string_table =
nullptr;
2705 __block vm_offset_t vm_nlist_memory = 0;
2706 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2707 __block vm_offset_t vm_string_memory = 0;
2708 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2710 llvm::scope_exit _(^{
2711 if (vm_nlist_memory)
2712 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2713 if (vm_string_memory)
2714 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2717 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2718 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2719 UndefinedNameToDescMap undefined_name_to_desc;
2720 SymbolIndexToName reexport_shlib_needs_fixup;
2728 if (process_shared_cache_uuid.
IsValid() &&
2729 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2738 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2745 dyld_image_local_nlist_content_4Symbolication(
2746 image, ^(
const void *nlistStart, uint64_t nlistCount,
2747 const char *stringTable) {
2748 if (!nlistStart || !nlistCount)
2756 nlist_byte_size * nlistCount, &vm_nlist_memory,
2757 &vm_nlist_bytes_read);
2760 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2765 vm_address_t string_address = (vm_address_t)stringTable;
2766 vm_size_t region_size;
2767 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2768 vm_region_basic_info_data_t info;
2769 memory_object_name_t object;
2771 ®ion_size, VM_REGION_BASIC_INFO_64,
2772 (vm_region_info_t)&info, &info_count, &
object);
2778 ((vm_address_t)stringTable - string_address),
2779 &vm_string_memory, &vm_string_bytes_read);
2783 nlist_buffer = (
void *)vm_nlist_memory;
2784 string_table = (
char *)vm_string_memory;
2785 nlist_count = nlistCount;
2791 nlist_count * nlist_byte_size,
2792 byte_order, addr_byte_size);
2793 unmapped_local_symbols_found = nlist_count;
2799 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2804 for (uint32_t nlist_index = 0;
2805 nlist_index < nlist_count;
2809 std::optional<struct nlist_64> nlist_maybe =
2810 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2814 struct nlist_64 nlist = *nlist_maybe;
2817 const char *symbol_name = string_table + nlist.n_strx;
2819 if (symbol_name == NULL) {
2824 "DSC unmapped local symbol[{0}] has invalid "
2825 "string table offset {1:x} in {2}, ignoring symbol",
2826 nlist_index, nlist.n_strx,
2827 module_sp->GetFileSpec().GetPath()));
2830 if (symbol_name[0] ==
'\0')
2833 const char *symbol_name_non_abi_mangled = NULL;
2836 bool add_nlist =
true;
2837 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2838 bool demangled_is_synthesized =
false;
2839 bool is_gsym =
false;
2840 bool set_value =
true;
2842 assert(sym_idx < num_syms);
2847 switch (nlist.n_type) {
2867 symbol_name, symbol_name_non_abi_mangled,
2869 demangled_is_synthesized =
true;
2871 if (nlist.n_value != 0)
2873 nlist.n_sect, nlist.n_value);
2889 nlist.n_sect, nlist.n_value);
2891 N_FUN_addr_to_sym_idx.insert(
2892 std::make_pair(nlist.n_value, sym_idx));
2896 N_FUN_indexes.push_back(sym_idx);
2900 if (!N_FUN_indexes.empty()) {
2907 N_FUN_indexes.pop_back();
2919 N_STSYM_addr_to_sym_idx.insert(
2920 std::make_pair(nlist.n_value, sym_idx));
2921 symbol_section = section_info.
GetSection(nlist.n_sect,
2923 if (symbol_name && symbol_name[0]) {
2931 symbol_section = section_info.
GetSection(nlist.n_sect,
2965 symbol_section = section_info.
GetSection(nlist.n_sect,
2978 if (symbol_name == NULL) {
2989 N_NSYM_indexes.clear();
2990 N_INCL_indexes.clear();
2991 N_BRAC_indexes.clear();
2992 N_COMM_indexes.clear();
2993 N_FUN_indexes.clear();
2999 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3000 if (N_SO_has_full_path) {
3001 if ((N_SO_index == sym_idx - 1) &&
3002 ((sym_idx - 1) < num_syms)) {
3008 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3014 N_SO_index = sym_idx;
3016 }
else if ((N_SO_index == sym_idx - 1) &&
3017 ((sym_idx - 1) < num_syms)) {
3022 const char *so_path = sym[sym_idx - 1]
3026 if (so_path && so_path[0]) {
3027 std::string full_so_path(so_path);
3028 const size_t double_slash_pos =
3029 full_so_path.find(
"//");
3030 if (double_slash_pos != std::string::npos) {
3041 &full_so_path[double_slash_pos + 1],
3042 FileSpec::Style::native);
3045 full_so_path.erase(0, double_slash_pos + 1);
3049 if (*full_so_path.rbegin() !=
'/')
3050 full_so_path +=
'/';
3051 full_so_path += symbol_name;
3055 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3059 N_SO_index = sym_idx;
3080 N_INCL_indexes.push_back(sym_idx);
3090 if (!N_INCL_indexes.empty()) {
3095 N_INCL_indexes.pop_back();
3130 symbol_section = section_info.
GetSection(nlist.n_sect,
3141 symbol_section = section_info.
GetSection(nlist.n_sect,
3143 N_BRAC_indexes.push_back(sym_idx);
3153 symbol_section = section_info.
GetSection(nlist.n_sect,
3155 if (!N_BRAC_indexes.empty()) {
3160 N_BRAC_indexes.pop_back();
3177 N_COMM_indexes.push_back(sym_idx);
3182 symbol_section = section_info.
GetSection(nlist.n_sect,
3193 if (!N_COMM_indexes.empty()) {
3198 N_COMM_indexes.pop_back();
3213 uint8_t n_type = N_TYPE & nlist.n_type;
3214 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3218 const char *reexport_name_cstr =
3219 strtab_data.PeekCStr(nlist.n_value);
3220 if (reexport_name_cstr && reexport_name_cstr[0]) {
3223 reexport_name_cstr +
3224 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3227 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3229 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3235 if (symbol_name && symbol_name[0]) {
3237 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3238 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3250 symbol_section = section_info.
GetSection(nlist.n_sect,
3253 if (symbol_section == NULL) {
3259 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3262 uint32_t section_type =
3263 symbol_section->Get() & SECTION_TYPE;
3265 switch (section_type) {
3266 case S_CSTRING_LITERALS:
3269 case S_4BYTE_LITERALS:
3272 case S_8BYTE_LITERALS:
3275 case S_LITERAL_POINTERS:
3278 case S_NON_LAZY_SYMBOL_POINTERS:
3282 case S_LAZY_SYMBOL_POINTERS:
3285 case S_SYMBOL_STUBS:
3289 case S_MOD_INIT_FUNC_POINTERS:
3293 case S_MOD_TERM_FUNC_POINTERS:
3301 case S_16BYTE_LITERALS:
3307 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3311 switch (symbol_section->GetType()) {
3338 const char *symbol_sect_name =
3339 symbol_section->GetName().AsCString();
3340 if (symbol_section->IsDescendant(
3341 text_section_sp.get())) {
3342 if (symbol_section->IsClear(
3343 S_ATTR_PURE_INSTRUCTIONS |
3344 S_ATTR_SELF_MODIFYING_CODE |
3345 S_ATTR_SOME_INSTRUCTIONS))
3349 }
else if (symbol_section->IsDescendant(
3350 data_section_sp.get()) ||
3351 symbol_section->IsDescendant(
3352 data_dirty_section_sp.get()) ||
3353 symbol_section->IsDescendant(
3354 data_const_section_sp.get())) {
3355 if (symbol_sect_name &&
3356 ::strstr(symbol_sect_name,
"__objc") ==
3362 symbol_name_non_abi_mangled, type))
3363 demangled_is_synthesized =
true;
3364 }
else if (symbol_sect_name &&
3365 ::strstr(symbol_sect_name,
3366 "__gcc_except_tab") ==
3372 }
else if (symbol_sect_name &&
3373 ::strstr(symbol_sect_name,
"__IMPORT") ==
3376 }
else if (symbol_section->IsDescendant(
3377 objc_section_sp.get())) {
3379 if (symbol_name && symbol_name[0] ==
'.') {
3380 llvm::StringRef symbol_name_ref(symbol_name);
3382 g_objc_v1_prefix_class(
".objc_class_name_");
3383 if (symbol_name_ref.starts_with(
3384 g_objc_v1_prefix_class)) {
3385 symbol_name_non_abi_mangled = symbol_name;
3386 symbol_name = symbol_name +
3387 g_objc_v1_prefix_class.size();
3389 demangled_is_synthesized =
true;
3400 uint64_t symbol_value = nlist.n_value;
3401 if (symbol_name_non_abi_mangled) {
3407 if (symbol_name && symbol_name[0] ==
'_') {
3414 if (is_gsym && is_debug) {
3415 const char *gsym_name =
3421 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3425 if (symbol_section) {
3426 const addr_t section_file_addr =
3427 symbol_section->GetFileAddress();
3428 symbol_value -= section_file_addr;
3431 if (is_debug ==
false) {
3439 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3440 if (range.first != range.second) {
3441 bool found_it =
false;
3442 for (
auto pos = range.first; pos != range.second;
3444 if (sym[sym_idx].GetMangled().
GetName(
3448 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3454 sym[sym_idx].IsExternal());
3455 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3457 if (resolver_addresses.find(nlist.n_value) !=
3458 resolver_addresses.end())
3460 sym[sym_idx].
Clear();
3468 if (resolver_addresses.find(nlist.n_value) !=
3469 resolver_addresses.end())
3481 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3483 if (range.first != range.second) {
3484 bool found_it =
false;
3485 for (
auto pos = range.first; pos != range.second;
3487 if (sym[sym_idx].GetMangled().
GetName(
3491 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3497 sym[sym_idx].IsExternal());
3498 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3500 sym[sym_idx].
Clear();
3508 const char *gsym_name =
3516 ConstNameToSymbolIndexMap::const_iterator pos =
3517 N_GSYM_name_to_sym_idx.find(gsym_name);
3518 if (pos != N_GSYM_name_to_sym_idx.end()) {
3519 const uint32_t GSYM_sym_idx = pos->second;
3520 m_nlist_idx_to_sym_idx[nlist_idx] =
3526 Address(symbol_section, symbol_value);
3527 add_symbol_addr(sym[GSYM_sym_idx]
3534 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3536 sym[sym_idx].
Clear();
3544 sym[sym_idx].
SetID(nlist_idx);
3548 Address(symbol_section, symbol_value);
3550 sym[sym_idx].GetAddress().GetFileAddress());
3552 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3554 if (demangled_is_synthesized)
3558 sym[sym_idx].
Clear();
3565 for (
const auto &pos : reexport_shlib_needs_fixup) {
3566 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3567 if (undef_pos != undefined_name_to_desc.end()) {
3568 const uint8_t dylib_ordinal =
3569 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3570 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3580 if (nlist_data.GetByteSize() > 0) {
3584 if (sym ==
nullptr) {
3590 if (unmapped_local_symbols_found) {
3592 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3598 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3599 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3600 UndefinedNameToDescMap undefined_name_to_desc;
3601 SymbolIndexToName reexport_shlib_needs_fixup;
3609 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3611 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3612 if (is_debug != debug_only)
3615 const char *symbol_name_non_abi_mangled =
nullptr;
3616 const char *symbol_name =
nullptr;
3618 if (have_strtab_data) {
3619 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3621 if (symbol_name ==
nullptr) {
3625 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3627 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3630 if (symbol_name[0] ==
'\0')
3631 symbol_name =
nullptr;
3633 const addr_t str_addr = strtab_addr + nlist.n_strx;
3635 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3637 symbol_name = memory_symbol_name.c_str();
3642 bool add_nlist =
true;
3643 bool is_gsym =
false;
3644 bool demangled_is_synthesized =
false;
3645 bool set_value =
true;
3647 assert(sym_idx < num_syms);
3651 switch (nlist.n_type) {
3669 symbol_name_non_abi_mangled, type)) {
3670 demangled_is_synthesized =
true;
3672 if (nlist.n_value != 0)
3674 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3690 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3692 N_FUN_addr_to_sym_idx.insert(
3693 std::make_pair(nlist.n_value, sym_idx));
3697 N_FUN_indexes.push_back(sym_idx);
3701 if (!N_FUN_indexes.empty()) {
3706 N_FUN_indexes.pop_back();
3717 N_STSYM_addr_to_sym_idx.insert(
3718 std::make_pair(nlist.n_value, sym_idx));
3719 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3720 if (symbol_name && symbol_name[0]) {
3728 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3759 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3771 if (symbol_name ==
nullptr) {
3782 N_NSYM_indexes.clear();
3783 N_INCL_indexes.clear();
3784 N_BRAC_indexes.clear();
3785 N_COMM_indexes.clear();
3786 N_FUN_indexes.clear();
3792 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3793 if (N_SO_has_full_path) {
3794 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3799 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3804 N_SO_index = sym_idx;
3806 }
else if ((N_SO_index == sym_idx - 1) &&
3807 ((sym_idx - 1) < num_syms)) {
3811 const char *so_path =
3813 if (so_path && so_path[0]) {
3814 std::string full_so_path(so_path);
3815 const size_t double_slash_pos = full_so_path.find(
"//");
3816 if (double_slash_pos != std::string::npos) {
3824 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3825 FileSpec::Style::native);
3828 full_so_path.erase(0, double_slash_pos + 1);
3832 if (*full_so_path.rbegin() !=
'/')
3833 full_so_path +=
'/';
3834 full_so_path += symbol_name;
3838 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3842 N_SO_index = sym_idx;
3862 N_INCL_indexes.push_back(sym_idx);
3871 if (!N_INCL_indexes.empty()) {
3875 N_INCL_indexes.pop_back();
3910 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3919 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3920 N_BRAC_indexes.push_back(sym_idx);
3929 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3930 if (!N_BRAC_indexes.empty()) {
3934 N_BRAC_indexes.pop_back();
3950 N_COMM_indexes.push_back(sym_idx);
3955 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3964 if (!N_COMM_indexes.empty()) {
3968 N_COMM_indexes.pop_back();
3982 uint8_t n_type = N_TYPE & nlist.n_type;
3983 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3987 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3988 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3991 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3994 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3995 indirect_symbol_names.insert(
3996 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
4002 if (symbol_name && symbol_name[0]) {
4004 ((symbol_name[0] ==
'_') ? 1 : 0));
4005 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4018 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4020 if (!symbol_section) {
4026 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4029 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4031 switch (section_type) {
4032 case S_CSTRING_LITERALS:
4035 case S_4BYTE_LITERALS:
4038 case S_8BYTE_LITERALS:
4041 case S_LITERAL_POINTERS:
4044 case S_NON_LAZY_SYMBOL_POINTERS:
4047 case S_LAZY_SYMBOL_POINTERS:
4050 case S_SYMBOL_STUBS:
4054 case S_MOD_INIT_FUNC_POINTERS:
4057 case S_MOD_TERM_FUNC_POINTERS:
4064 case S_16BYTE_LITERALS:
4070 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4074 switch (symbol_section->GetType()) {
4096 const char *symbol_sect_name =
4097 symbol_section->GetName().AsCString();
4098 if (symbol_section->IsDescendant(text_section_sp.get())) {
4099 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4100 S_ATTR_SELF_MODIFYING_CODE |
4101 S_ATTR_SOME_INSTRUCTIONS))
4105 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4106 symbol_section->IsDescendant(
4107 data_dirty_section_sp.get()) ||
4108 symbol_section->IsDescendant(
4109 data_const_section_sp.get())) {
4110 if (symbol_sect_name &&
4111 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4115 symbol_name, symbol_name_non_abi_mangled, type))
4116 demangled_is_synthesized =
true;
4117 }
else if (symbol_sect_name &&
4118 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4124 }
else if (symbol_sect_name &&
4125 ::strstr(symbol_sect_name,
"__IMPORT") ==
4128 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4130 if (symbol_name && symbol_name[0] ==
'.') {
4131 llvm::StringRef symbol_name_ref(symbol_name);
4132 llvm::StringRef g_objc_v1_prefix_class(
4133 ".objc_class_name_");
4134 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4135 symbol_name_non_abi_mangled = symbol_name;
4136 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4138 demangled_is_synthesized =
true;
4149 sym[sym_idx].
Clear();
4153 uint64_t symbol_value = nlist.n_value;
4155 if (symbol_name_non_abi_mangled) {
4161 if (symbol_name && symbol_name[0] ==
'_') {
4172 const char *gsym_name = sym[sym_idx]
4177 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4180 if (symbol_section) {
4181 const addr_t section_file_addr = symbol_section->GetFileAddress();
4182 symbol_value -= section_file_addr;
4191 std::pair<ValueToSymbolIndexMap::const_iterator,
4192 ValueToSymbolIndexMap::const_iterator>
4194 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4195 if (range.first != range.second) {
4196 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4197 pos != range.second; ++pos) {
4201 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4205 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4206 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4207 if (resolver_addresses.find(nlist.n_value) !=
4208 resolver_addresses.end())
4210 sym[sym_idx].
Clear();
4215 if (resolver_addresses.find(nlist.n_value) !=
4216 resolver_addresses.end())
4226 std::pair<ValueToSymbolIndexMap::const_iterator,
4227 ValueToSymbolIndexMap::const_iterator>
4229 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4230 if (range.first != range.second) {
4231 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4232 pos != range.second; ++pos) {
4236 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4240 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4241 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4242 sym[sym_idx].
Clear();
4248 const char *gsym_name = sym[sym_idx]
4253 ConstNameToSymbolIndexMap::const_iterator pos =
4254 N_GSYM_name_to_sym_idx.find(gsym_name);
4255 if (pos != N_GSYM_name_to_sym_idx.end()) {
4256 const uint32_t GSYM_sym_idx = pos->second;
4257 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4261 Address(symbol_section, symbol_value);
4263 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4267 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4268 sym[sym_idx].
Clear();
4276 sym[sym_idx].
SetID(nlist_idx);
4281 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4283 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4284 if (nlist.n_desc & N_WEAK_REF)
4287 if (demangled_is_synthesized)
4296 std::vector<struct nlist_64> nlists;
4297 nlists.reserve(symtab_load_command.
nsyms);
4298 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4300 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4301 nlists.push_back(*nlist);
4311 for (
auto &nlist : nlists) {
4312 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4318 for (
auto &nlist : nlists) {
4323 for (
const auto &pos : reexport_shlib_needs_fixup) {
4324 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4325 if (undef_pos != undefined_name_to_desc.end()) {
4326 const uint8_t dylib_ordinal =
4327 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4328 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4336 int trie_symbol_table_augment_count = 0;
4337 for (
auto &e : external_sym_trie_entries) {
4338 if (!symbols_added.contains(e.entry.address))
4339 trie_symbol_table_augment_count++;
4342 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4343 num_syms = sym_idx + trie_symbol_table_augment_count;
4344 sym = symtab.
Resize(num_syms);
4346 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4349 for (
auto &e : external_sym_trie_entries) {
4350 if (symbols_added.contains(e.entry.address))
4356 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4358 const char *symbol_name = e.entry.name.GetCString();
4359 bool demangled_is_synthesized =
false;
4361 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4362 data_section_sp, data_dirty_section_sp,
4363 data_const_section_sp, symbol_section);
4366 if (symbol_section) {
4367 sym[sym_idx].
SetID(synthetic_sym_id++);
4369 if (demangled_is_synthesized)
4382 if (function_starts_count > 0) {
4383 uint32_t num_synthetic_function_symbols = 0;
4384 for (i = 0; i < function_starts_count; ++i) {
4385 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4386 ++num_synthetic_function_symbols;
4389 if (num_synthetic_function_symbols > 0) {
4390 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4391 num_syms = sym_idx + num_synthetic_function_symbols;
4392 sym = symtab.
Resize(num_syms);
4394 for (i = 0; i < function_starts_count; ++i) {
4395 const FunctionStarts::Entry *func_start_entry =
4396 function_starts.GetEntryAtIndex(i);
4397 if (!symbols_added.contains(func_start_entry->addr)) {
4398 addr_t symbol_file_addr = func_start_entry->addr;
4399 uint32_t symbol_flags = 0;
4400 if (func_start_entry->data)
4403 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4405 if (symbol_section) {
4406 sym[sym_idx].
SetID(synthetic_sym_id++);
4416 sym[sym_idx].
SetFlags(symbol_flags);
4427 if (sym_idx < num_syms) {
4429 sym = symtab.
Resize(num_syms);
4434 if (indirect_symbol_index_data.GetByteSize()) {
4435 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4436 m_nlist_idx_to_sym_idx.end();
4443 if (symbol_stub_byte_size == 0)
4446 const uint32_t num_symbol_stubs =
4449 if (num_symbol_stubs == 0)
4452 const uint32_t symbol_stub_index_offset =
4454 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4455 const uint32_t symbol_stub_index =
4456 symbol_stub_index_offset + stub_idx;
4459 (stub_idx * symbol_stub_byte_size);
4461 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4462 symbol_stub_offset, 4)) {
4463 const uint32_t stub_sym_id =
4464 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4465 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4468 NListIndexToSymbolIndexMap::const_iterator index_pos =
4469 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4470 Symbol *stub_symbol =
nullptr;
4471 if (index_pos != end_index_pos) {
4482 Address so_addr(symbol_stub_addr, section_list);
4489 if (resolver_addresses.find(symbol_stub_addr) ==
4490 resolver_addresses.end())
4500 if (sym_idx >= num_syms) {
4501 sym = symtab.
Resize(++num_syms);
4502 stub_symbol =
nullptr;
4504 sym[sym_idx].
SetID(synthetic_sym_id++);
4505 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4506 if (resolver_addresses.find(symbol_stub_addr) ==
4507 resolver_addresses.end())
4519 log->
Warning(
"symbol stub referencing symbol table symbol "
4520 "%u that isn't in our minimal symbol table, "
4531 if (!reexport_trie_entries.empty()) {
4532 for (
const auto &e : reexport_trie_entries) {
4533 if (e.entry.import_name) {
4536 if (indirect_symbol_names.find(e.entry.name) ==
4537 indirect_symbol_names.end()) {
4539 if (sym_idx >= num_syms)
4540 sym = symtab.
Resize(++num_syms);
4541 sym[sym_idx].
SetID(synthetic_sym_id++);
4546 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
6339 Target &target = process_sp->GetTarget();
6341 const llvm::Triple &target_triple = target_arch.
GetTriple();
6342 if (target_triple.getVendor() == llvm::Triple::Apple &&
6343 (target_triple.getOS() == llvm::Triple::MacOSX ||
6344 target_triple.getOS() == llvm::Triple::IOS ||
6345 target_triple.getOS() == llvm::Triple::WatchOS ||
6346 target_triple.getOS() == llvm::Triple::TvOS ||
6347 target_triple.getOS() == llvm::Triple::BridgeOS ||
6348 target_triple.getOS() == llvm::Triple::XROS)) {
6349 bool make_core =
false;
6351 case llvm::Triple::aarch64:
6352 case llvm::Triple::aarch64_32:
6353 case llvm::Triple::arm:
6354 case llvm::Triple::thumb:
6355 case llvm::Triple::x86:
6356 case llvm::Triple::x86_64:
6361 "unsupported core architecture: %s", target_triple.str().c_str());
6367 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6368 if (
error.Success()) {
6371 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6372 for (
const auto &core_range_info : core_ranges) {
6374 const auto &core_range = core_range_info.data;
6375 uint32_t cmd_type = LC_SEGMENT_64;
6376 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6377 if (addr_byte_size == 4) {
6378 cmd_type = LC_SEGMENT;
6379 segment_size =
sizeof(llvm::MachO::segment_command);
6383 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6385 uint32_t vm_prot = 0;
6386 if (core_range.lldb_permissions & ePermissionsReadable)
6387 vm_prot |= VM_PROT_READ;
6388 if (core_range.lldb_permissions & ePermissionsWritable)
6389 vm_prot |= VM_PROT_WRITE;
6390 if (core_range.lldb_permissions & ePermissionsExecutable)
6391 vm_prot |= VM_PROT_EXECUTE;
6392 const addr_t vm_addr = core_range.range.start();
6393 const addr_t vm_size = core_range.range.size();
6394 llvm::MachO::segment_command_64
segment = {
6406 segment_load_commands.push_back(
segment);
6411 llvm::MachO::mach_header_64 mach_header;
6412 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6415 mach_header.filetype = MH_CORE;
6416 mach_header.ncmds = segment_load_commands.size();
6417 mach_header.flags = 0;
6418 mach_header.reserved = 0;
6419 ThreadList &thread_list = process_sp->GetThreadList();
6420 const uint32_t num_threads = thread_list.
GetSize();
6426 std::vector<StreamString> LC_THREAD_datas(num_threads);
6427 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6429 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6430 LC_THREAD_data.SetByteOrder(byte_order);
6432 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6435 switch (mach_header.cputype) {
6436 case llvm::MachO::CPU_TYPE_ARM64:
6437 case llvm::MachO::CPU_TYPE_ARM64_32:
6439 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6442 case llvm::MachO::CPU_TYPE_ARM:
6444 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6447 case llvm::MachO::CPU_TYPE_X86_64:
6449 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6452 case llvm::MachO::CPU_TYPE_RISCV:
6454 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6461 if (addr_byte_size == 8) {
6462 mach_header.sizeofcmds = segment_load_commands.size() *
6463 sizeof(llvm::MachO::segment_command_64);
6465 mach_header.sizeofcmds = segment_load_commands.size() *
6466 sizeof(llvm::MachO::segment_command);
6470 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6471 ++mach_header.ncmds;
6472 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6477 uint64_t address_mask = process_sp->GetCodeAddressMask();
6480 mach_header.ncmds++;
6481 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6485 mach_header.ncmds++;
6486 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6489 mach_header.ncmds++;
6490 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6493 buffer.
PutHex32(mach_header.magic);
6494 buffer.
PutHex32(mach_header.cputype);
6495 buffer.
PutHex32(mach_header.cpusubtype);
6496 buffer.
PutHex32(mach_header.filetype);
6497 buffer.
PutHex32(mach_header.ncmds);
6498 buffer.
PutHex32(mach_header.sizeofcmds);
6499 buffer.
PutHex32(mach_header.flags);
6500 if (addr_byte_size == 8) {
6501 buffer.
PutHex32(mach_header.reserved);
6506 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6508 file_offset = llvm::alignTo(file_offset, 16);
6509 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6513 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6515 addrable_bits_lcnote_up->name =
"addrable bits";
6516 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6517 int bits = std::bitset<64>(~address_mask).count();
6518 addrable_bits_lcnote_up->payload.PutHex32(4);
6519 addrable_bits_lcnote_up->payload.PutHex32(
6521 addrable_bits_lcnote_up->payload.PutHex32(
6523 addrable_bits_lcnote_up->payload.PutHex32(0);
6525 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6527 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6531 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6533 thread_extrainfo_lcnote_up->name =
"process metadata";
6534 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6537 std::make_shared<StructuredData::Dictionary>());
6539 std::make_shared<StructuredData::Array>());
6541 process_sp->CalculateCoreFileThreadList(options)) {
6543 std::make_shared<StructuredData::Dictionary>());
6544 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6545 threads->AddItem(thread);
6547 dict->AddItem(
"threads", threads);
6549 dict->Dump(strm,
false);
6550 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.
GetData(),
6553 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6554 file_offset = llvm::alignTo(file_offset, 16);
6555 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6558 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6560 all_image_infos_lcnote_up->name =
"all image infos";
6561 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6563 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6565 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6568 for (
auto &lcnote : lc_notes) {
6571 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6573 memset(namebuf, 0,
sizeof(namebuf));
6579 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6581 buffer.
PutHex64(lcnote->payload_file_offset);
6582 buffer.
PutHex64(lcnote->payload.GetSize());
6586 file_offset = llvm::alignTo(file_offset, 4096);
6588 for (
auto &
segment : segment_load_commands) {
6589 segment.fileoff = file_offset;
6590 file_offset +=
segment.filesize;
6594 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6595 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6597 buffer.
PutHex32(8 + LC_THREAD_data_size);
6598 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6602 for (
const auto &
segment : segment_load_commands) {
6606 if (addr_byte_size == 8) {
6623 std::string core_file_path(outfile.
GetPath());
6631 uint8_t bytes[0x1000];
6633 size_t bytes_written = buffer.
GetString().size();
6635 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6636 if (
error.Success()) {
6638 for (
auto &lcnote : lc_notes) {
6639 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6642 "Unable to seek to corefile pos "
6643 "to write '%s' LC_NOTE payload",
6644 lcnote->name.c_str());
6647 bytes_written = lcnote->payload.GetSize();
6648 error = core_file.get()->Write(lcnote->payload.GetData(),
6650 if (!
error.Success())
6655 for (
const auto &
segment : segment_load_commands) {
6656 if (core_file.get()->SeekFromStart(
segment.fileoff) == -1) {
6658 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6659 segment.fileoff, core_file_path.c_str());
6665 " bytes of data for memory region at 0x%" PRIx64
"\n",
6670 while (bytes_left > 0 &&
error.Success()) {
6671 const size_t bytes_to_read =
6672 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6677 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6680 if (bytes_read == bytes_to_read) {
6681 size_t bytes_written = bytes_read;
6682 error = core_file.get()->Write(bytes, bytes_written);
6683 bytes_left -= bytes_read;
6688 memset(bytes, 0, bytes_to_read);
6689 size_t bytes_written = bytes_to_read;
6690 error = core_file.get()->Write(bytes, bytes_written);
6691 bytes_left -= bytes_to_read;
6692 addr += bytes_to_read;