2207 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2208 Progress progress(
"Parsing symbol table", file_name);
2223 llvm::DenseSet<addr_t> symbols_added;
2227 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2231 symbols_added.insert(file_addr);
2233 FunctionStarts function_starts;
2239 for (i = 0; i <
m_header.ncmds; ++i) {
2242 llvm::MachO::load_command lc;
2243 if (
m_data.GetU32(&offset, &lc, 2) ==
nullptr)
2248 llvm::MachO::symtab_command lc_obj;
2249 if (
m_data.GetU32(&offset, &lc_obj.symoff, 4)) {
2250 lc_obj.cmd = lc.cmd;
2251 lc_obj.cmdsize = lc.cmdsize;
2252 symtab_load_command = lc_obj;
2257 case LC_DYLD_INFO_ONLY: {
2258 llvm::MachO::dyld_info_command lc_obj;
2259 if (
m_data.GetU32(&offset, &lc_obj.rebase_off, 10)) {
2260 lc_obj.cmd = lc.cmd;
2261 lc_obj.cmdsize = lc.cmdsize;
2267 case LC_LOAD_WEAK_DYLIB:
2268 case LC_REEXPORT_DYLIB:
2270 case LC_LOAD_UPWARD_DYLIB: {
2271 uint32_t name_offset = cmd_offset +
m_data.GetU32(&offset);
2272 const char *path =
m_data.PeekCStr(name_offset);
2280 if (lc.cmd == LC_REEXPORT_DYLIB) {
2284 dylib_files.
Append(file_spec);
2288 case LC_DYLD_EXPORTS_TRIE: {
2289 llvm::MachO::linkedit_data_command lc_obj;
2290 lc_obj.cmd = lc.cmd;
2291 lc_obj.cmdsize = lc.cmdsize;
2292 if (
m_data.GetU32(&offset, &lc_obj.dataoff, 2))
2293 exports_trie_load_command = lc_obj;
2295 case LC_FUNCTION_STARTS: {
2296 llvm::MachO::linkedit_data_command lc_obj;
2297 lc_obj.cmd = lc.cmd;
2298 lc_obj.cmdsize = lc.cmdsize;
2299 if (
m_data.GetU32(&offset, &lc_obj.dataoff, 2))
2300 function_starts_load_command = lc_obj;
2304 const uint8_t *uuid_bytes =
m_data.PeekData(offset, 16);
2307 image_uuid =
UUID(uuid_bytes, 16);
2314 offset = cmd_offset + lc.cmdsize;
2317 if (!symtab_load_command.
cmd)
2321 if (section_list ==
nullptr)
2324 const uint32_t addr_byte_size =
m_data.GetAddressByteSize();
2326 bool bit_width_32 = addr_byte_size == 4;
2327 const size_t nlist_byte_size =
2328 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2330 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2331 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2332 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2333 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2335 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2337 const
addr_t nlist_data_byte_size =
2338 symtab_load_command.nsyms * nlist_byte_size;
2339 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2342 ProcessSP process_sp(m_process_wp.lock());
2343 Process *process = process_sp.get();
2347 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2357 section_list->FindSectionByName(g_segment_name_TEXT));
2359 section_list->FindSectionByName(g_segment_name_DATA));
2361 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2363 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2365 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2367 section_list->FindSectionByName(g_segment_name_OBJC));
2370 if (text_section_sp.get()) {
2371 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2372 g_section_name_eh_frame);
2373 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2374 g_section_name_lldb_no_nlist);
2376 eh_frame_section_sp =
2378 lldb_no_nlist_section_sp =
2382 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2383 !is_local_shared_cache_image) {
2384 Target &target = process->GetTarget();
2393 if (lldb_no_nlist_section_sp)
2398 if (linkedit_section_sp) {
2399 addr_t linkedit_load_addr =
2400 linkedit_section_sp->GetLoadBaseAddress(&target);
2410 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2411 const addr_t symoff_addr = linkedit_load_addr +
2412 symtab_load_command.
symoff -
2413 linkedit_file_offset;
2414 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2415 linkedit_file_offset;
2423 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2425 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2427 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2429 const addr_t indirect_syms_addr = linkedit_load_addr +
2431 linkedit_file_offset;
2433 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2434 if (indirect_syms_data_sp)
2435 indirect_symbol_index_data.SetData(
2436 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2446 if (!is_shared_cache_image) {
2448 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2449 if (strtab_data_sp) {
2450 strtab_data.SetData(strtab_data_sp, 0,
2451 strtab_data_sp->GetByteSize());
2456 if (function_starts_load_command.
cmd) {
2457 const addr_t func_start_addr =
2458 linkedit_load_addr + function_starts_load_command.
dataoff -
2459 linkedit_file_offset;
2462 function_starts_load_command.
datasize));
2463 if (func_start_data_sp)
2464 function_starts_data.SetData(func_start_data_sp, 0,
2465 func_start_data_sp->GetByteSize());
2471 if (is_local_shared_cache_image) {
2479 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2482 symtab_load_command.
symoff += linkedit_slide;
2483 symtab_load_command.
stroff += linkedit_slide;
2486 function_starts_load_command.
dataoff += linkedit_slide;
2487 exports_trie_load_command.
dataoff += linkedit_slide;
2491 nlist_data_byte_size);
2492 strtab_data.SetData(
m_data, symtab_load_command.
stroff,
2493 strtab_data_byte_size);
2498 && (exports_trie_load_command.
datasize > 0)));
2502 }
else if (exports_trie_load_command.
datasize > 0) {
2503 dyld_trie_data.SetData(
m_data, exports_trie_load_command.
dataoff,
2504 exports_trie_load_command.
datasize);
2511 if (function_starts_load_command.
cmd) {
2512 function_starts_data.SetData(
m_data, function_starts_load_command.
dataoff,
2513 function_starts_load_command.
datasize);
2517 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2519 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2536 if (text_section_sp && function_starts_data.GetByteSize()) {
2537 FunctionStarts::Entry function_start_entry;
2538 function_start_entry.data =
false;
2540 function_start_entry.addr = text_section_sp->GetFileAddress();
2542 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2545 function_start_entry.addr += delta;
2547 if (function_start_entry.addr & 1) {
2549 function_start_entry.data =
true;
2550 }
else if (always_thumb) {
2551 function_start_entry.data =
true;
2554 function_starts.Append(function_start_entry);
2562 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2568 addr_t text_base_addr = text_section_sp->GetFileAddress();
2569 size_t count = functions.
GetSize();
2570 for (
size_t i = 0; i < count; ++i) {
2574 FunctionStarts::Entry function_start_entry;
2575 function_start_entry.addr = func->
base - text_base_addr;
2577 if (function_start_entry.addr & 1) {
2579 function_start_entry.data =
true;
2580 }
else if (always_thumb) {
2581 function_start_entry.data =
true;
2584 function_starts.Append(function_start_entry);
2590 const size_t function_starts_count = function_starts.GetSize();
2605 if (unwind_or_symbol_log)
2606 module_sp->LogMessage(
2607 unwind_or_symbol_log,
2608 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2611 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2612 ? eh_frame_section_sp->GetID()
2618 std::vector<uint32_t> N_FUN_indexes;
2619 std::vector<uint32_t> N_NSYM_indexes;
2620 std::vector<uint32_t> N_INCL_indexes;
2621 std::vector<uint32_t> N_BRAC_indexes;
2622 std::vector<uint32_t> N_COMM_indexes;
2623 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2624 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2625 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2626 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2627 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2628 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2631 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2632 uint32_t nlist_idx = 0;
2633 Symbol *symbol_ptr =
nullptr;
2635 uint32_t sym_idx = 0;
2637 size_t num_syms = 0;
2638 std::string memory_symbol_name;
2639 uint32_t unmapped_local_symbols_found = 0;
2641 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2642 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2643 std::set<lldb::addr_t> resolver_addresses;
2645 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2646 if (dyld_trie_data_size > 0) {
2647 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2651 if (text_segment_sp)
2652 text_segment_file_addr = text_segment_sp->GetFileAddress();
2653 std::vector<llvm::StringRef> nameSlices;
2655 nameSlices, resolver_addresses, reexport_trie_entries,
2656 external_sym_trie_entries);
2659 typedef std::set<ConstString> IndirectSymbols;
2660 IndirectSymbols indirect_symbol_names;
2683 UUID process_shared_cache_uuid;
2684 addr_t process_shared_cache_base_addr;
2688 process_shared_cache_uuid);
2691 __block
bool found_image =
false;
2692 __block
void *nlist_buffer =
nullptr;
2693 __block
unsigned nlist_count = 0;
2694 __block
char *string_table =
nullptr;
2695 __block vm_offset_t vm_nlist_memory = 0;
2696 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2697 __block vm_offset_t vm_string_memory = 0;
2698 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2700 auto _ = llvm::make_scope_exit(^{
2701 if (vm_nlist_memory)
2702 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2703 if (vm_string_memory)
2704 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2707 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2708 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2709 UndefinedNameToDescMap undefined_name_to_desc;
2710 SymbolIndexToName reexport_shlib_needs_fixup;
2712 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2714 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2718 if (process_shared_cache_uuid.
IsValid() &&
2719 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2722 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2727 dyld_image_copy_uuid(image, &dsc_image_uuid);
2728 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2735 dyld_image_local_nlist_content_4Symbolication(
2736 image, ^(
const void *nlistStart, uint64_t nlistCount,
2737 const char *stringTable) {
2738 if (!nlistStart || !nlistCount)
2746 nlist_byte_size * nlistCount, &vm_nlist_memory,
2747 &vm_nlist_bytes_read);
2750 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2755 vm_address_t string_address = (vm_address_t)stringTable;
2756 vm_size_t region_size;
2757 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2758 vm_region_basic_info_data_t info;
2759 memory_object_name_t object;
2761 ®ion_size, VM_REGION_BASIC_INFO_64,
2762 (vm_region_info_t)&info, &info_count, &
object);
2768 ((vm_address_t)stringTable - string_address),
2769 &vm_string_memory, &vm_string_bytes_read);
2773 nlist_buffer = (
void *)vm_nlist_memory;
2774 string_table = (
char *)vm_string_memory;
2775 nlist_count = nlistCount;
2781 nlist_count * nlist_byte_size,
2782 byte_order, addr_byte_size);
2783 unmapped_local_symbols_found = nlist_count;
2789 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2794 for (uint32_t nlist_index = 0;
2795 nlist_index < nlist_count;
2799 std::optional<struct nlist_64> nlist_maybe =
2800 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2804 struct nlist_64 nlist = *nlist_maybe;
2807 const char *symbol_name = string_table + nlist.n_strx;
2809 if (symbol_name == NULL) {
2814 "DSC unmapped local symbol[{0}] has invalid "
2815 "string table offset {1:x} in {2}, ignoring symbol",
2816 nlist_index, nlist.n_strx,
2817 module_sp->GetFileSpec().GetPath()));
2820 if (symbol_name[0] ==
'\0')
2823 const char *symbol_name_non_abi_mangled = NULL;
2826 bool add_nlist =
true;
2827 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2828 bool demangled_is_synthesized =
false;
2829 bool is_gsym =
false;
2830 bool set_value =
true;
2832 assert(sym_idx < num_syms);
2837 switch (nlist.n_type) {
2857 symbol_name, symbol_name_non_abi_mangled,
2859 demangled_is_synthesized =
true;
2861 if (nlist.n_value != 0)
2863 nlist.n_sect, nlist.n_value);
2879 nlist.n_sect, nlist.n_value);
2881 N_FUN_addr_to_sym_idx.insert(
2882 std::make_pair(nlist.n_value, sym_idx));
2886 N_FUN_indexes.push_back(sym_idx);
2890 if (!N_FUN_indexes.empty()) {
2897 N_FUN_indexes.pop_back();
2909 N_STSYM_addr_to_sym_idx.insert(
2910 std::make_pair(nlist.n_value, sym_idx));
2911 symbol_section = section_info.
GetSection(nlist.n_sect,
2913 if (symbol_name && symbol_name[0]) {
2921 symbol_section = section_info.
GetSection(nlist.n_sect,
2955 symbol_section = section_info.
GetSection(nlist.n_sect,
2968 if (symbol_name == NULL) {
2979 N_NSYM_indexes.clear();
2980 N_INCL_indexes.clear();
2981 N_BRAC_indexes.clear();
2982 N_COMM_indexes.clear();
2983 N_FUN_indexes.clear();
2989 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2990 if (N_SO_has_full_path) {
2991 if ((N_SO_index == sym_idx - 1) &&
2992 ((sym_idx - 1) < num_syms)) {
2998 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3004 N_SO_index = sym_idx;
3006 }
else if ((N_SO_index == sym_idx - 1) &&
3007 ((sym_idx - 1) < num_syms)) {
3012 const char *so_path = sym[sym_idx - 1]
3016 if (so_path && so_path[0]) {
3017 std::string full_so_path(so_path);
3018 const size_t double_slash_pos =
3019 full_so_path.find(
"//");
3020 if (double_slash_pos != std::string::npos) {
3031 &full_so_path[double_slash_pos + 1],
3032 FileSpec::Style::native);
3035 full_so_path.erase(0, double_slash_pos + 1);
3039 if (*full_so_path.rbegin() !=
'/')
3040 full_so_path +=
'/';
3041 full_so_path += symbol_name;
3045 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3049 N_SO_index = sym_idx;
3070 N_INCL_indexes.push_back(sym_idx);
3080 if (!N_INCL_indexes.empty()) {
3085 N_INCL_indexes.pop_back();
3120 symbol_section = section_info.
GetSection(nlist.n_sect,
3131 symbol_section = section_info.
GetSection(nlist.n_sect,
3133 N_BRAC_indexes.push_back(sym_idx);
3143 symbol_section = section_info.
GetSection(nlist.n_sect,
3145 if (!N_BRAC_indexes.empty()) {
3150 N_BRAC_indexes.pop_back();
3167 N_COMM_indexes.push_back(sym_idx);
3172 symbol_section = section_info.
GetSection(nlist.n_sect,
3183 if (!N_COMM_indexes.empty()) {
3188 N_COMM_indexes.pop_back();
3203 uint8_t n_type = N_TYPE & nlist.n_type;
3204 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3208 const char *reexport_name_cstr =
3209 strtab_data.PeekCStr(nlist.n_value);
3210 if (reexport_name_cstr && reexport_name_cstr[0]) {
3213 reexport_name_cstr +
3214 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3217 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3219 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3225 if (symbol_name && symbol_name[0]) {
3227 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3228 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3240 symbol_section = section_info.
GetSection(nlist.n_sect,
3243 if (symbol_section == NULL) {
3249 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3252 uint32_t section_type =
3253 symbol_section->Get() & SECTION_TYPE;
3255 switch (section_type) {
3256 case S_CSTRING_LITERALS:
3259 case S_4BYTE_LITERALS:
3262 case S_8BYTE_LITERALS:
3265 case S_LITERAL_POINTERS:
3268 case S_NON_LAZY_SYMBOL_POINTERS:
3272 case S_LAZY_SYMBOL_POINTERS:
3275 case S_SYMBOL_STUBS:
3279 case S_MOD_INIT_FUNC_POINTERS:
3283 case S_MOD_TERM_FUNC_POINTERS:
3291 case S_16BYTE_LITERALS:
3297 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3301 switch (symbol_section->GetType()) {
3328 const char *symbol_sect_name =
3329 symbol_section->GetName().AsCString();
3330 if (symbol_section->IsDescendant(
3331 text_section_sp.get())) {
3332 if (symbol_section->IsClear(
3333 S_ATTR_PURE_INSTRUCTIONS |
3334 S_ATTR_SELF_MODIFYING_CODE |
3335 S_ATTR_SOME_INSTRUCTIONS))
3339 }
else if (symbol_section->IsDescendant(
3340 data_section_sp.get()) ||
3341 symbol_section->IsDescendant(
3342 data_dirty_section_sp.get()) ||
3343 symbol_section->IsDescendant(
3344 data_const_section_sp.get())) {
3345 if (symbol_sect_name &&
3346 ::strstr(symbol_sect_name,
"__objc") ==
3352 symbol_name_non_abi_mangled, type))
3353 demangled_is_synthesized =
true;
3354 }
else if (symbol_sect_name &&
3355 ::strstr(symbol_sect_name,
3356 "__gcc_except_tab") ==
3362 }
else if (symbol_sect_name &&
3363 ::strstr(symbol_sect_name,
"__IMPORT") ==
3366 }
else if (symbol_section->IsDescendant(
3367 objc_section_sp.get())) {
3369 if (symbol_name && symbol_name[0] ==
'.') {
3370 llvm::StringRef symbol_name_ref(symbol_name);
3372 g_objc_v1_prefix_class(
".objc_class_name_");
3373 if (symbol_name_ref.starts_with(
3374 g_objc_v1_prefix_class)) {
3375 symbol_name_non_abi_mangled = symbol_name;
3376 symbol_name = symbol_name +
3377 g_objc_v1_prefix_class.size();
3379 demangled_is_synthesized =
true;
3390 uint64_t symbol_value = nlist.n_value;
3391 if (symbol_name_non_abi_mangled) {
3397 if (symbol_name && symbol_name[0] ==
'_') {
3404 if (is_gsym && is_debug) {
3405 const char *gsym_name =
3411 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3415 if (symbol_section) {
3416 const addr_t section_file_addr =
3417 symbol_section->GetFileAddress();
3418 symbol_value -= section_file_addr;
3421 if (is_debug ==
false) {
3429 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3430 if (range.first != range.second) {
3431 bool found_it =
false;
3432 for (
auto pos = range.first; pos != range.second;
3434 if (sym[sym_idx].GetMangled().
GetName(
3438 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3444 sym[sym_idx].IsExternal());
3445 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3447 if (resolver_addresses.find(nlist.n_value) !=
3448 resolver_addresses.end())
3450 sym[sym_idx].
Clear();
3458 if (resolver_addresses.find(nlist.n_value) !=
3459 resolver_addresses.end())
3471 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3473 if (range.first != range.second) {
3474 bool found_it =
false;
3475 for (
auto pos = range.first; pos != range.second;
3477 if (sym[sym_idx].GetMangled().
GetName(
3481 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3487 sym[sym_idx].IsExternal());
3488 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3490 sym[sym_idx].
Clear();
3498 const char *gsym_name =
3506 ConstNameToSymbolIndexMap::const_iterator pos =
3507 N_GSYM_name_to_sym_idx.find(gsym_name);
3508 if (pos != N_GSYM_name_to_sym_idx.end()) {
3509 const uint32_t GSYM_sym_idx = pos->second;
3510 m_nlist_idx_to_sym_idx[nlist_idx] =
3519 add_symbol_addr(sym[GSYM_sym_idx]
3526 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3528 sym[sym_idx].
Clear();
3536 sym[sym_idx].
SetID(nlist_idx);
3542 sym[sym_idx].GetAddress().GetFileAddress());
3544 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3546 if (demangled_is_synthesized)
3550 sym[sym_idx].
Clear();
3557 for (
const auto &pos : reexport_shlib_needs_fixup) {
3558 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3559 if (undef_pos != undefined_name_to_desc.end()) {
3560 const uint8_t dylib_ordinal =
3561 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3562 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3572 if (nlist_data.GetByteSize() > 0) {
3576 if (sym ==
nullptr) {
3582 if (unmapped_local_symbols_found) {
3584 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3590 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3591 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3592 UndefinedNameToDescMap undefined_name_to_desc;
3593 SymbolIndexToName reexport_shlib_needs_fixup;
3601 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3603 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3604 if (is_debug != debug_only)
3607 const char *symbol_name_non_abi_mangled =
nullptr;
3608 const char *symbol_name =
nullptr;
3610 if (have_strtab_data) {
3611 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3613 if (symbol_name ==
nullptr) {
3617 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3619 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3622 if (symbol_name[0] ==
'\0')
3623 symbol_name =
nullptr;
3625 const addr_t str_addr = strtab_addr + nlist.n_strx;
3627 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3629 symbol_name = memory_symbol_name.c_str();
3634 bool add_nlist =
true;
3635 bool is_gsym =
false;
3636 bool demangled_is_synthesized =
false;
3637 bool set_value =
true;
3639 assert(sym_idx < num_syms);
3643 switch (nlist.n_type) {
3661 symbol_name_non_abi_mangled, type)) {
3662 demangled_is_synthesized =
true;
3664 if (nlist.n_value != 0)
3666 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3682 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3684 N_FUN_addr_to_sym_idx.insert(
3685 std::make_pair(nlist.n_value, sym_idx));
3689 N_FUN_indexes.push_back(sym_idx);
3693 if (!N_FUN_indexes.empty()) {
3698 N_FUN_indexes.pop_back();
3709 N_STSYM_addr_to_sym_idx.insert(
3710 std::make_pair(nlist.n_value, sym_idx));
3711 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3712 if (symbol_name && symbol_name[0]) {
3720 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3751 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3763 if (symbol_name ==
nullptr) {
3774 N_NSYM_indexes.clear();
3775 N_INCL_indexes.clear();
3776 N_BRAC_indexes.clear();
3777 N_COMM_indexes.clear();
3778 N_FUN_indexes.clear();
3784 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3785 if (N_SO_has_full_path) {
3786 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3791 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3796 N_SO_index = sym_idx;
3798 }
else if ((N_SO_index == sym_idx - 1) &&
3799 ((sym_idx - 1) < num_syms)) {
3803 const char *so_path =
3805 if (so_path && so_path[0]) {
3806 std::string full_so_path(so_path);
3807 const size_t double_slash_pos = full_so_path.find(
"//");
3808 if (double_slash_pos != std::string::npos) {
3816 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3817 FileSpec::Style::native);
3820 full_so_path.erase(0, double_slash_pos + 1);
3824 if (*full_so_path.rbegin() !=
'/')
3825 full_so_path +=
'/';
3826 full_so_path += symbol_name;
3830 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3834 N_SO_index = sym_idx;
3854 N_INCL_indexes.push_back(sym_idx);
3863 if (!N_INCL_indexes.empty()) {
3867 N_INCL_indexes.pop_back();
3902 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3911 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3912 N_BRAC_indexes.push_back(sym_idx);
3921 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3922 if (!N_BRAC_indexes.empty()) {
3926 N_BRAC_indexes.pop_back();
3942 N_COMM_indexes.push_back(sym_idx);
3947 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3956 if (!N_COMM_indexes.empty()) {
3960 N_COMM_indexes.pop_back();
3974 uint8_t n_type = N_TYPE & nlist.n_type;
3975 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3979 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3980 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3983 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3986 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3987 indirect_symbol_names.insert(
3988 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3994 if (symbol_name && symbol_name[0]) {
3996 ((symbol_name[0] ==
'_') ? 1 : 0));
3997 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4010 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4012 if (!symbol_section) {
4018 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4021 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4023 switch (section_type) {
4024 case S_CSTRING_LITERALS:
4027 case S_4BYTE_LITERALS:
4030 case S_8BYTE_LITERALS:
4033 case S_LITERAL_POINTERS:
4036 case S_NON_LAZY_SYMBOL_POINTERS:
4039 case S_LAZY_SYMBOL_POINTERS:
4042 case S_SYMBOL_STUBS:
4046 case S_MOD_INIT_FUNC_POINTERS:
4049 case S_MOD_TERM_FUNC_POINTERS:
4056 case S_16BYTE_LITERALS:
4062 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4066 switch (symbol_section->GetType()) {
4088 const char *symbol_sect_name =
4089 symbol_section->GetName().AsCString();
4090 if (symbol_section->IsDescendant(text_section_sp.get())) {
4091 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4092 S_ATTR_SELF_MODIFYING_CODE |
4093 S_ATTR_SOME_INSTRUCTIONS))
4097 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4098 symbol_section->IsDescendant(
4099 data_dirty_section_sp.get()) ||
4100 symbol_section->IsDescendant(
4101 data_const_section_sp.get())) {
4102 if (symbol_sect_name &&
4103 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4107 symbol_name, symbol_name_non_abi_mangled, type))
4108 demangled_is_synthesized =
true;
4109 }
else if (symbol_sect_name &&
4110 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4116 }
else if (symbol_sect_name &&
4117 ::strstr(symbol_sect_name,
"__IMPORT") ==
4120 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4122 if (symbol_name && symbol_name[0] ==
'.') {
4123 llvm::StringRef symbol_name_ref(symbol_name);
4124 llvm::StringRef g_objc_v1_prefix_class(
4125 ".objc_class_name_");
4126 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4127 symbol_name_non_abi_mangled = symbol_name;
4128 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4130 demangled_is_synthesized =
true;
4141 sym[sym_idx].
Clear();
4145 uint64_t symbol_value = nlist.n_value;
4147 if (symbol_name_non_abi_mangled) {
4153 if (symbol_name && symbol_name[0] ==
'_') {
4164 const char *gsym_name = sym[sym_idx]
4169 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4172 if (symbol_section) {
4173 const addr_t section_file_addr = symbol_section->GetFileAddress();
4174 symbol_value -= section_file_addr;
4183 std::pair<ValueToSymbolIndexMap::const_iterator,
4184 ValueToSymbolIndexMap::const_iterator>
4186 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4187 if (range.first != range.second) {
4188 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4189 pos != range.second; ++pos) {
4193 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4197 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4198 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4199 if (resolver_addresses.find(nlist.n_value) !=
4200 resolver_addresses.end())
4202 sym[sym_idx].
Clear();
4207 if (resolver_addresses.find(nlist.n_value) !=
4208 resolver_addresses.end())
4218 std::pair<ValueToSymbolIndexMap::const_iterator,
4219 ValueToSymbolIndexMap::const_iterator>
4221 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4222 if (range.first != range.second) {
4223 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4224 pos != range.second; ++pos) {
4228 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4232 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4233 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4234 sym[sym_idx].
Clear();
4240 const char *gsym_name = sym[sym_idx]
4245 ConstNameToSymbolIndexMap::const_iterator pos =
4246 N_GSYM_name_to_sym_idx.find(gsym_name);
4247 if (pos != N_GSYM_name_to_sym_idx.end()) {
4248 const uint32_t GSYM_sym_idx = pos->second;
4249 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4255 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4259 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4260 sym[sym_idx].
Clear();
4268 sym[sym_idx].
SetID(nlist_idx);
4274 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4276 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4277 if (nlist.n_desc & N_WEAK_REF)
4280 if (demangled_is_synthesized)
4289 std::vector<struct nlist_64> nlists;
4290 nlists.reserve(symtab_load_command.
nsyms);
4291 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4293 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4294 nlists.push_back(*nlist);
4304 for (
auto &nlist : nlists) {
4305 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4311 for (
auto &nlist : nlists) {
4316 for (
const auto &pos : reexport_shlib_needs_fixup) {
4317 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4318 if (undef_pos != undefined_name_to_desc.end()) {
4319 const uint8_t dylib_ordinal =
4320 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4321 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4329 int trie_symbol_table_augment_count = 0;
4330 for (
auto &e : external_sym_trie_entries) {
4331 if (!symbols_added.contains(e.entry.address))
4332 trie_symbol_table_augment_count++;
4335 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4336 num_syms = sym_idx + trie_symbol_table_augment_count;
4337 sym = symtab.
Resize(num_syms);
4339 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4342 for (
auto &e : external_sym_trie_entries) {
4343 if (symbols_added.contains(e.entry.address))
4349 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4351 const char *symbol_name = e.entry.name.GetCString();
4352 bool demangled_is_synthesized =
false;
4354 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4355 data_section_sp, data_dirty_section_sp,
4356 data_const_section_sp, symbol_section);
4359 if (symbol_section) {
4360 sym[sym_idx].
SetID(synthetic_sym_id++);
4362 if (demangled_is_synthesized)
4375 if (function_starts_count > 0) {
4376 uint32_t num_synthetic_function_symbols = 0;
4377 for (i = 0; i < function_starts_count; ++i) {
4378 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4379 ++num_synthetic_function_symbols;
4382 if (num_synthetic_function_symbols > 0) {
4383 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4384 num_syms = sym_idx + num_synthetic_function_symbols;
4385 sym = symtab.
Resize(num_syms);
4387 for (i = 0; i < function_starts_count; ++i) {
4388 const FunctionStarts::Entry *func_start_entry =
4389 function_starts.GetEntryAtIndex(i);
4390 if (!symbols_added.contains(func_start_entry->addr)) {
4391 addr_t symbol_file_addr = func_start_entry->addr;
4392 uint32_t symbol_flags = 0;
4393 if (func_start_entry->data)
4396 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4398 if (symbol_section) {
4399 sym[sym_idx].
SetID(synthetic_sym_id++);
4409 sym[sym_idx].
SetFlags(symbol_flags);
4420 if (sym_idx < num_syms) {
4422 sym = symtab.
Resize(num_syms);
4427 if (indirect_symbol_index_data.GetByteSize()) {
4428 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4429 m_nlist_idx_to_sym_idx.end();
4436 if (symbol_stub_byte_size == 0)
4439 const uint32_t num_symbol_stubs =
4442 if (num_symbol_stubs == 0)
4445 const uint32_t symbol_stub_index_offset =
4447 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4448 const uint32_t symbol_stub_index =
4449 symbol_stub_index_offset + stub_idx;
4452 (stub_idx * symbol_stub_byte_size);
4454 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4455 symbol_stub_offset, 4)) {
4456 const uint32_t stub_sym_id =
4457 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4458 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4461 NListIndexToSymbolIndexMap::const_iterator index_pos =
4462 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4463 Symbol *stub_symbol =
nullptr;
4464 if (index_pos != end_index_pos) {
4475 Address so_addr(symbol_stub_addr, section_list);
4482 if (resolver_addresses.find(symbol_stub_addr) ==
4483 resolver_addresses.end())
4493 if (sym_idx >= num_syms) {
4494 sym = symtab.
Resize(++num_syms);
4495 stub_symbol =
nullptr;
4497 sym[sym_idx].
SetID(synthetic_sym_id++);
4498 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4499 if (resolver_addresses.find(symbol_stub_addr) ==
4500 resolver_addresses.end())
4512 log->
Warning(
"symbol stub referencing symbol table symbol "
4513 "%u that isn't in our minimal symbol table, "
4524 if (!reexport_trie_entries.empty()) {
4525 for (
const auto &e : reexport_trie_entries) {
4526 if (e.entry.import_name) {
4529 if (indirect_symbol_names.find(e.entry.name) ==
4530 indirect_symbol_names.end()) {
4532 if (sym_idx >= num_syms)
4533 sym = symtab.
Resize(++num_syms);
4534 sym[sym_idx].
SetID(synthetic_sym_id++);
4539 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
6328 Target &target = process_sp->GetTarget();
6330 const llvm::Triple &target_triple = target_arch.
GetTriple();
6331 if (target_triple.getVendor() == llvm::Triple::Apple &&
6332 (target_triple.getOS() == llvm::Triple::MacOSX ||
6333 target_triple.getOS() == llvm::Triple::IOS ||
6334 target_triple.getOS() == llvm::Triple::WatchOS ||
6335 target_triple.getOS() == llvm::Triple::TvOS ||
6336 target_triple.getOS() == llvm::Triple::BridgeOS ||
6337 target_triple.getOS() == llvm::Triple::XROS)) {
6338 bool make_core =
false;
6340 case llvm::Triple::aarch64:
6341 case llvm::Triple::aarch64_32:
6342 case llvm::Triple::arm:
6343 case llvm::Triple::thumb:
6344 case llvm::Triple::x86:
6345 case llvm::Triple::x86_64:
6350 "unsupported core architecture: %s", target_triple.str().c_str());
6356 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6357 if (
error.Success()) {
6360 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6361 for (
const auto &core_range_info : core_ranges) {
6363 const auto &core_range = core_range_info.data;
6364 uint32_t cmd_type = LC_SEGMENT_64;
6365 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6366 if (addr_byte_size == 4) {
6367 cmd_type = LC_SEGMENT;
6368 segment_size =
sizeof(llvm::MachO::segment_command);
6372 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6374 uint32_t vm_prot = 0;
6375 if (core_range.lldb_permissions & ePermissionsReadable)
6376 vm_prot |= VM_PROT_READ;
6377 if (core_range.lldb_permissions & ePermissionsWritable)
6378 vm_prot |= VM_PROT_WRITE;
6379 if (core_range.lldb_permissions & ePermissionsExecutable)
6380 vm_prot |= VM_PROT_EXECUTE;
6381 const addr_t vm_addr = core_range.range.start();
6382 const addr_t vm_size = core_range.range.size();
6383 llvm::MachO::segment_command_64 segment = {
6395 segment_load_commands.push_back(segment);
6400 llvm::MachO::mach_header_64 mach_header;
6401 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6404 mach_header.filetype = MH_CORE;
6405 mach_header.ncmds = segment_load_commands.size();
6406 mach_header.flags = 0;
6407 mach_header.reserved = 0;
6408 ThreadList &thread_list = process_sp->GetThreadList();
6409 const uint32_t num_threads = thread_list.
GetSize();
6415 std::vector<StreamString> LC_THREAD_datas(num_threads);
6416 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6418 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6419 LC_THREAD_data.SetByteOrder(byte_order);
6421 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6424 switch (mach_header.cputype) {
6425 case llvm::MachO::CPU_TYPE_ARM64:
6426 case llvm::MachO::CPU_TYPE_ARM64_32:
6428 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6431 case llvm::MachO::CPU_TYPE_ARM:
6433 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6436 case llvm::MachO::CPU_TYPE_X86_64:
6438 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6441 case llvm::MachO::CPU_TYPE_RISCV:
6443 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6450 if (addr_byte_size == 8) {
6451 mach_header.sizeofcmds = segment_load_commands.size() *
6452 sizeof(llvm::MachO::segment_command_64);
6454 mach_header.sizeofcmds = segment_load_commands.size() *
6455 sizeof(llvm::MachO::segment_command);
6459 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6460 ++mach_header.ncmds;
6461 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6466 uint64_t address_mask = process_sp->GetCodeAddressMask();
6469 mach_header.ncmds++;
6470 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6474 mach_header.ncmds++;
6475 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6478 mach_header.ncmds++;
6479 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6482 buffer.
PutHex32(mach_header.magic);
6483 buffer.
PutHex32(mach_header.cputype);
6484 buffer.
PutHex32(mach_header.cpusubtype);
6485 buffer.
PutHex32(mach_header.filetype);
6486 buffer.
PutHex32(mach_header.ncmds);
6487 buffer.
PutHex32(mach_header.sizeofcmds);
6488 buffer.
PutHex32(mach_header.flags);
6489 if (addr_byte_size == 8) {
6490 buffer.
PutHex32(mach_header.reserved);
6495 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6497 file_offset = llvm::alignTo(file_offset, 16);
6498 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6502 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6504 addrable_bits_lcnote_up->name =
"addrable bits";
6505 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6506 int bits = std::bitset<64>(~address_mask).count();
6507 addrable_bits_lcnote_up->payload.PutHex32(4);
6508 addrable_bits_lcnote_up->payload.PutHex32(
6510 addrable_bits_lcnote_up->payload.PutHex32(
6512 addrable_bits_lcnote_up->payload.PutHex32(0);
6514 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6516 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6520 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6522 thread_extrainfo_lcnote_up->name =
"process metadata";
6523 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6526 std::make_shared<StructuredData::Dictionary>());
6528 std::make_shared<StructuredData::Array>());
6530 process_sp->CalculateCoreFileThreadList(options)) {
6532 std::make_shared<StructuredData::Dictionary>());
6533 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6534 threads->AddItem(thread);
6536 dict->AddItem(
"threads", threads);
6538 dict->Dump(strm,
false);
6542 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6543 file_offset = llvm::alignTo(file_offset, 16);
6544 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6547 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6549 all_image_infos_lcnote_up->name =
"all image infos";
6550 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6552 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6554 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6557 for (
auto &lcnote : lc_notes) {
6560 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6562 memset(namebuf, 0,
sizeof(namebuf));
6568 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6570 buffer.
PutHex64(lcnote->payload_file_offset);
6571 buffer.
PutHex64(lcnote->payload.GetSize());
6575 file_offset = llvm::alignTo(file_offset, 4096);
6577 for (
auto &segment : segment_load_commands) {
6578 segment.fileoff = file_offset;
6579 file_offset += segment.filesize;
6583 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6584 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6586 buffer.
PutHex32(8 + LC_THREAD_data_size);
6587 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6591 for (
const auto &segment : segment_load_commands) {
6594 buffer.
PutRawBytes(segment.segname,
sizeof(segment.segname));
6595 if (addr_byte_size == 8) {
6601 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmaddr));
6602 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmsize));
6603 buffer.
PutHex32(
static_cast<uint32_t
>(segment.fileoff));
6604 buffer.
PutHex32(
static_cast<uint32_t
>(segment.filesize));
6612 std::string core_file_path(outfile.
GetPath());
6620 uint8_t bytes[0x1000];
6622 size_t bytes_written = buffer.
GetString().size();
6624 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6625 if (
error.Success()) {
6627 for (
auto &lcnote : lc_notes) {
6628 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6631 "Unable to seek to corefile pos "
6632 "to write '%s' LC_NOTE payload",
6633 lcnote->name.c_str());
6636 bytes_written = lcnote->payload.GetSize();
6637 error = core_file.get()->Write(lcnote->payload.GetData(),
6639 if (!
error.Success())
6644 for (
const auto &segment : segment_load_commands) {
6645 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6647 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6648 segment.fileoff, core_file_path.c_str());
6654 " bytes of data for memory region at 0x%" PRIx64
"\n",
6655 segment.vmsize, segment.vmaddr);
6656 addr_t bytes_left = segment.vmsize;
6657 addr_t addr = segment.vmaddr;
6659 while (bytes_left > 0 &&
error.Success()) {
6660 const size_t bytes_to_read =
6661 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6666 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6669 if (bytes_read == bytes_to_read) {
6670 size_t bytes_written = bytes_read;
6671 error = core_file.get()->Write(bytes, bytes_written);
6672 bytes_left -= bytes_read;
6677 memset(bytes, 0, bytes_to_read);
6678 size_t bytes_written = bytes_to_read;
6679 error = core_file.get()->Write(bytes, bytes_written);
6680 bytes_left -= bytes_to_read;
6681 addr += bytes_to_read;