2193 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2194 Progress progress(
"Parsing symbol table", file_name);
2209 llvm::DenseSet<addr_t> symbols_added;
2213 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2217 symbols_added.insert(file_addr);
2219 FunctionStarts function_starts;
2225 for (i = 0; i <
m_header.ncmds; ++i) {
2228 llvm::MachO::load_command lc;
2229 if (
m_data.GetU32(&offset, &lc, 2) ==
nullptr)
2234 llvm::MachO::symtab_command lc_obj;
2235 if (
m_data.GetU32(&offset, &lc_obj.symoff, 4)) {
2236 lc_obj.cmd = lc.cmd;
2237 lc_obj.cmdsize = lc.cmdsize;
2238 symtab_load_command = lc_obj;
2243 case LC_DYLD_INFO_ONLY: {
2244 llvm::MachO::dyld_info_command lc_obj;
2245 if (
m_data.GetU32(&offset, &lc_obj.rebase_off, 10)) {
2246 lc_obj.cmd = lc.cmd;
2247 lc_obj.cmdsize = lc.cmdsize;
2253 case LC_LOAD_WEAK_DYLIB:
2254 case LC_REEXPORT_DYLIB:
2256 case LC_LOAD_UPWARD_DYLIB: {
2257 uint32_t name_offset = cmd_offset +
m_data.GetU32(&offset);
2258 const char *path =
m_data.PeekCStr(name_offset);
2266 if (lc.cmd == LC_REEXPORT_DYLIB) {
2270 dylib_files.
Append(file_spec);
2274 case LC_DYLD_EXPORTS_TRIE: {
2275 llvm::MachO::linkedit_data_command lc_obj;
2276 lc_obj.cmd = lc.cmd;
2277 lc_obj.cmdsize = lc.cmdsize;
2278 if (
m_data.GetU32(&offset, &lc_obj.dataoff, 2))
2279 exports_trie_load_command = lc_obj;
2281 case LC_FUNCTION_STARTS: {
2282 llvm::MachO::linkedit_data_command lc_obj;
2283 lc_obj.cmd = lc.cmd;
2284 lc_obj.cmdsize = lc.cmdsize;
2285 if (
m_data.GetU32(&offset, &lc_obj.dataoff, 2))
2286 function_starts_load_command = lc_obj;
2290 const uint8_t *uuid_bytes =
m_data.PeekData(offset, 16);
2293 image_uuid =
UUID(uuid_bytes, 16);
2300 offset = cmd_offset + lc.cmdsize;
2303 if (!symtab_load_command.
cmd)
2307 if (section_list ==
nullptr)
2310 const uint32_t addr_byte_size =
m_data.GetAddressByteSize();
2312 bool bit_width_32 = addr_byte_size == 4;
2313 const size_t nlist_byte_size =
2314 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2316 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2317 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2318 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2319 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2321 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2323 const
addr_t nlist_data_byte_size =
2324 symtab_load_command.nsyms * nlist_byte_size;
2325 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2328 ProcessSP process_sp(m_process_wp.lock());
2329 Process *process = process_sp.get();
2333 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2343 section_list->FindSectionByName(g_segment_name_TEXT));
2345 section_list->FindSectionByName(g_segment_name_DATA));
2347 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2349 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2351 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2353 section_list->FindSectionByName(g_segment_name_OBJC));
2356 if (text_section_sp.get()) {
2357 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2358 g_section_name_eh_frame);
2359 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2360 g_section_name_lldb_no_nlist);
2362 eh_frame_section_sp =
2364 lldb_no_nlist_section_sp =
2368 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2369 !is_local_shared_cache_image) {
2370 Target &target = process->GetTarget();
2379 if (lldb_no_nlist_section_sp)
2384 if (linkedit_section_sp) {
2385 addr_t linkedit_load_addr =
2386 linkedit_section_sp->GetLoadBaseAddress(&target);
2396 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2397 const addr_t symoff_addr = linkedit_load_addr +
2398 symtab_load_command.
symoff -
2399 linkedit_file_offset;
2400 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2401 linkedit_file_offset;
2409 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2411 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2413 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2415 const addr_t indirect_syms_addr = linkedit_load_addr +
2417 linkedit_file_offset;
2419 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2420 if (indirect_syms_data_sp)
2421 indirect_symbol_index_data.SetData(
2422 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2432 if (!is_shared_cache_image) {
2434 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2435 if (strtab_data_sp) {
2436 strtab_data.SetData(strtab_data_sp, 0,
2437 strtab_data_sp->GetByteSize());
2442 if (function_starts_load_command.
cmd) {
2443 const addr_t func_start_addr =
2444 linkedit_load_addr + function_starts_load_command.
dataoff -
2445 linkedit_file_offset;
2448 function_starts_load_command.
datasize));
2449 if (func_start_data_sp)
2450 function_starts_data.SetData(func_start_data_sp, 0,
2451 func_start_data_sp->GetByteSize());
2457 if (is_local_shared_cache_image) {
2465 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2468 symtab_load_command.
symoff += linkedit_slide;
2469 symtab_load_command.
stroff += linkedit_slide;
2472 function_starts_load_command.
dataoff += linkedit_slide;
2473 exports_trie_load_command.
dataoff += linkedit_slide;
2477 nlist_data_byte_size);
2478 strtab_data.SetData(
m_data, symtab_load_command.
stroff,
2479 strtab_data_byte_size);
2484 && (exports_trie_load_command.
datasize > 0)));
2488 }
else if (exports_trie_load_command.
datasize > 0) {
2489 dyld_trie_data.SetData(
m_data, exports_trie_load_command.
dataoff,
2490 exports_trie_load_command.
datasize);
2497 if (function_starts_load_command.
cmd) {
2498 function_starts_data.SetData(
m_data, function_starts_load_command.
dataoff,
2499 function_starts_load_command.
datasize);
2503 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2505 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2522 if (text_section_sp && function_starts_data.GetByteSize()) {
2523 FunctionStarts::Entry function_start_entry;
2524 function_start_entry.data =
false;
2526 function_start_entry.addr = text_section_sp->GetFileAddress();
2528 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2531 function_start_entry.addr += delta;
2533 if (function_start_entry.addr & 1) {
2535 function_start_entry.data =
true;
2536 }
else if (always_thumb) {
2537 function_start_entry.data =
true;
2540 function_starts.Append(function_start_entry);
2548 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2554 addr_t text_base_addr = text_section_sp->GetFileAddress();
2555 size_t count = functions.
GetSize();
2556 for (
size_t i = 0; i < count; ++i) {
2560 FunctionStarts::Entry function_start_entry;
2561 function_start_entry.addr = func->
base - text_base_addr;
2563 if (function_start_entry.addr & 1) {
2565 function_start_entry.data =
true;
2566 }
else if (always_thumb) {
2567 function_start_entry.data =
true;
2570 function_starts.Append(function_start_entry);
2576 const size_t function_starts_count = function_starts.GetSize();
2591 if (unwind_or_symbol_log)
2592 module_sp->LogMessage(
2593 unwind_or_symbol_log,
2594 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2597 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2598 ? eh_frame_section_sp->GetID()
2604 std::vector<uint32_t> N_FUN_indexes;
2605 std::vector<uint32_t> N_NSYM_indexes;
2606 std::vector<uint32_t> N_INCL_indexes;
2607 std::vector<uint32_t> N_BRAC_indexes;
2608 std::vector<uint32_t> N_COMM_indexes;
2609 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2610 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2611 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2612 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2613 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2614 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2617 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2618 uint32_t nlist_idx = 0;
2619 Symbol *symbol_ptr =
nullptr;
2621 uint32_t sym_idx = 0;
2623 size_t num_syms = 0;
2624 std::string memory_symbol_name;
2625 uint32_t unmapped_local_symbols_found = 0;
2627 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2628 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2629 std::set<lldb::addr_t> resolver_addresses;
2631 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2632 if (dyld_trie_data_size > 0) {
2633 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2637 if (text_segment_sp)
2638 text_segment_file_addr = text_segment_sp->GetFileAddress();
2639 std::vector<llvm::StringRef> nameSlices;
2641 nameSlices, resolver_addresses, reexport_trie_entries,
2642 external_sym_trie_entries);
2645 typedef std::set<ConstString> IndirectSymbols;
2646 IndirectSymbols indirect_symbol_names;
2669 UUID process_shared_cache_uuid;
2670 addr_t process_shared_cache_base_addr;
2674 process_shared_cache_uuid);
2677 __block
bool found_image =
false;
2678 __block
void *nlist_buffer =
nullptr;
2679 __block
unsigned nlist_count = 0;
2680 __block
char *string_table =
nullptr;
2681 __block vm_offset_t vm_nlist_memory = 0;
2682 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2683 __block vm_offset_t vm_string_memory = 0;
2684 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2686 auto _ = llvm::make_scope_exit(^{
2687 if (vm_nlist_memory)
2688 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2689 if (vm_string_memory)
2690 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2693 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2694 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2695 UndefinedNameToDescMap undefined_name_to_desc;
2696 SymbolIndexToName reexport_shlib_needs_fixup;
2698 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2700 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2704 if (process_shared_cache_uuid.
IsValid() &&
2705 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2708 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2713 dyld_image_copy_uuid(image, &dsc_image_uuid);
2714 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2721 dyld_image_local_nlist_content_4Symbolication(
2722 image, ^(
const void *nlistStart, uint64_t nlistCount,
2723 const char *stringTable) {
2724 if (!nlistStart || !nlistCount)
2732 nlist_byte_size * nlistCount, &vm_nlist_memory,
2733 &vm_nlist_bytes_read);
2736 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2741 vm_address_t string_address = (vm_address_t)stringTable;
2742 vm_size_t region_size;
2743 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2744 vm_region_basic_info_data_t info;
2745 memory_object_name_t object;
2747 ®ion_size, VM_REGION_BASIC_INFO_64,
2748 (vm_region_info_t)&info, &info_count, &
object);
2754 ((vm_address_t)stringTable - string_address),
2755 &vm_string_memory, &vm_string_bytes_read);
2759 nlist_buffer = (
void *)vm_nlist_memory;
2760 string_table = (
char *)vm_string_memory;
2761 nlist_count = nlistCount;
2767 nlist_count * nlist_byte_size,
2768 byte_order, addr_byte_size);
2769 unmapped_local_symbols_found = nlist_count;
2775 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2780 for (uint32_t nlist_index = 0;
2781 nlist_index < nlist_count;
2785 std::optional<struct nlist_64> nlist_maybe =
2786 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2790 struct nlist_64 nlist = *nlist_maybe;
2793 const char *symbol_name = string_table + nlist.n_strx;
2795 if (symbol_name == NULL) {
2800 "DSC unmapped local symbol[{0}] has invalid "
2801 "string table offset {1:x} in {2}, ignoring symbol",
2802 nlist_index, nlist.n_strx,
2803 module_sp->GetFileSpec().GetPath()));
2806 if (symbol_name[0] ==
'\0')
2809 const char *symbol_name_non_abi_mangled = NULL;
2812 bool add_nlist =
true;
2813 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2814 bool demangled_is_synthesized =
false;
2815 bool is_gsym =
false;
2816 bool set_value =
true;
2818 assert(sym_idx < num_syms);
2823 switch (nlist.n_type) {
2843 symbol_name, symbol_name_non_abi_mangled,
2845 demangled_is_synthesized =
true;
2847 if (nlist.n_value != 0)
2849 nlist.n_sect, nlist.n_value);
2865 nlist.n_sect, nlist.n_value);
2867 N_FUN_addr_to_sym_idx.insert(
2868 std::make_pair(nlist.n_value, sym_idx));
2872 N_FUN_indexes.push_back(sym_idx);
2876 if (!N_FUN_indexes.empty()) {
2883 N_FUN_indexes.pop_back();
2895 N_STSYM_addr_to_sym_idx.insert(
2896 std::make_pair(nlist.n_value, sym_idx));
2897 symbol_section = section_info.
GetSection(nlist.n_sect,
2899 if (symbol_name && symbol_name[0]) {
2907 symbol_section = section_info.
GetSection(nlist.n_sect,
2941 symbol_section = section_info.
GetSection(nlist.n_sect,
2954 if (symbol_name == NULL) {
2965 N_NSYM_indexes.clear();
2966 N_INCL_indexes.clear();
2967 N_BRAC_indexes.clear();
2968 N_COMM_indexes.clear();
2969 N_FUN_indexes.clear();
2975 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2976 if (N_SO_has_full_path) {
2977 if ((N_SO_index == sym_idx - 1) &&
2978 ((sym_idx - 1) < num_syms)) {
2984 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2990 N_SO_index = sym_idx;
2992 }
else if ((N_SO_index == sym_idx - 1) &&
2993 ((sym_idx - 1) < num_syms)) {
2998 const char *so_path = sym[sym_idx - 1]
3002 if (so_path && so_path[0]) {
3003 std::string full_so_path(so_path);
3004 const size_t double_slash_pos =
3005 full_so_path.find(
"//");
3006 if (double_slash_pos != std::string::npos) {
3017 &full_so_path[double_slash_pos + 1],
3018 FileSpec::Style::native);
3021 full_so_path.erase(0, double_slash_pos + 1);
3025 if (*full_so_path.rbegin() !=
'/')
3026 full_so_path +=
'/';
3027 full_so_path += symbol_name;
3031 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3035 N_SO_index = sym_idx;
3056 N_INCL_indexes.push_back(sym_idx);
3066 if (!N_INCL_indexes.empty()) {
3071 N_INCL_indexes.pop_back();
3106 symbol_section = section_info.
GetSection(nlist.n_sect,
3117 symbol_section = section_info.
GetSection(nlist.n_sect,
3119 N_BRAC_indexes.push_back(sym_idx);
3129 symbol_section = section_info.
GetSection(nlist.n_sect,
3131 if (!N_BRAC_indexes.empty()) {
3136 N_BRAC_indexes.pop_back();
3153 N_COMM_indexes.push_back(sym_idx);
3158 symbol_section = section_info.
GetSection(nlist.n_sect,
3169 if (!N_COMM_indexes.empty()) {
3174 N_COMM_indexes.pop_back();
3189 uint8_t n_type = N_TYPE & nlist.n_type;
3190 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3194 const char *reexport_name_cstr =
3195 strtab_data.PeekCStr(nlist.n_value);
3196 if (reexport_name_cstr && reexport_name_cstr[0]) {
3199 reexport_name_cstr +
3200 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3203 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3205 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3211 if (symbol_name && symbol_name[0]) {
3213 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3214 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3226 symbol_section = section_info.
GetSection(nlist.n_sect,
3229 if (symbol_section == NULL) {
3235 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3238 uint32_t section_type =
3239 symbol_section->Get() & SECTION_TYPE;
3241 switch (section_type) {
3242 case S_CSTRING_LITERALS:
3245 case S_4BYTE_LITERALS:
3248 case S_8BYTE_LITERALS:
3251 case S_LITERAL_POINTERS:
3254 case S_NON_LAZY_SYMBOL_POINTERS:
3258 case S_LAZY_SYMBOL_POINTERS:
3261 case S_SYMBOL_STUBS:
3265 case S_MOD_INIT_FUNC_POINTERS:
3269 case S_MOD_TERM_FUNC_POINTERS:
3277 case S_16BYTE_LITERALS:
3283 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3287 switch (symbol_section->GetType()) {
3314 const char *symbol_sect_name =
3315 symbol_section->GetName().AsCString();
3316 if (symbol_section->IsDescendant(
3317 text_section_sp.get())) {
3318 if (symbol_section->IsClear(
3319 S_ATTR_PURE_INSTRUCTIONS |
3320 S_ATTR_SELF_MODIFYING_CODE |
3321 S_ATTR_SOME_INSTRUCTIONS))
3325 }
else if (symbol_section->IsDescendant(
3326 data_section_sp.get()) ||
3327 symbol_section->IsDescendant(
3328 data_dirty_section_sp.get()) ||
3329 symbol_section->IsDescendant(
3330 data_const_section_sp.get())) {
3331 if (symbol_sect_name &&
3332 ::strstr(symbol_sect_name,
"__objc") ==
3338 symbol_name_non_abi_mangled, type))
3339 demangled_is_synthesized =
true;
3340 }
else if (symbol_sect_name &&
3341 ::strstr(symbol_sect_name,
3342 "__gcc_except_tab") ==
3348 }
else if (symbol_sect_name &&
3349 ::strstr(symbol_sect_name,
"__IMPORT") ==
3352 }
else if (symbol_section->IsDescendant(
3353 objc_section_sp.get())) {
3355 if (symbol_name && symbol_name[0] ==
'.') {
3356 llvm::StringRef symbol_name_ref(symbol_name);
3358 g_objc_v1_prefix_class(
".objc_class_name_");
3359 if (symbol_name_ref.starts_with(
3360 g_objc_v1_prefix_class)) {
3361 symbol_name_non_abi_mangled = symbol_name;
3362 symbol_name = symbol_name +
3363 g_objc_v1_prefix_class.size();
3365 demangled_is_synthesized =
true;
3376 uint64_t symbol_value = nlist.n_value;
3377 if (symbol_name_non_abi_mangled) {
3383 if (symbol_name && symbol_name[0] ==
'_') {
3390 if (is_gsym && is_debug) {
3391 const char *gsym_name =
3397 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3401 if (symbol_section) {
3402 const addr_t section_file_addr =
3403 symbol_section->GetFileAddress();
3404 symbol_value -= section_file_addr;
3407 if (is_debug ==
false) {
3415 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3416 if (range.first != range.second) {
3417 bool found_it =
false;
3418 for (
auto pos = range.first; pos != range.second;
3420 if (sym[sym_idx].GetMangled().
GetName(
3424 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3430 sym[sym_idx].IsExternal());
3431 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3433 if (resolver_addresses.find(nlist.n_value) !=
3434 resolver_addresses.end())
3436 sym[sym_idx].
Clear();
3444 if (resolver_addresses.find(nlist.n_value) !=
3445 resolver_addresses.end())
3457 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3459 if (range.first != range.second) {
3460 bool found_it =
false;
3461 for (
auto pos = range.first; pos != range.second;
3463 if (sym[sym_idx].GetMangled().
GetName(
3467 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3473 sym[sym_idx].IsExternal());
3474 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3476 sym[sym_idx].
Clear();
3484 const char *gsym_name =
3492 ConstNameToSymbolIndexMap::const_iterator pos =
3493 N_GSYM_name_to_sym_idx.find(gsym_name);
3494 if (pos != N_GSYM_name_to_sym_idx.end()) {
3495 const uint32_t GSYM_sym_idx = pos->second;
3496 m_nlist_idx_to_sym_idx[nlist_idx] =
3505 add_symbol_addr(sym[GSYM_sym_idx]
3512 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3514 sym[sym_idx].
Clear();
3522 sym[sym_idx].
SetID(nlist_idx);
3528 sym[sym_idx].GetAddress().GetFileAddress());
3530 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3532 if (demangled_is_synthesized)
3536 sym[sym_idx].
Clear();
3543 for (
const auto &pos : reexport_shlib_needs_fixup) {
3544 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3545 if (undef_pos != undefined_name_to_desc.end()) {
3546 const uint8_t dylib_ordinal =
3547 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3548 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3558 if (nlist_data.GetByteSize() > 0) {
3562 if (sym ==
nullptr) {
3568 if (unmapped_local_symbols_found) {
3570 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3576 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3577 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3578 UndefinedNameToDescMap undefined_name_to_desc;
3579 SymbolIndexToName reexport_shlib_needs_fixup;
3587 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3589 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3590 if (is_debug != debug_only)
3593 const char *symbol_name_non_abi_mangled =
nullptr;
3594 const char *symbol_name =
nullptr;
3596 if (have_strtab_data) {
3597 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3599 if (symbol_name ==
nullptr) {
3603 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3605 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3608 if (symbol_name[0] ==
'\0')
3609 symbol_name =
nullptr;
3611 const addr_t str_addr = strtab_addr + nlist.n_strx;
3613 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3615 symbol_name = memory_symbol_name.c_str();
3620 bool add_nlist =
true;
3621 bool is_gsym =
false;
3622 bool demangled_is_synthesized =
false;
3623 bool set_value =
true;
3625 assert(sym_idx < num_syms);
3629 switch (nlist.n_type) {
3647 symbol_name_non_abi_mangled, type)) {
3648 demangled_is_synthesized =
true;
3650 if (nlist.n_value != 0)
3652 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3668 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3670 N_FUN_addr_to_sym_idx.insert(
3671 std::make_pair(nlist.n_value, sym_idx));
3675 N_FUN_indexes.push_back(sym_idx);
3679 if (!N_FUN_indexes.empty()) {
3684 N_FUN_indexes.pop_back();
3695 N_STSYM_addr_to_sym_idx.insert(
3696 std::make_pair(nlist.n_value, sym_idx));
3697 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3698 if (symbol_name && symbol_name[0]) {
3706 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3737 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3749 if (symbol_name ==
nullptr) {
3760 N_NSYM_indexes.clear();
3761 N_INCL_indexes.clear();
3762 N_BRAC_indexes.clear();
3763 N_COMM_indexes.clear();
3764 N_FUN_indexes.clear();
3770 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3771 if (N_SO_has_full_path) {
3772 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3777 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3782 N_SO_index = sym_idx;
3784 }
else if ((N_SO_index == sym_idx - 1) &&
3785 ((sym_idx - 1) < num_syms)) {
3789 const char *so_path =
3791 if (so_path && so_path[0]) {
3792 std::string full_so_path(so_path);
3793 const size_t double_slash_pos = full_so_path.find(
"//");
3794 if (double_slash_pos != std::string::npos) {
3802 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3803 FileSpec::Style::native);
3806 full_so_path.erase(0, double_slash_pos + 1);
3810 if (*full_so_path.rbegin() !=
'/')
3811 full_so_path +=
'/';
3812 full_so_path += symbol_name;
3816 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3820 N_SO_index = sym_idx;
3840 N_INCL_indexes.push_back(sym_idx);
3849 if (!N_INCL_indexes.empty()) {
3853 N_INCL_indexes.pop_back();
3888 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3897 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3898 N_BRAC_indexes.push_back(sym_idx);
3907 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3908 if (!N_BRAC_indexes.empty()) {
3912 N_BRAC_indexes.pop_back();
3928 N_COMM_indexes.push_back(sym_idx);
3933 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3942 if (!N_COMM_indexes.empty()) {
3946 N_COMM_indexes.pop_back();
3960 uint8_t n_type = N_TYPE & nlist.n_type;
3961 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3965 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3966 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3969 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3972 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3973 indirect_symbol_names.insert(
3974 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3980 if (symbol_name && symbol_name[0]) {
3982 ((symbol_name[0] ==
'_') ? 1 : 0));
3983 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3996 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3998 if (!symbol_section) {
4004 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4007 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4009 switch (section_type) {
4010 case S_CSTRING_LITERALS:
4013 case S_4BYTE_LITERALS:
4016 case S_8BYTE_LITERALS:
4019 case S_LITERAL_POINTERS:
4022 case S_NON_LAZY_SYMBOL_POINTERS:
4025 case S_LAZY_SYMBOL_POINTERS:
4028 case S_SYMBOL_STUBS:
4032 case S_MOD_INIT_FUNC_POINTERS:
4035 case S_MOD_TERM_FUNC_POINTERS:
4042 case S_16BYTE_LITERALS:
4048 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4052 switch (symbol_section->GetType()) {
4074 const char *symbol_sect_name =
4075 symbol_section->GetName().AsCString();
4076 if (symbol_section->IsDescendant(text_section_sp.get())) {
4077 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4078 S_ATTR_SELF_MODIFYING_CODE |
4079 S_ATTR_SOME_INSTRUCTIONS))
4083 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4084 symbol_section->IsDescendant(
4085 data_dirty_section_sp.get()) ||
4086 symbol_section->IsDescendant(
4087 data_const_section_sp.get())) {
4088 if (symbol_sect_name &&
4089 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4093 symbol_name, symbol_name_non_abi_mangled, type))
4094 demangled_is_synthesized =
true;
4095 }
else if (symbol_sect_name &&
4096 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4102 }
else if (symbol_sect_name &&
4103 ::strstr(symbol_sect_name,
"__IMPORT") ==
4106 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4108 if (symbol_name && symbol_name[0] ==
'.') {
4109 llvm::StringRef symbol_name_ref(symbol_name);
4110 llvm::StringRef g_objc_v1_prefix_class(
4111 ".objc_class_name_");
4112 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4113 symbol_name_non_abi_mangled = symbol_name;
4114 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4116 demangled_is_synthesized =
true;
4127 sym[sym_idx].
Clear();
4131 uint64_t symbol_value = nlist.n_value;
4133 if (symbol_name_non_abi_mangled) {
4139 if (symbol_name && symbol_name[0] ==
'_') {
4150 const char *gsym_name = sym[sym_idx]
4155 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4158 if (symbol_section) {
4159 const addr_t section_file_addr = symbol_section->GetFileAddress();
4160 symbol_value -= section_file_addr;
4169 std::pair<ValueToSymbolIndexMap::const_iterator,
4170 ValueToSymbolIndexMap::const_iterator>
4172 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4173 if (range.first != range.second) {
4174 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4175 pos != range.second; ++pos) {
4179 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4183 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4184 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4185 if (resolver_addresses.find(nlist.n_value) !=
4186 resolver_addresses.end())
4188 sym[sym_idx].
Clear();
4193 if (resolver_addresses.find(nlist.n_value) !=
4194 resolver_addresses.end())
4204 std::pair<ValueToSymbolIndexMap::const_iterator,
4205 ValueToSymbolIndexMap::const_iterator>
4207 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4208 if (range.first != range.second) {
4209 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4210 pos != range.second; ++pos) {
4214 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4218 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4219 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4220 sym[sym_idx].
Clear();
4226 const char *gsym_name = sym[sym_idx]
4231 ConstNameToSymbolIndexMap::const_iterator pos =
4232 N_GSYM_name_to_sym_idx.find(gsym_name);
4233 if (pos != N_GSYM_name_to_sym_idx.end()) {
4234 const uint32_t GSYM_sym_idx = pos->second;
4235 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4241 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4245 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4246 sym[sym_idx].
Clear();
4254 sym[sym_idx].
SetID(nlist_idx);
4260 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4262 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4263 if (nlist.n_desc & N_WEAK_REF)
4266 if (demangled_is_synthesized)
4275 std::vector<struct nlist_64> nlists;
4276 nlists.reserve(symtab_load_command.
nsyms);
4277 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4279 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4280 nlists.push_back(*nlist);
4290 for (
auto &nlist : nlists) {
4291 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4297 for (
auto &nlist : nlists) {
4302 for (
const auto &pos : reexport_shlib_needs_fixup) {
4303 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4304 if (undef_pos != undefined_name_to_desc.end()) {
4305 const uint8_t dylib_ordinal =
4306 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4307 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4315 int trie_symbol_table_augment_count = 0;
4316 for (
auto &e : external_sym_trie_entries) {
4317 if (!symbols_added.contains(e.entry.address))
4318 trie_symbol_table_augment_count++;
4321 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4322 num_syms = sym_idx + trie_symbol_table_augment_count;
4323 sym = symtab.
Resize(num_syms);
4325 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4328 for (
auto &e : external_sym_trie_entries) {
4329 if (symbols_added.contains(e.entry.address))
4335 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4337 const char *symbol_name = e.entry.name.GetCString();
4338 bool demangled_is_synthesized =
false;
4340 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4341 data_section_sp, data_dirty_section_sp,
4342 data_const_section_sp, symbol_section);
4345 if (symbol_section) {
4346 sym[sym_idx].
SetID(synthetic_sym_id++);
4348 if (demangled_is_synthesized)
4361 if (function_starts_count > 0) {
4362 uint32_t num_synthetic_function_symbols = 0;
4363 for (i = 0; i < function_starts_count; ++i) {
4364 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4365 ++num_synthetic_function_symbols;
4368 if (num_synthetic_function_symbols > 0) {
4369 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4370 num_syms = sym_idx + num_synthetic_function_symbols;
4371 sym = symtab.
Resize(num_syms);
4373 for (i = 0; i < function_starts_count; ++i) {
4374 const FunctionStarts::Entry *func_start_entry =
4375 function_starts.GetEntryAtIndex(i);
4376 if (!symbols_added.contains(func_start_entry->addr)) {
4377 addr_t symbol_file_addr = func_start_entry->addr;
4378 uint32_t symbol_flags = 0;
4379 if (func_start_entry->data)
4382 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4384 if (symbol_section) {
4385 sym[sym_idx].
SetID(synthetic_sym_id++);
4395 sym[sym_idx].
SetFlags(symbol_flags);
4406 if (sym_idx < num_syms) {
4408 sym = symtab.
Resize(num_syms);
4413 if (indirect_symbol_index_data.GetByteSize()) {
4414 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4415 m_nlist_idx_to_sym_idx.end();
4422 if (symbol_stub_byte_size == 0)
4425 const uint32_t num_symbol_stubs =
4428 if (num_symbol_stubs == 0)
4431 const uint32_t symbol_stub_index_offset =
4433 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4434 const uint32_t symbol_stub_index =
4435 symbol_stub_index_offset + stub_idx;
4438 (stub_idx * symbol_stub_byte_size);
4440 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4441 symbol_stub_offset, 4)) {
4442 const uint32_t stub_sym_id =
4443 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4444 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4447 NListIndexToSymbolIndexMap::const_iterator index_pos =
4448 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4449 Symbol *stub_symbol =
nullptr;
4450 if (index_pos != end_index_pos) {
4461 Address so_addr(symbol_stub_addr, section_list);
4468 if (resolver_addresses.find(symbol_stub_addr) ==
4469 resolver_addresses.end())
4479 if (sym_idx >= num_syms) {
4480 sym = symtab.
Resize(++num_syms);
4481 stub_symbol =
nullptr;
4483 sym[sym_idx].
SetID(synthetic_sym_id++);
4484 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4485 if (resolver_addresses.find(symbol_stub_addr) ==
4486 resolver_addresses.end())
4498 log->
Warning(
"symbol stub referencing symbol table symbol "
4499 "%u that isn't in our minimal symbol table, "
4510 if (!reexport_trie_entries.empty()) {
4511 for (
const auto &e : reexport_trie_entries) {
4512 if (e.entry.import_name) {
4515 if (indirect_symbol_names.find(e.entry.name) ==
4516 indirect_symbol_names.end()) {
4518 if (sym_idx >= num_syms)
4519 sym = symtab.
Resize(++num_syms);
4520 sym[sym_idx].
SetID(synthetic_sym_id++);
4525 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
6300 Target &target = process_sp->GetTarget();
6302 const llvm::Triple &target_triple = target_arch.
GetTriple();
6303 if (target_triple.getVendor() == llvm::Triple::Apple &&
6304 (target_triple.getOS() == llvm::Triple::MacOSX ||
6305 target_triple.getOS() == llvm::Triple::IOS ||
6306 target_triple.getOS() == llvm::Triple::WatchOS ||
6307 target_triple.getOS() == llvm::Triple::TvOS ||
6308 target_triple.getOS() == llvm::Triple::BridgeOS ||
6309 target_triple.getOS() == llvm::Triple::XROS)) {
6310 bool make_core =
false;
6312 case llvm::Triple::aarch64:
6313 case llvm::Triple::aarch64_32:
6314 case llvm::Triple::arm:
6315 case llvm::Triple::thumb:
6316 case llvm::Triple::x86:
6317 case llvm::Triple::x86_64:
6322 "unsupported core architecture: %s", target_triple.str().c_str());
6328 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6329 if (
error.Success()) {
6332 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6333 for (
const auto &core_range_info : core_ranges) {
6335 const auto &core_range = core_range_info.data;
6336 uint32_t cmd_type = LC_SEGMENT_64;
6337 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6338 if (addr_byte_size == 4) {
6339 cmd_type = LC_SEGMENT;
6340 segment_size =
sizeof(llvm::MachO::segment_command);
6344 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6346 uint32_t vm_prot = 0;
6347 if (core_range.lldb_permissions & ePermissionsReadable)
6348 vm_prot |= VM_PROT_READ;
6349 if (core_range.lldb_permissions & ePermissionsWritable)
6350 vm_prot |= VM_PROT_WRITE;
6351 if (core_range.lldb_permissions & ePermissionsExecutable)
6352 vm_prot |= VM_PROT_EXECUTE;
6353 const addr_t vm_addr = core_range.range.start();
6354 const addr_t vm_size = core_range.range.size();
6355 llvm::MachO::segment_command_64 segment = {
6367 segment_load_commands.push_back(segment);
6372 llvm::MachO::mach_header_64 mach_header;
6373 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6376 mach_header.filetype = MH_CORE;
6377 mach_header.ncmds = segment_load_commands.size();
6378 mach_header.flags = 0;
6379 mach_header.reserved = 0;
6380 ThreadList &thread_list = process_sp->GetThreadList();
6381 const uint32_t num_threads = thread_list.
GetSize();
6387 std::vector<StreamString> LC_THREAD_datas(num_threads);
6388 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6390 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6391 LC_THREAD_data.SetByteOrder(byte_order);
6393 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6396 switch (mach_header.cputype) {
6397 case llvm::MachO::CPU_TYPE_ARM64:
6398 case llvm::MachO::CPU_TYPE_ARM64_32:
6400 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6403 case llvm::MachO::CPU_TYPE_ARM:
6405 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6408 case llvm::MachO::CPU_TYPE_X86_64:
6410 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6413 case llvm::MachO::CPU_TYPE_RISCV:
6415 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6422 if (addr_byte_size == 8) {
6423 mach_header.sizeofcmds = segment_load_commands.size() *
6424 sizeof(llvm::MachO::segment_command_64);
6426 mach_header.sizeofcmds = segment_load_commands.size() *
6427 sizeof(llvm::MachO::segment_command);
6431 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6432 ++mach_header.ncmds;
6433 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6438 uint64_t address_mask = process_sp->GetCodeAddressMask();
6441 mach_header.ncmds++;
6442 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6446 mach_header.ncmds++;
6447 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6450 mach_header.ncmds++;
6451 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6454 buffer.
PutHex32(mach_header.magic);
6455 buffer.
PutHex32(mach_header.cputype);
6456 buffer.
PutHex32(mach_header.cpusubtype);
6457 buffer.
PutHex32(mach_header.filetype);
6458 buffer.
PutHex32(mach_header.ncmds);
6459 buffer.
PutHex32(mach_header.sizeofcmds);
6460 buffer.
PutHex32(mach_header.flags);
6461 if (addr_byte_size == 8) {
6462 buffer.
PutHex32(mach_header.reserved);
6467 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6469 file_offset = llvm::alignTo(file_offset, 16);
6470 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6474 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6476 addrable_bits_lcnote_up->name =
"addrable bits";
6477 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6478 int bits = std::bitset<64>(~address_mask).count();
6479 addrable_bits_lcnote_up->payload.PutHex32(4);
6480 addrable_bits_lcnote_up->payload.PutHex32(
6482 addrable_bits_lcnote_up->payload.PutHex32(
6484 addrable_bits_lcnote_up->payload.PutHex32(0);
6486 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6488 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6492 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6494 thread_extrainfo_lcnote_up->name =
"process metadata";
6495 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6498 std::make_shared<StructuredData::Dictionary>());
6500 std::make_shared<StructuredData::Array>());
6502 process_sp->CalculateCoreFileThreadList(options)) {
6504 std::make_shared<StructuredData::Dictionary>());
6505 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6506 threads->AddItem(thread);
6508 dict->AddItem(
"threads", threads);
6510 dict->Dump(strm,
false);
6514 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6515 file_offset = llvm::alignTo(file_offset, 16);
6516 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6519 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6521 all_image_infos_lcnote_up->name =
"all image infos";
6522 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6524 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6526 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6529 for (
auto &lcnote : lc_notes) {
6532 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6534 memset(namebuf, 0,
sizeof(namebuf));
6540 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6542 buffer.
PutHex64(lcnote->payload_file_offset);
6543 buffer.
PutHex64(lcnote->payload.GetSize());
6547 file_offset = llvm::alignTo(file_offset, 4096);
6549 for (
auto &segment : segment_load_commands) {
6550 segment.fileoff = file_offset;
6551 file_offset += segment.filesize;
6555 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6556 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6558 buffer.
PutHex32(8 + LC_THREAD_data_size);
6559 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6563 for (
const auto &segment : segment_load_commands) {
6566 buffer.
PutRawBytes(segment.segname,
sizeof(segment.segname));
6567 if (addr_byte_size == 8) {
6573 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmaddr));
6574 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmsize));
6575 buffer.
PutHex32(
static_cast<uint32_t
>(segment.fileoff));
6576 buffer.
PutHex32(
static_cast<uint32_t
>(segment.filesize));
6584 std::string core_file_path(outfile.
GetPath());
6592 uint8_t bytes[0x1000];
6594 size_t bytes_written = buffer.
GetString().size();
6596 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6597 if (
error.Success()) {
6599 for (
auto &lcnote : lc_notes) {
6600 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6603 "Unable to seek to corefile pos "
6604 "to write '%s' LC_NOTE payload",
6605 lcnote->name.c_str());
6608 bytes_written = lcnote->payload.GetSize();
6609 error = core_file.get()->Write(lcnote->payload.GetData(),
6611 if (!
error.Success())
6616 for (
const auto &segment : segment_load_commands) {
6617 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6619 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6620 segment.fileoff, core_file_path.c_str());
6626 " bytes of data for memory region at 0x%" PRIx64
"\n",
6627 segment.vmsize, segment.vmaddr);
6628 addr_t bytes_left = segment.vmsize;
6629 addr_t addr = segment.vmaddr;
6631 while (bytes_left > 0 &&
error.Success()) {
6632 const size_t bytes_to_read =
6633 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6638 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6641 if (bytes_read == bytes_to_read) {
6642 size_t bytes_written = bytes_read;
6643 error = core_file.get()->Write(bytes, bytes_written);
6644 bytes_left -= bytes_read;
6649 memset(bytes, 0, bytes_to_read);
6650 size_t bytes_written = bytes_to_read;
6651 error = core_file.get()->Write(bytes, bytes_written);
6652 bytes_left -= bytes_to_read;
6653 addr += bytes_to_read;