2209 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2210 Progress progress(
"Parsing symbol table", file_name);
2225 llvm::DenseSet<addr_t> symbols_added;
2229 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2233 symbols_added.insert(file_addr);
2235 FunctionStarts function_starts;
2241 for (i = 0; i <
m_header.ncmds; ++i) {
2244 llvm::MachO::load_command lc;
2245 if (
m_data_nsp->GetU32(&offset, &lc, 2) ==
nullptr)
2250 llvm::MachO::symtab_command lc_obj;
2251 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2252 lc_obj.cmd = lc.cmd;
2253 lc_obj.cmdsize = lc.cmdsize;
2254 symtab_load_command = lc_obj;
2259 case LC_DYLD_INFO_ONLY: {
2260 llvm::MachO::dyld_info_command lc_obj;
2261 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2262 lc_obj.cmd = lc.cmd;
2263 lc_obj.cmdsize = lc.cmdsize;
2269 case LC_LOAD_WEAK_DYLIB:
2270 case LC_REEXPORT_DYLIB:
2272 case LC_LOAD_UPWARD_DYLIB: {
2273 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2274 const char *path =
m_data_nsp->PeekCStr(name_offset);
2282 if (lc.cmd == LC_REEXPORT_DYLIB) {
2286 dylib_files.
Append(file_spec);
2290 case LC_DYLD_EXPORTS_TRIE: {
2291 llvm::MachO::linkedit_data_command lc_obj;
2292 lc_obj.cmd = lc.cmd;
2293 lc_obj.cmdsize = lc.cmdsize;
2294 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2295 exports_trie_load_command = lc_obj;
2297 case LC_FUNCTION_STARTS: {
2298 llvm::MachO::linkedit_data_command lc_obj;
2299 lc_obj.cmd = lc.cmd;
2300 lc_obj.cmdsize = lc.cmdsize;
2301 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2302 function_starts_load_command = lc_obj;
2306 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2309 image_uuid =
UUID(uuid_bytes, 16);
2316 offset = cmd_offset + lc.cmdsize;
2319 if (!symtab_load_command.
cmd)
2323 if (section_list ==
nullptr)
2326 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2328 bool bit_width_32 = addr_byte_size == 4;
2329 const size_t nlist_byte_size =
2330 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2332 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2333 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2334 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2335 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2337 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2339 const
addr_t nlist_data_byte_size =
2340 symtab_load_command.nsyms * nlist_byte_size;
2341 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2344 ProcessSP process_sp(m_process_wp.lock());
2345 Process *process = process_sp.get();
2349 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2359 section_list->FindSectionByName(g_segment_name_TEXT));
2361 section_list->FindSectionByName(g_segment_name_DATA));
2363 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2365 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2367 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2369 section_list->FindSectionByName(g_segment_name_OBJC));
2372 if (text_section_sp.get()) {
2373 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2374 g_section_name_eh_frame);
2375 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2376 g_section_name_lldb_no_nlist);
2378 eh_frame_section_sp =
2380 lldb_no_nlist_section_sp =
2384 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2385 !is_local_shared_cache_image) {
2386 Target &target = process->GetTarget();
2395 if (lldb_no_nlist_section_sp)
2400 if (linkedit_section_sp) {
2401 addr_t linkedit_load_addr =
2402 linkedit_section_sp->GetLoadBaseAddress(&target);
2412 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2413 const addr_t symoff_addr = linkedit_load_addr +
2414 symtab_load_command.
symoff -
2415 linkedit_file_offset;
2416 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2417 linkedit_file_offset;
2425 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2427 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2429 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2431 const addr_t indirect_syms_addr = linkedit_load_addr +
2433 linkedit_file_offset;
2435 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2436 if (indirect_syms_data_sp)
2437 indirect_symbol_index_data.SetData(
2438 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2448 if (!is_shared_cache_image) {
2450 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2451 if (strtab_data_sp) {
2452 strtab_data.SetData(strtab_data_sp, 0,
2453 strtab_data_sp->GetByteSize());
2458 if (function_starts_load_command.
cmd) {
2459 const addr_t func_start_addr =
2460 linkedit_load_addr + function_starts_load_command.
dataoff -
2461 linkedit_file_offset;
2464 function_starts_load_command.
datasize));
2465 if (func_start_data_sp)
2466 function_starts_data.SetData(func_start_data_sp, 0,
2467 func_start_data_sp->GetByteSize());
2473 if (is_local_shared_cache_image) {
2481 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2484 symtab_load_command.
symoff += linkedit_slide;
2485 symtab_load_command.
stroff += linkedit_slide;
2488 function_starts_load_command.
dataoff += linkedit_slide;
2489 exports_trie_load_command.
dataoff += linkedit_slide;
2493 nlist_data_byte_size);
2494 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2495 strtab_data_byte_size);
2500 && (exports_trie_load_command.
datasize > 0)));
2504 }
else if (exports_trie_load_command.
datasize > 0) {
2507 exports_trie_load_command.
datasize);
2511 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2514 if (function_starts_load_command.
cmd) {
2515 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2516 function_starts_load_command.
dataoff,
2517 function_starts_load_command.
datasize);
2521 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2523 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2540 if (text_section_sp && function_starts_data.GetByteSize()) {
2541 FunctionStarts::Entry function_start_entry;
2542 function_start_entry.data =
false;
2544 function_start_entry.addr = text_section_sp->GetFileAddress();
2546 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2549 function_start_entry.addr += delta;
2551 if (function_start_entry.addr & 1) {
2553 function_start_entry.data =
true;
2554 }
else if (always_thumb) {
2555 function_start_entry.data =
true;
2558 function_starts.Append(function_start_entry);
2566 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2572 addr_t text_base_addr = text_section_sp->GetFileAddress();
2573 size_t count = functions.
GetSize();
2574 for (
size_t i = 0; i < count; ++i) {
2578 FunctionStarts::Entry function_start_entry;
2579 function_start_entry.addr = func->
base - text_base_addr;
2581 if (function_start_entry.addr & 1) {
2583 function_start_entry.data =
true;
2584 }
else if (always_thumb) {
2585 function_start_entry.data =
true;
2588 function_starts.Append(function_start_entry);
2594 const size_t function_starts_count = function_starts.GetSize();
2609 if (unwind_or_symbol_log)
2610 module_sp->LogMessage(
2611 unwind_or_symbol_log,
2612 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2615 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2616 ? eh_frame_section_sp->GetID()
2622 std::vector<uint32_t> N_FUN_indexes;
2623 std::vector<uint32_t> N_NSYM_indexes;
2624 std::vector<uint32_t> N_INCL_indexes;
2625 std::vector<uint32_t> N_BRAC_indexes;
2626 std::vector<uint32_t> N_COMM_indexes;
2627 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2628 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2629 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2630 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2631 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2632 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2635 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2636 uint32_t nlist_idx = 0;
2637 Symbol *symbol_ptr =
nullptr;
2639 uint32_t sym_idx = 0;
2641 size_t num_syms = 0;
2642 std::string memory_symbol_name;
2643 uint32_t unmapped_local_symbols_found = 0;
2645 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2646 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2647 std::set<lldb::addr_t> resolver_addresses;
2649 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2650 if (dyld_trie_data_size > 0) {
2651 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2655 if (text_segment_sp)
2656 text_segment_file_addr = text_segment_sp->GetFileAddress();
2658 ParseTrieEntries(dyld_trie_data, 0, is_arm, text_segment_file_addr, prefix,
2659 resolver_addresses, reexport_trie_entries,
2660 external_sym_trie_entries);
2663 typedef std::set<ConstString> IndirectSymbols;
2664 IndirectSymbols indirect_symbol_names;
2687 UUID process_shared_cache_uuid;
2688 addr_t process_shared_cache_base_addr;
2692 process_shared_cache_uuid);
2695 __block
bool found_image =
false;
2696 __block
void *nlist_buffer =
nullptr;
2697 __block
unsigned nlist_count = 0;
2698 __block
char *string_table =
nullptr;
2699 __block vm_offset_t vm_nlist_memory = 0;
2700 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2701 __block vm_offset_t vm_string_memory = 0;
2702 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2704 llvm::scope_exit _(^{
2705 if (vm_nlist_memory)
2706 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2707 if (vm_string_memory)
2708 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2711 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2712 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2713 UndefinedNameToDescMap undefined_name_to_desc;
2714 SymbolIndexToName reexport_shlib_needs_fixup;
2722 if (process_shared_cache_uuid.
IsValid() &&
2723 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2732 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2739 dyld_image_local_nlist_content_4Symbolication(
2740 image, ^(
const void *nlistStart, uint64_t nlistCount,
2741 const char *stringTable) {
2742 if (!nlistStart || !nlistCount)
2750 nlist_byte_size * nlistCount, &vm_nlist_memory,
2751 &vm_nlist_bytes_read);
2754 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2759 vm_address_t string_address = (vm_address_t)stringTable;
2760 vm_size_t region_size;
2761 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2762 vm_region_basic_info_data_t info;
2763 memory_object_name_t object;
2765 ®ion_size, VM_REGION_BASIC_INFO_64,
2766 (vm_region_info_t)&info, &info_count, &
object);
2772 ((vm_address_t)stringTable - string_address),
2773 &vm_string_memory, &vm_string_bytes_read);
2777 nlist_buffer = (
void *)vm_nlist_memory;
2778 string_table = (
char *)vm_string_memory;
2779 nlist_count = nlistCount;
2785 nlist_count * nlist_byte_size,
2786 byte_order, addr_byte_size);
2787 unmapped_local_symbols_found = nlist_count;
2793 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2798 for (uint32_t nlist_index = 0;
2799 nlist_index < nlist_count;
2803 std::optional<struct nlist_64> nlist_maybe =
2804 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2808 struct nlist_64 nlist = *nlist_maybe;
2811 const char *symbol_name = string_table + nlist.n_strx;
2813 if (symbol_name == NULL) {
2818 "DSC unmapped local symbol[{0}] has invalid "
2819 "string table offset {1:x} in {2}, ignoring symbol",
2820 nlist_index, nlist.n_strx,
2821 module_sp->GetFileSpec().GetPath()));
2824 if (symbol_name[0] ==
'\0')
2827 const char *symbol_name_non_abi_mangled = NULL;
2830 bool add_nlist =
true;
2831 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2832 bool demangled_is_synthesized =
false;
2833 bool is_gsym =
false;
2834 bool set_value =
true;
2836 assert(sym_idx < num_syms);
2841 switch (nlist.n_type) {
2861 symbol_name, symbol_name_non_abi_mangled,
2863 demangled_is_synthesized =
true;
2865 if (nlist.n_value != 0)
2867 nlist.n_sect, nlist.n_value);
2883 nlist.n_sect, nlist.n_value);
2885 N_FUN_addr_to_sym_idx.insert(
2886 std::make_pair(nlist.n_value, sym_idx));
2890 N_FUN_indexes.push_back(sym_idx);
2894 if (!N_FUN_indexes.empty()) {
2901 N_FUN_indexes.pop_back();
2913 N_STSYM_addr_to_sym_idx.insert(
2914 std::make_pair(nlist.n_value, sym_idx));
2915 symbol_section = section_info.
GetSection(nlist.n_sect,
2917 if (symbol_name && symbol_name[0]) {
2925 symbol_section = section_info.
GetSection(nlist.n_sect,
2959 symbol_section = section_info.
GetSection(nlist.n_sect,
2972 if (symbol_name == NULL) {
2983 N_NSYM_indexes.clear();
2984 N_INCL_indexes.clear();
2985 N_BRAC_indexes.clear();
2986 N_COMM_indexes.clear();
2987 N_FUN_indexes.clear();
2993 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2994 if (N_SO_has_full_path) {
2995 if ((N_SO_index == sym_idx - 1) &&
2996 ((sym_idx - 1) < num_syms)) {
3002 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3008 N_SO_index = sym_idx;
3010 }
else if ((N_SO_index == sym_idx - 1) &&
3011 ((sym_idx - 1) < num_syms)) {
3016 const char *so_path = sym[sym_idx - 1]
3020 if (so_path && so_path[0]) {
3021 std::string full_so_path(so_path);
3022 const size_t double_slash_pos =
3023 full_so_path.find(
"//");
3024 if (double_slash_pos != std::string::npos) {
3035 &full_so_path[double_slash_pos + 1],
3036 FileSpec::Style::native);
3039 full_so_path.erase(0, double_slash_pos + 1);
3043 if (*full_so_path.rbegin() !=
'/')
3044 full_so_path +=
'/';
3045 full_so_path += symbol_name;
3049 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3053 N_SO_index = sym_idx;
3074 N_INCL_indexes.push_back(sym_idx);
3084 if (!N_INCL_indexes.empty()) {
3089 N_INCL_indexes.pop_back();
3124 symbol_section = section_info.
GetSection(nlist.n_sect,
3135 symbol_section = section_info.
GetSection(nlist.n_sect,
3137 N_BRAC_indexes.push_back(sym_idx);
3147 symbol_section = section_info.
GetSection(nlist.n_sect,
3149 if (!N_BRAC_indexes.empty()) {
3154 N_BRAC_indexes.pop_back();
3171 N_COMM_indexes.push_back(sym_idx);
3176 symbol_section = section_info.
GetSection(nlist.n_sect,
3187 if (!N_COMM_indexes.empty()) {
3192 N_COMM_indexes.pop_back();
3207 uint8_t n_type = N_TYPE & nlist.n_type;
3208 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3212 const char *reexport_name_cstr =
3213 strtab_data.PeekCStr(nlist.n_value);
3214 if (reexport_name_cstr && reexport_name_cstr[0]) {
3217 reexport_name_cstr +
3218 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3221 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3223 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3229 if (symbol_name && symbol_name[0]) {
3231 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3232 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3244 symbol_section = section_info.
GetSection(nlist.n_sect,
3247 if (symbol_section == NULL) {
3253 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3256 uint32_t section_type =
3257 symbol_section->Get() & SECTION_TYPE;
3259 switch (section_type) {
3260 case S_CSTRING_LITERALS:
3263 case S_4BYTE_LITERALS:
3266 case S_8BYTE_LITERALS:
3269 case S_LITERAL_POINTERS:
3272 case S_NON_LAZY_SYMBOL_POINTERS:
3276 case S_LAZY_SYMBOL_POINTERS:
3279 case S_SYMBOL_STUBS:
3283 case S_MOD_INIT_FUNC_POINTERS:
3287 case S_MOD_TERM_FUNC_POINTERS:
3295 case S_16BYTE_LITERALS:
3301 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3305 switch (symbol_section->GetType()) {
3332 const char *symbol_sect_name =
3333 symbol_section->GetName().AsCString(
nullptr);
3334 if (symbol_section->IsDescendant(
3335 text_section_sp.get())) {
3336 if (symbol_section->IsClear(
3337 S_ATTR_PURE_INSTRUCTIONS |
3338 S_ATTR_SELF_MODIFYING_CODE |
3339 S_ATTR_SOME_INSTRUCTIONS))
3343 }
else if (symbol_section->IsDescendant(
3344 data_section_sp.get()) ||
3345 symbol_section->IsDescendant(
3346 data_dirty_section_sp.get()) ||
3347 symbol_section->IsDescendant(
3348 data_const_section_sp.get())) {
3349 if (symbol_sect_name &&
3350 ::strstr(symbol_sect_name,
"__objc") ==
3356 symbol_name_non_abi_mangled, type))
3357 demangled_is_synthesized =
true;
3358 }
else if (symbol_sect_name &&
3359 ::strstr(symbol_sect_name,
3360 "__gcc_except_tab") ==
3366 }
else if (symbol_sect_name &&
3367 ::strstr(symbol_sect_name,
"__IMPORT") ==
3370 }
else if (symbol_section->IsDescendant(
3371 objc_section_sp.get())) {
3373 if (symbol_name && symbol_name[0] ==
'.') {
3374 llvm::StringRef symbol_name_ref(symbol_name);
3376 g_objc_v1_prefix_class(
".objc_class_name_");
3377 if (symbol_name_ref.starts_with(
3378 g_objc_v1_prefix_class)) {
3379 symbol_name_non_abi_mangled = symbol_name;
3380 symbol_name = symbol_name +
3381 g_objc_v1_prefix_class.size();
3383 demangled_is_synthesized =
true;
3394 uint64_t symbol_value = nlist.n_value;
3395 if (symbol_name_non_abi_mangled) {
3401 if (symbol_name && symbol_name[0] ==
'_') {
3408 if (is_gsym && is_debug) {
3409 const char *gsym_name =
3415 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3419 if (symbol_section) {
3420 const addr_t section_file_addr =
3421 symbol_section->GetFileAddress();
3422 symbol_value -= section_file_addr;
3425 if (is_debug ==
false) {
3433 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3434 if (range.first != range.second) {
3435 bool found_it =
false;
3436 for (
auto pos = range.first; pos != range.second;
3438 if (sym[sym_idx].GetMangled().
GetName(
3442 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3448 sym[sym_idx].IsExternal());
3449 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3451 if (resolver_addresses.find(nlist.n_value) !=
3452 resolver_addresses.end())
3454 sym[sym_idx].
Clear();
3462 if (resolver_addresses.find(nlist.n_value) !=
3463 resolver_addresses.end())
3475 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3477 if (range.first != range.second) {
3478 bool found_it =
false;
3479 for (
auto pos = range.first; pos != range.second;
3481 if (sym[sym_idx].GetMangled().
GetName(
3485 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3491 sym[sym_idx].IsExternal());
3492 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3494 sym[sym_idx].
Clear();
3502 const char *gsym_name =
3510 ConstNameToSymbolIndexMap::const_iterator pos =
3511 N_GSYM_name_to_sym_idx.find(gsym_name);
3512 if (pos != N_GSYM_name_to_sym_idx.end()) {
3513 const uint32_t GSYM_sym_idx = pos->second;
3514 m_nlist_idx_to_sym_idx[nlist_idx] =
3520 Address(symbol_section, symbol_value);
3521 add_symbol_addr(sym[GSYM_sym_idx]
3528 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3530 sym[sym_idx].
Clear();
3538 sym[sym_idx].
SetID(nlist_idx);
3542 Address(symbol_section, symbol_value);
3544 sym[sym_idx].GetAddress().GetFileAddress());
3546 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3548 if (demangled_is_synthesized)
3552 sym[sym_idx].
Clear();
3559 for (
const auto &pos : reexport_shlib_needs_fixup) {
3560 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3561 if (undef_pos != undefined_name_to_desc.end()) {
3562 const uint8_t dylib_ordinal =
3563 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3564 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3574 if (nlist_data.GetByteSize() > 0) {
3578 if (sym ==
nullptr) {
3584 if (unmapped_local_symbols_found) {
3586 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3592 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3593 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3594 UndefinedNameToDescMap undefined_name_to_desc;
3595 SymbolIndexToName reexport_shlib_needs_fixup;
3603 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3605 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3606 if (is_debug != debug_only)
3609 const char *symbol_name_non_abi_mangled =
nullptr;
3610 const char *symbol_name =
nullptr;
3612 if (have_strtab_data) {
3613 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3615 if (symbol_name ==
nullptr) {
3619 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3621 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3624 if (symbol_name[0] ==
'\0')
3625 symbol_name =
nullptr;
3627 const addr_t str_addr = strtab_addr + nlist.n_strx;
3629 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3631 symbol_name = memory_symbol_name.c_str();
3636 bool add_nlist =
true;
3637 bool is_gsym =
false;
3638 bool demangled_is_synthesized =
false;
3639 bool set_value =
true;
3641 assert(sym_idx < num_syms);
3645 switch (nlist.n_type) {
3663 symbol_name_non_abi_mangled, type)) {
3664 demangled_is_synthesized =
true;
3666 if (nlist.n_value != 0)
3668 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3684 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3686 N_FUN_addr_to_sym_idx.insert(
3687 std::make_pair(nlist.n_value, sym_idx));
3691 N_FUN_indexes.push_back(sym_idx);
3695 if (!N_FUN_indexes.empty()) {
3700 N_FUN_indexes.pop_back();
3711 N_STSYM_addr_to_sym_idx.insert(
3712 std::make_pair(nlist.n_value, sym_idx));
3713 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3714 if (symbol_name && symbol_name[0]) {
3722 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3753 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3765 if (symbol_name ==
nullptr) {
3776 N_NSYM_indexes.clear();
3777 N_INCL_indexes.clear();
3778 N_BRAC_indexes.clear();
3779 N_COMM_indexes.clear();
3780 N_FUN_indexes.clear();
3786 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3787 if (N_SO_has_full_path) {
3788 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3793 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3798 N_SO_index = sym_idx;
3800 }
else if ((N_SO_index == sym_idx - 1) &&
3801 ((sym_idx - 1) < num_syms)) {
3805 llvm::StringRef so_path = sym[sym_idx - 1]
3809 if (!so_path.empty()) {
3810 std::string full_so_path(so_path);
3811 const size_t double_slash_pos = full_so_path.find(
"//");
3812 if (double_slash_pos != std::string::npos) {
3820 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3821 FileSpec::Style::native);
3824 full_so_path.erase(0, double_slash_pos + 1);
3828 if (*full_so_path.rbegin() !=
'/')
3829 full_so_path +=
'/';
3830 full_so_path += symbol_name;
3834 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3838 N_SO_index = sym_idx;
3858 N_INCL_indexes.push_back(sym_idx);
3867 if (!N_INCL_indexes.empty()) {
3871 N_INCL_indexes.pop_back();
3906 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3915 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3916 N_BRAC_indexes.push_back(sym_idx);
3925 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3926 if (!N_BRAC_indexes.empty()) {
3930 N_BRAC_indexes.pop_back();
3946 N_COMM_indexes.push_back(sym_idx);
3951 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3960 if (!N_COMM_indexes.empty()) {
3964 N_COMM_indexes.pop_back();
3978 uint8_t n_type = N_TYPE & nlist.n_type;
3979 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3983 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3984 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3987 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3990 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3991 indirect_symbol_names.insert(
3992 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3998 if (symbol_name && symbol_name[0]) {
4000 ((symbol_name[0] ==
'_') ? 1 : 0));
4001 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4014 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4016 if (!symbol_section) {
4022 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4025 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4027 switch (section_type) {
4028 case S_CSTRING_LITERALS:
4031 case S_4BYTE_LITERALS:
4034 case S_8BYTE_LITERALS:
4037 case S_LITERAL_POINTERS:
4040 case S_NON_LAZY_SYMBOL_POINTERS:
4043 case S_LAZY_SYMBOL_POINTERS:
4046 case S_SYMBOL_STUBS:
4050 case S_MOD_INIT_FUNC_POINTERS:
4053 case S_MOD_TERM_FUNC_POINTERS:
4060 case S_16BYTE_LITERALS:
4066 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4070 switch (symbol_section->GetType()) {
4092 const char *symbol_sect_name =
4093 symbol_section->GetName().AsCString(
nullptr);
4094 if (symbol_section->IsDescendant(text_section_sp.get())) {
4095 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4096 S_ATTR_SELF_MODIFYING_CODE |
4097 S_ATTR_SOME_INSTRUCTIONS))
4101 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4102 symbol_section->IsDescendant(
4103 data_dirty_section_sp.get()) ||
4104 symbol_section->IsDescendant(
4105 data_const_section_sp.get())) {
4106 if (symbol_sect_name &&
4107 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4111 symbol_name, symbol_name_non_abi_mangled, type))
4112 demangled_is_synthesized =
true;
4113 }
else if (symbol_sect_name &&
4114 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4120 }
else if (symbol_sect_name &&
4121 ::strstr(symbol_sect_name,
"__IMPORT") ==
4124 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4126 if (symbol_name && symbol_name[0] ==
'.') {
4127 llvm::StringRef symbol_name_ref(symbol_name);
4128 llvm::StringRef g_objc_v1_prefix_class(
4129 ".objc_class_name_");
4130 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4131 symbol_name_non_abi_mangled = symbol_name;
4132 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4134 demangled_is_synthesized =
true;
4145 sym[sym_idx].
Clear();
4149 uint64_t symbol_value = nlist.n_value;
4151 if (symbol_name_non_abi_mangled) {
4157 if (symbol_name && symbol_name[0] ==
'_') {
4168 const char *gsym_name = sym[sym_idx]
4173 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4176 if (symbol_section) {
4177 const addr_t section_file_addr = symbol_section->GetFileAddress();
4178 symbol_value -= section_file_addr;
4187 std::pair<ValueToSymbolIndexMap::const_iterator,
4188 ValueToSymbolIndexMap::const_iterator>
4190 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4191 if (range.first != range.second) {
4192 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4193 pos != range.second; ++pos) {
4197 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4201 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4202 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4203 if (resolver_addresses.find(nlist.n_value) !=
4204 resolver_addresses.end())
4206 sym[sym_idx].
Clear();
4211 if (resolver_addresses.find(nlist.n_value) !=
4212 resolver_addresses.end())
4222 std::pair<ValueToSymbolIndexMap::const_iterator,
4223 ValueToSymbolIndexMap::const_iterator>
4225 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4226 if (range.first != range.second) {
4227 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4228 pos != range.second; ++pos) {
4232 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4236 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4237 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4238 sym[sym_idx].
Clear();
4244 const char *gsym_name = sym[sym_idx]
4249 ConstNameToSymbolIndexMap::const_iterator pos =
4250 N_GSYM_name_to_sym_idx.find(gsym_name);
4251 if (pos != N_GSYM_name_to_sym_idx.end()) {
4252 const uint32_t GSYM_sym_idx = pos->second;
4253 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4257 Address(symbol_section, symbol_value);
4259 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4263 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4264 sym[sym_idx].
Clear();
4272 sym[sym_idx].
SetID(nlist_idx);
4277 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4279 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4280 if (nlist.n_desc & N_WEAK_REF)
4283 if (demangled_is_synthesized)
4292 std::vector<struct nlist_64> nlists;
4293 nlists.reserve(symtab_load_command.
nsyms);
4294 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4296 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4297 nlists.push_back(*nlist);
4307 for (
auto &nlist : nlists) {
4308 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4314 for (
auto &nlist : nlists) {
4319 for (
const auto &pos : reexport_shlib_needs_fixup) {
4320 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4321 if (undef_pos != undefined_name_to_desc.end()) {
4322 const uint8_t dylib_ordinal =
4323 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4324 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4332 int trie_symbol_table_augment_count = 0;
4333 for (
auto &e : external_sym_trie_entries) {
4334 if (!symbols_added.contains(e.entry.address))
4335 trie_symbol_table_augment_count++;
4338 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4339 num_syms = sym_idx + trie_symbol_table_augment_count;
4340 sym = symtab.
Resize(num_syms);
4342 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4345 for (
auto &e : external_sym_trie_entries) {
4346 if (symbols_added.contains(e.entry.address))
4352 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4354 const char *symbol_name = e.entry.name.GetCString();
4355 bool demangled_is_synthesized =
false;
4357 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4358 data_section_sp, data_dirty_section_sp,
4359 data_const_section_sp, symbol_section);
4362 if (symbol_section) {
4363 sym[sym_idx].
SetID(synthetic_sym_id++);
4365 if (demangled_is_synthesized)
4378 if (function_starts_count > 0) {
4379 uint32_t num_synthetic_function_symbols = 0;
4380 for (i = 0; i < function_starts_count; ++i) {
4381 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4382 ++num_synthetic_function_symbols;
4385 if (num_synthetic_function_symbols > 0) {
4386 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4387 num_syms = sym_idx + num_synthetic_function_symbols;
4388 sym = symtab.
Resize(num_syms);
4390 for (i = 0; i < function_starts_count; ++i) {
4391 const FunctionStarts::Entry *func_start_entry =
4392 function_starts.GetEntryAtIndex(i);
4393 if (!symbols_added.contains(func_start_entry->addr)) {
4394 addr_t symbol_file_addr = func_start_entry->addr;
4395 uint32_t symbol_flags = 0;
4396 if (func_start_entry->data)
4399 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4401 if (symbol_section) {
4402 sym[sym_idx].
SetID(synthetic_sym_id++);
4412 sym[sym_idx].
SetFlags(symbol_flags);
4423 if (sym_idx < num_syms) {
4425 sym = symtab.
Resize(num_syms);
4430 if (indirect_symbol_index_data.GetByteSize()) {
4431 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4432 m_nlist_idx_to_sym_idx.end();
4439 if (symbol_stub_byte_size == 0)
4442 const uint32_t num_symbol_stubs =
4445 if (num_symbol_stubs == 0)
4448 const uint32_t symbol_stub_index_offset =
4450 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4451 const uint32_t symbol_stub_index =
4452 symbol_stub_index_offset + stub_idx;
4455 (stub_idx * symbol_stub_byte_size);
4457 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4458 symbol_stub_offset, 4)) {
4459 const uint32_t stub_sym_id =
4460 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4461 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4464 NListIndexToSymbolIndexMap::const_iterator index_pos =
4465 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4466 Symbol *stub_symbol =
nullptr;
4467 if (index_pos != end_index_pos) {
4478 Address so_addr(symbol_stub_addr, section_list);
4485 if (resolver_addresses.find(symbol_stub_addr) ==
4486 resolver_addresses.end())
4496 if (sym_idx >= num_syms) {
4497 sym = symtab.
Resize(++num_syms);
4498 stub_symbol =
nullptr;
4500 sym[sym_idx].
SetID(synthetic_sym_id++);
4501 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4502 if (resolver_addresses.find(symbol_stub_addr) ==
4503 resolver_addresses.end())
4515 "warning: symbol stub referencing symbol table "
4516 "symbol %u that isn't in our minimal symbol table, "
4527 if (!reexport_trie_entries.empty()) {
4528 for (
const auto &e : reexport_trie_entries) {
4529 if (e.entry.import_name) {
4532 if (indirect_symbol_names.find(e.entry.name) ==
4533 indirect_symbol_names.end()) {
4535 if (sym_idx >= num_syms)
4536 sym = symtab.
Resize(++num_syms);
4537 sym[sym_idx].
SetID(synthetic_sym_id++);
4542 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
6334 Target &target = process_sp->GetTarget();
6336 const llvm::Triple &target_triple = target_arch.
GetTriple();
6337 if (target_triple.getVendor() == llvm::Triple::Apple &&
6338 (target_triple.getOS() == llvm::Triple::MacOSX ||
6339 target_triple.getOS() == llvm::Triple::IOS ||
6340 target_triple.getOS() == llvm::Triple::WatchOS ||
6341 target_triple.getOS() == llvm::Triple::TvOS ||
6342 target_triple.getOS() == llvm::Triple::BridgeOS ||
6343 target_triple.getOS() == llvm::Triple::XROS)) {
6344 bool make_core =
false;
6346 case llvm::Triple::aarch64:
6347 case llvm::Triple::aarch64_32:
6348 case llvm::Triple::arm:
6349 case llvm::Triple::thumb:
6350 case llvm::Triple::x86:
6351 case llvm::Triple::x86_64:
6356 "unsupported core architecture: %s", target_triple.str().c_str());
6362 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6363 if (
error.Success()) {
6366 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6367 for (
const auto &core_range_info : core_ranges) {
6369 const auto &core_range = core_range_info.data;
6370 uint32_t cmd_type = LC_SEGMENT_64;
6371 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6372 if (addr_byte_size == 4) {
6373 cmd_type = LC_SEGMENT;
6374 segment_size =
sizeof(llvm::MachO::segment_command);
6378 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6380 uint32_t vm_prot = 0;
6381 if (core_range.lldb_permissions & ePermissionsReadable)
6382 vm_prot |= VM_PROT_READ;
6383 if (core_range.lldb_permissions & ePermissionsWritable)
6384 vm_prot |= VM_PROT_WRITE;
6385 if (core_range.lldb_permissions & ePermissionsExecutable)
6386 vm_prot |= VM_PROT_EXECUTE;
6387 const addr_t vm_addr = core_range.range.start();
6388 const addr_t vm_size = core_range.range.size();
6389 llvm::MachO::segment_command_64
segment = {
6401 segment_load_commands.push_back(
segment);
6406 llvm::MachO::mach_header_64 mach_header;
6407 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6410 mach_header.filetype = MH_CORE;
6411 mach_header.ncmds = segment_load_commands.size();
6412 mach_header.flags = 0;
6413 mach_header.reserved = 0;
6414 ThreadList &thread_list = process_sp->GetThreadList();
6415 const uint32_t num_threads = thread_list.
GetSize();
6421 std::vector<StreamString> LC_THREAD_datas(num_threads);
6422 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6424 LC_THREAD_data.SetByteOrder(byte_order);
6426 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6429 switch (mach_header.cputype) {
6430 case llvm::MachO::CPU_TYPE_ARM64:
6431 case llvm::MachO::CPU_TYPE_ARM64_32:
6433 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6436 case llvm::MachO::CPU_TYPE_ARM:
6438 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6441 case llvm::MachO::CPU_TYPE_X86_64:
6443 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6446 case llvm::MachO::CPU_TYPE_RISCV:
6448 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6455 if (addr_byte_size == 8) {
6456 mach_header.sizeofcmds = segment_load_commands.size() *
6457 sizeof(llvm::MachO::segment_command_64);
6459 mach_header.sizeofcmds = segment_load_commands.size() *
6460 sizeof(llvm::MachO::segment_command);
6464 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6465 ++mach_header.ncmds;
6466 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6471 uint64_t address_mask = process_sp->GetCodeAddressMask();
6474 mach_header.ncmds++;
6475 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6479 mach_header.ncmds++;
6480 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6483 mach_header.ncmds++;
6484 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6487 buffer.
PutHex32(mach_header.magic);
6488 buffer.
PutHex32(mach_header.cputype);
6489 buffer.
PutHex32(mach_header.cpusubtype);
6490 buffer.
PutHex32(mach_header.filetype);
6491 buffer.
PutHex32(mach_header.ncmds);
6492 buffer.
PutHex32(mach_header.sizeofcmds);
6493 buffer.
PutHex32(mach_header.flags);
6494 if (addr_byte_size == 8) {
6495 buffer.
PutHex32(mach_header.reserved);
6500 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6502 file_offset = llvm::alignTo(file_offset, 16);
6503 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6507 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6509 addrable_bits_lcnote_up->name =
"addrable bits";
6510 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6511 int bits = std::bitset<64>(~address_mask).count();
6512 addrable_bits_lcnote_up->payload.PutHex32(4);
6513 addrable_bits_lcnote_up->payload.PutHex32(
6515 addrable_bits_lcnote_up->payload.PutHex32(
6517 addrable_bits_lcnote_up->payload.PutHex32(0);
6519 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6521 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6525 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6527 thread_extrainfo_lcnote_up->name =
"process metadata";
6528 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6531 std::make_shared<StructuredData::Dictionary>());
6533 std::make_shared<StructuredData::Array>());
6535 process_sp->CalculateCoreFileThreadList(options)) {
6537 std::make_shared<StructuredData::Dictionary>());
6538 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6539 threads->AddItem(thread);
6541 dict->AddItem(
"threads", threads);
6543 dict->Dump(strm,
false);
6544 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.
GetData(),
6547 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6548 file_offset = llvm::alignTo(file_offset, 16);
6549 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6552 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6554 all_image_infos_lcnote_up->name =
"all image infos";
6555 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6557 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6559 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6562 for (
auto &lcnote : lc_notes) {
6565 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6567 memset(namebuf, 0,
sizeof(namebuf));
6573 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6575 buffer.
PutHex64(lcnote->payload_file_offset);
6576 buffer.
PutHex64(lcnote->payload.GetSize());
6580 file_offset = llvm::alignTo(file_offset, 4096);
6582 for (
auto &
segment : segment_load_commands) {
6583 segment.fileoff = file_offset;
6584 file_offset +=
segment.filesize;
6588 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6589 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6591 buffer.
PutHex32(8 + LC_THREAD_data_size);
6592 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6596 for (
const auto &
segment : segment_load_commands) {
6600 if (addr_byte_size == 8) {
6617 std::string core_file_path(outfile.
GetPath());
6625 uint8_t bytes[0x1000];
6627 size_t bytes_written = buffer.
GetString().size();
6629 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6630 if (
error.Success()) {
6632 for (
auto &lcnote : lc_notes) {
6633 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6636 "Unable to seek to corefile pos "
6637 "to write '%s' LC_NOTE payload",
6638 lcnote->name.c_str());
6641 bytes_written = lcnote->payload.GetSize();
6642 error = core_file.get()->Write(lcnote->payload.GetData(),
6644 if (!
error.Success())
6649 for (
const auto &
segment : segment_load_commands) {
6650 if (core_file.get()->SeekFromStart(
segment.fileoff) == -1) {
6652 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6653 segment.fileoff, core_file_path.c_str());
6659 " bytes of data for memory region at 0x%" PRIx64
"\n",
6664 while (bytes_left > 0 &&
error.Success()) {
6665 const size_t bytes_to_read =
6666 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6671 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6674 if (bytes_read == bytes_to_read) {
6675 size_t bytes_written = bytes_read;
6676 error = core_file.get()->Write(bytes, bytes_written);
6677 bytes_left -= bytes_read;
6682 memset(bytes, 0, bytes_to_read);
6683 size_t bytes_written = bytes_to_read;
6684 error = core_file.get()->Write(bytes, bytes_written);
6685 bytes_left -= bytes_to_read;
6686 addr += bytes_to_read;