2156 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2157 Progress progress(
"Parsing symbol table", file_name);
2172 llvm::DenseSet<addr_t> symbols_added;
2176 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2180 symbols_added.insert(file_addr);
2182 FunctionStarts function_starts;
2186 llvm::StringRef g_objc_v2_prefix_class(
"_OBJC_CLASS_$_");
2187 llvm::StringRef g_objc_v2_prefix_metaclass(
"_OBJC_METACLASS_$_");
2188 llvm::StringRef g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
2191 for (i = 0; i <
m_header.ncmds; ++i) {
2194 llvm::MachO::load_command lc;
2195 if (
m_data.GetU32(&offset, &lc, 2) ==
nullptr)
2200 llvm::MachO::symtab_command lc_obj;
2201 if (
m_data.GetU32(&offset, &lc_obj.symoff, 4)) {
2202 lc_obj.cmd = lc.cmd;
2203 lc_obj.cmdsize = lc.cmdsize;
2204 symtab_load_command = lc_obj;
2209 case LC_DYLD_INFO_ONLY: {
2210 llvm::MachO::dyld_info_command lc_obj;
2211 if (
m_data.GetU32(&offset, &lc_obj.rebase_off, 10)) {
2212 lc_obj.cmd = lc.cmd;
2213 lc_obj.cmdsize = lc.cmdsize;
2219 case LC_LOAD_WEAK_DYLIB:
2220 case LC_REEXPORT_DYLIB:
2222 case LC_LOAD_UPWARD_DYLIB: {
2223 uint32_t name_offset = cmd_offset +
m_data.GetU32(&offset);
2224 const char *path =
m_data.PeekCStr(name_offset);
2232 if (lc.cmd == LC_REEXPORT_DYLIB) {
2236 dylib_files.
Append(file_spec);
2240 case LC_DYLD_EXPORTS_TRIE: {
2241 llvm::MachO::linkedit_data_command lc_obj;
2242 lc_obj.cmd = lc.cmd;
2243 lc_obj.cmdsize = lc.cmdsize;
2244 if (
m_data.GetU32(&offset, &lc_obj.dataoff, 2))
2245 exports_trie_load_command = lc_obj;
2247 case LC_FUNCTION_STARTS: {
2248 llvm::MachO::linkedit_data_command lc_obj;
2249 lc_obj.cmd = lc.cmd;
2250 lc_obj.cmdsize = lc.cmdsize;
2251 if (
m_data.GetU32(&offset, &lc_obj.dataoff, 2))
2252 function_starts_load_command = lc_obj;
2256 const uint8_t *uuid_bytes =
m_data.PeekData(offset, 16);
2259 image_uuid =
UUID(uuid_bytes, 16);
2266 offset = cmd_offset + lc.cmdsize;
2269 if (!symtab_load_command.
cmd)
2273 if (section_list ==
nullptr)
2276 const uint32_t addr_byte_size =
m_data.GetAddressByteSize();
2278 bool bit_width_32 = addr_byte_size == 4;
2279 const size_t nlist_byte_size =
2280 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2282 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2283 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2284 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2285 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2287 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2289 const
addr_t nlist_data_byte_size =
2290 symtab_load_command.nsyms * nlist_byte_size;
2291 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2294 ProcessSP process_sp(m_process_wp.lock());
2295 Process *process = process_sp.get();
2299 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2309 section_list->FindSectionByName(g_segment_name_TEXT));
2311 section_list->FindSectionByName(g_segment_name_DATA));
2313 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2315 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2317 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2319 section_list->FindSectionByName(g_segment_name_OBJC));
2322 if (text_section_sp.get()) {
2323 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2324 g_section_name_eh_frame);
2325 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2326 g_section_name_lldb_no_nlist);
2328 eh_frame_section_sp =
2330 lldb_no_nlist_section_sp =
2334 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2335 !is_local_shared_cache_image) {
2336 Target &target = process->GetTarget();
2345 if (lldb_no_nlist_section_sp)
2350 if (linkedit_section_sp) {
2351 addr_t linkedit_load_addr =
2352 linkedit_section_sp->GetLoadBaseAddress(&target);
2362 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2363 const addr_t symoff_addr = linkedit_load_addr +
2364 symtab_load_command.
symoff -
2365 linkedit_file_offset;
2366 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2367 linkedit_file_offset;
2375 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2377 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2379 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2381 const addr_t indirect_syms_addr = linkedit_load_addr +
2383 linkedit_file_offset;
2385 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2386 if (indirect_syms_data_sp)
2387 indirect_symbol_index_data.SetData(
2388 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2398 if (!is_shared_cache_image) {
2400 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2401 if (strtab_data_sp) {
2402 strtab_data.SetData(strtab_data_sp, 0,
2403 strtab_data_sp->GetByteSize());
2408 if (function_starts_load_command.
cmd) {
2409 const addr_t func_start_addr =
2410 linkedit_load_addr + function_starts_load_command.
dataoff -
2411 linkedit_file_offset;
2414 function_starts_load_command.
datasize));
2415 if (func_start_data_sp)
2416 function_starts_data.SetData(func_start_data_sp, 0,
2417 func_start_data_sp->GetByteSize());
2423 if (is_local_shared_cache_image) {
2431 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2434 symtab_load_command.
symoff += linkedit_slide;
2435 symtab_load_command.
stroff += linkedit_slide;
2438 function_starts_load_command.
dataoff += linkedit_slide;
2439 exports_trie_load_command.
dataoff += linkedit_slide;
2443 nlist_data_byte_size);
2444 strtab_data.SetData(
m_data, symtab_load_command.
stroff,
2445 strtab_data_byte_size);
2450 && (exports_trie_load_command.
datasize > 0)));
2454 }
else if (exports_trie_load_command.
datasize > 0) {
2455 dyld_trie_data.SetData(
m_data, exports_trie_load_command.
dataoff,
2456 exports_trie_load_command.
datasize);
2463 if (function_starts_load_command.
cmd) {
2464 function_starts_data.SetData(
m_data, function_starts_load_command.
dataoff,
2465 function_starts_load_command.
datasize);
2469 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2471 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2488 if (text_section_sp && function_starts_data.GetByteSize()) {
2489 FunctionStarts::Entry function_start_entry;
2490 function_start_entry.data =
false;
2492 function_start_entry.addr = text_section_sp->GetFileAddress();
2494 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2497 function_start_entry.addr += delta;
2499 if (function_start_entry.addr & 1) {
2501 function_start_entry.data =
true;
2502 }
else if (always_thumb) {
2503 function_start_entry.data =
true;
2506 function_starts.Append(function_start_entry);
2514 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2520 addr_t text_base_addr = text_section_sp->GetFileAddress();
2521 size_t count = functions.
GetSize();
2522 for (
size_t i = 0; i < count; ++i) {
2526 FunctionStarts::Entry function_start_entry;
2527 function_start_entry.addr = func->
base - text_base_addr;
2529 if (function_start_entry.addr & 1) {
2531 function_start_entry.data =
true;
2532 }
else if (always_thumb) {
2533 function_start_entry.data =
true;
2536 function_starts.Append(function_start_entry);
2542 const size_t function_starts_count = function_starts.GetSize();
2557 if (unwind_or_symbol_log)
2558 module_sp->LogMessage(
2559 unwind_or_symbol_log,
2560 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2563 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2564 ? eh_frame_section_sp->GetID()
2570 std::vector<uint32_t> N_FUN_indexes;
2571 std::vector<uint32_t> N_NSYM_indexes;
2572 std::vector<uint32_t> N_INCL_indexes;
2573 std::vector<uint32_t> N_BRAC_indexes;
2574 std::vector<uint32_t> N_COMM_indexes;
2575 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2576 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2577 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2578 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2579 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2580 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2583 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2584 uint32_t nlist_idx = 0;
2585 Symbol *symbol_ptr =
nullptr;
2587 uint32_t sym_idx = 0;
2589 size_t num_syms = 0;
2590 std::string memory_symbol_name;
2591 uint32_t unmapped_local_symbols_found = 0;
2593 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2594 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2595 std::set<lldb::addr_t> resolver_addresses;
2597 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2598 if (dyld_trie_data_size > 0) {
2599 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2603 if (text_segment_sp)
2604 text_segment_file_addr = text_segment_sp->GetFileAddress();
2605 std::vector<llvm::StringRef> nameSlices;
2607 nameSlices, resolver_addresses, reexport_trie_entries,
2608 external_sym_trie_entries);
2611 typedef std::set<ConstString> IndirectSymbols;
2612 IndirectSymbols indirect_symbol_names;
2635 UUID process_shared_cache_uuid;
2636 addr_t process_shared_cache_base_addr;
2640 process_shared_cache_uuid);
2643 __block
bool found_image =
false;
2644 __block
void *nlist_buffer =
nullptr;
2645 __block
unsigned nlist_count = 0;
2646 __block
char *string_table =
nullptr;
2647 __block vm_offset_t vm_nlist_memory = 0;
2648 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2649 __block vm_offset_t vm_string_memory = 0;
2650 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2652 auto _ = llvm::make_scope_exit(^{
2653 if (vm_nlist_memory)
2654 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2655 if (vm_string_memory)
2656 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2659 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2660 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2661 UndefinedNameToDescMap undefined_name_to_desc;
2662 SymbolIndexToName reexport_shlib_needs_fixup;
2664 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2666 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2670 if (process_shared_cache_uuid.
IsValid() &&
2671 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2674 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2679 dyld_image_copy_uuid(image, &dsc_image_uuid);
2680 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2687 dyld_image_local_nlist_content_4Symbolication(
2688 image, ^(
const void *nlistStart, uint64_t nlistCount,
2689 const char *stringTable) {
2690 if (!nlistStart || !nlistCount)
2698 nlist_byte_size * nlistCount, &vm_nlist_memory,
2699 &vm_nlist_bytes_read);
2702 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2707 vm_address_t string_address = (vm_address_t)stringTable;
2708 vm_size_t region_size;
2709 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2710 vm_region_basic_info_data_t info;
2711 memory_object_name_t object;
2713 ®ion_size, VM_REGION_BASIC_INFO_64,
2714 (vm_region_info_t)&info, &info_count, &
object);
2720 ((vm_address_t)stringTable - string_address),
2721 &vm_string_memory, &vm_string_bytes_read);
2725 nlist_buffer = (
void *)vm_nlist_memory;
2726 string_table = (
char *)vm_string_memory;
2727 nlist_count = nlistCount;
2733 nlist_count * nlist_byte_size,
2734 byte_order, addr_byte_size);
2735 unmapped_local_symbols_found = nlist_count;
2741 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2746 for (uint32_t nlist_index = 0;
2747 nlist_index < nlist_count;
2751 std::optional<struct nlist_64> nlist_maybe =
2752 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2756 struct nlist_64 nlist = *nlist_maybe;
2759 const char *symbol_name = string_table + nlist.n_strx;
2761 if (symbol_name == NULL) {
2766 "DSC unmapped local symbol[{0}] has invalid "
2767 "string table offset {1:x} in {2}, ignoring symbol",
2768 nlist_index, nlist.n_strx,
2769 module_sp->GetFileSpec().GetPath()));
2772 if (symbol_name[0] ==
'\0')
2775 const char *symbol_name_non_abi_mangled = NULL;
2778 bool add_nlist =
true;
2779 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2780 bool demangled_is_synthesized =
false;
2781 bool is_gsym =
false;
2782 bool set_value =
true;
2784 assert(sym_idx < num_syms);
2789 switch (nlist.n_type) {
2808 if (symbol_name && symbol_name[0] ==
'_' &&
2809 symbol_name[1] ==
'O') {
2810 llvm::StringRef symbol_name_ref(symbol_name);
2811 if (symbol_name_ref.starts_with(
2812 g_objc_v2_prefix_class)) {
2813 symbol_name_non_abi_mangled = symbol_name + 1;
2815 symbol_name + g_objc_v2_prefix_class.size();
2817 demangled_is_synthesized =
true;
2819 }
else if (symbol_name_ref.starts_with(
2820 g_objc_v2_prefix_metaclass)) {
2821 symbol_name_non_abi_mangled = symbol_name + 1;
2823 symbol_name + g_objc_v2_prefix_metaclass.size();
2825 demangled_is_synthesized =
true;
2826 }
else if (symbol_name_ref.starts_with(
2827 g_objc_v2_prefix_ivar)) {
2828 symbol_name_non_abi_mangled = symbol_name + 1;
2830 symbol_name + g_objc_v2_prefix_ivar.size();
2832 demangled_is_synthesized =
true;
2835 if (nlist.n_value != 0)
2837 nlist.n_sect, nlist.n_value);
2852 nlist.n_sect, nlist.n_value);
2854 N_FUN_addr_to_sym_idx.insert(
2855 std::make_pair(nlist.n_value, sym_idx));
2859 N_FUN_indexes.push_back(sym_idx);
2863 if (!N_FUN_indexes.empty()) {
2870 N_FUN_indexes.pop_back();
2882 N_STSYM_addr_to_sym_idx.insert(
2883 std::make_pair(nlist.n_value, sym_idx));
2884 symbol_section = section_info.
GetSection(nlist.n_sect,
2886 if (symbol_name && symbol_name[0]) {
2894 symbol_section = section_info.
GetSection(nlist.n_sect,
2928 symbol_section = section_info.
GetSection(nlist.n_sect,
2941 if (symbol_name == NULL) {
2952 N_NSYM_indexes.clear();
2953 N_INCL_indexes.clear();
2954 N_BRAC_indexes.clear();
2955 N_COMM_indexes.clear();
2956 N_FUN_indexes.clear();
2962 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2963 if (N_SO_has_full_path) {
2964 if ((N_SO_index == sym_idx - 1) &&
2965 ((sym_idx - 1) < num_syms)) {
2971 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2977 N_SO_index = sym_idx;
2979 }
else if ((N_SO_index == sym_idx - 1) &&
2980 ((sym_idx - 1) < num_syms)) {
2985 const char *so_path = sym[sym_idx - 1]
2989 if (so_path && so_path[0]) {
2990 std::string full_so_path(so_path);
2991 const size_t double_slash_pos =
2992 full_so_path.find(
"//");
2993 if (double_slash_pos != std::string::npos) {
3004 &full_so_path[double_slash_pos + 1],
3005 FileSpec::Style::native);
3008 full_so_path.erase(0, double_slash_pos + 1);
3012 if (*full_so_path.rbegin() !=
'/')
3013 full_so_path +=
'/';
3014 full_so_path += symbol_name;
3018 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3022 N_SO_index = sym_idx;
3043 N_INCL_indexes.push_back(sym_idx);
3053 if (!N_INCL_indexes.empty()) {
3058 N_INCL_indexes.pop_back();
3093 symbol_section = section_info.
GetSection(nlist.n_sect,
3104 symbol_section = section_info.
GetSection(nlist.n_sect,
3106 N_BRAC_indexes.push_back(sym_idx);
3116 symbol_section = section_info.
GetSection(nlist.n_sect,
3118 if (!N_BRAC_indexes.empty()) {
3123 N_BRAC_indexes.pop_back();
3140 N_COMM_indexes.push_back(sym_idx);
3145 symbol_section = section_info.
GetSection(nlist.n_sect,
3156 if (!N_COMM_indexes.empty()) {
3161 N_COMM_indexes.pop_back();
3176 uint8_t n_type = N_TYPE & nlist.n_type;
3177 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3181 const char *reexport_name_cstr =
3182 strtab_data.PeekCStr(nlist.n_value);
3183 if (reexport_name_cstr && reexport_name_cstr[0]) {
3186 reexport_name_cstr +
3187 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3190 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3192 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3198 if (symbol_name && symbol_name[0]) {
3200 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3201 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3213 symbol_section = section_info.
GetSection(nlist.n_sect,
3216 if (symbol_section == NULL) {
3222 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3225 uint32_t section_type =
3226 symbol_section->Get() & SECTION_TYPE;
3228 switch (section_type) {
3229 case S_CSTRING_LITERALS:
3232 case S_4BYTE_LITERALS:
3235 case S_8BYTE_LITERALS:
3238 case S_LITERAL_POINTERS:
3241 case S_NON_LAZY_SYMBOL_POINTERS:
3245 case S_LAZY_SYMBOL_POINTERS:
3248 case S_SYMBOL_STUBS:
3252 case S_MOD_INIT_FUNC_POINTERS:
3256 case S_MOD_TERM_FUNC_POINTERS:
3264 case S_16BYTE_LITERALS:
3270 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3274 switch (symbol_section->GetType()) {
3301 const char *symbol_sect_name =
3302 symbol_section->GetName().AsCString();
3303 if (symbol_section->IsDescendant(
3304 text_section_sp.get())) {
3305 if (symbol_section->IsClear(
3306 S_ATTR_PURE_INSTRUCTIONS |
3307 S_ATTR_SELF_MODIFYING_CODE |
3308 S_ATTR_SOME_INSTRUCTIONS))
3312 }
else if (symbol_section->IsDescendant(
3313 data_section_sp.get()) ||
3314 symbol_section->IsDescendant(
3315 data_dirty_section_sp.get()) ||
3316 symbol_section->IsDescendant(
3317 data_const_section_sp.get())) {
3318 if (symbol_sect_name &&
3319 ::strstr(symbol_sect_name,
"__objc") ==
3324 llvm::StringRef symbol_name_ref(symbol_name);
3325 if (symbol_name_ref.starts_with(
"_OBJC_")) {
3327 g_objc_v2_prefix_class(
3330 g_objc_v2_prefix_metaclass(
3331 "_OBJC_METACLASS_$_");
3333 g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
3334 if (symbol_name_ref.starts_with(
3335 g_objc_v2_prefix_class)) {
3336 symbol_name_non_abi_mangled =
3340 g_objc_v2_prefix_class.size();
3342 demangled_is_synthesized =
true;
3344 symbol_name_ref.starts_with(
3345 g_objc_v2_prefix_metaclass)) {
3346 symbol_name_non_abi_mangled =
3350 g_objc_v2_prefix_metaclass.size();
3352 demangled_is_synthesized =
true;
3353 }
else if (symbol_name_ref.starts_with(
3354 g_objc_v2_prefix_ivar)) {
3355 symbol_name_non_abi_mangled =
3359 g_objc_v2_prefix_ivar.size();
3361 demangled_is_synthesized =
true;
3365 }
else if (symbol_sect_name &&
3366 ::strstr(symbol_sect_name,
3367 "__gcc_except_tab") ==
3373 }
else if (symbol_sect_name &&
3374 ::strstr(symbol_sect_name,
"__IMPORT") ==
3377 }
else if (symbol_section->IsDescendant(
3378 objc_section_sp.get())) {
3380 if (symbol_name && symbol_name[0] ==
'.') {
3381 llvm::StringRef symbol_name_ref(symbol_name);
3383 g_objc_v1_prefix_class(
".objc_class_name_");
3384 if (symbol_name_ref.starts_with(
3385 g_objc_v1_prefix_class)) {
3386 symbol_name_non_abi_mangled = symbol_name;
3387 symbol_name = symbol_name +
3388 g_objc_v1_prefix_class.size();
3390 demangled_is_synthesized =
true;
3401 uint64_t symbol_value = nlist.n_value;
3402 if (symbol_name_non_abi_mangled) {
3408 if (symbol_name && symbol_name[0] ==
'_') {
3415 if (is_gsym && is_debug) {
3416 const char *gsym_name =
3422 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3426 if (symbol_section) {
3427 const addr_t section_file_addr =
3428 symbol_section->GetFileAddress();
3429 symbol_value -= section_file_addr;
3432 if (is_debug ==
false) {
3440 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3441 if (range.first != range.second) {
3442 bool found_it =
false;
3443 for (
auto pos = range.first; pos != range.second;
3445 if (sym[sym_idx].GetMangled().
GetName(
3449 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3455 sym[sym_idx].IsExternal());
3456 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3458 if (resolver_addresses.find(nlist.n_value) !=
3459 resolver_addresses.end())
3461 sym[sym_idx].
Clear();
3469 if (resolver_addresses.find(nlist.n_value) !=
3470 resolver_addresses.end())
3482 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3484 if (range.first != range.second) {
3485 bool found_it =
false;
3486 for (
auto pos = range.first; pos != range.second;
3488 if (sym[sym_idx].GetMangled().
GetName(
3492 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3498 sym[sym_idx].IsExternal());
3499 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3501 sym[sym_idx].
Clear();
3509 const char *gsym_name =
3517 ConstNameToSymbolIndexMap::const_iterator pos =
3518 N_GSYM_name_to_sym_idx.find(gsym_name);
3519 if (pos != N_GSYM_name_to_sym_idx.end()) {
3520 const uint32_t GSYM_sym_idx = pos->second;
3521 m_nlist_idx_to_sym_idx[nlist_idx] =
3530 add_symbol_addr(sym[GSYM_sym_idx]
3537 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3539 sym[sym_idx].
Clear();
3547 sym[sym_idx].
SetID(nlist_idx);
3553 sym[sym_idx].GetAddress().GetFileAddress());
3555 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3557 if (demangled_is_synthesized)
3561 sym[sym_idx].
Clear();
3568 for (
const auto &pos : reexport_shlib_needs_fixup) {
3569 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3570 if (undef_pos != undefined_name_to_desc.end()) {
3571 const uint8_t dylib_ordinal =
3572 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3573 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3583 if (nlist_data.GetByteSize() > 0) {
3587 if (sym ==
nullptr) {
3593 if (unmapped_local_symbols_found) {
3595 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3601 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3602 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3603 UndefinedNameToDescMap undefined_name_to_desc;
3604 SymbolIndexToName reexport_shlib_needs_fixup;
3612 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3614 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3615 if (is_debug != debug_only)
3618 const char *symbol_name_non_abi_mangled =
nullptr;
3619 const char *symbol_name =
nullptr;
3621 if (have_strtab_data) {
3622 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3624 if (symbol_name ==
nullptr) {
3628 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3630 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3633 if (symbol_name[0] ==
'\0')
3634 symbol_name =
nullptr;
3636 const addr_t str_addr = strtab_addr + nlist.n_strx;
3638 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3640 symbol_name = memory_symbol_name.c_str();
3645 bool add_nlist =
true;
3646 bool is_gsym =
false;
3647 bool demangled_is_synthesized =
false;
3648 bool set_value =
true;
3650 assert(sym_idx < num_syms);
3654 switch (nlist.n_type) {
3671 if (symbol_name && symbol_name[0] ==
'_' && symbol_name[1] ==
'O') {
3672 llvm::StringRef symbol_name_ref(symbol_name);
3673 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
3674 symbol_name_non_abi_mangled = symbol_name + 1;
3675 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3677 demangled_is_synthesized =
true;
3679 }
else if (symbol_name_ref.starts_with(
3680 g_objc_v2_prefix_metaclass)) {
3681 symbol_name_non_abi_mangled = symbol_name + 1;
3682 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3684 demangled_is_synthesized =
true;
3685 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
3686 symbol_name_non_abi_mangled = symbol_name + 1;
3687 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3689 demangled_is_synthesized =
true;
3692 if (nlist.n_value != 0)
3694 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3709 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3711 N_FUN_addr_to_sym_idx.insert(
3712 std::make_pair(nlist.n_value, sym_idx));
3716 N_FUN_indexes.push_back(sym_idx);
3720 if (!N_FUN_indexes.empty()) {
3725 N_FUN_indexes.pop_back();
3736 N_STSYM_addr_to_sym_idx.insert(
3737 std::make_pair(nlist.n_value, sym_idx));
3738 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3739 if (symbol_name && symbol_name[0]) {
3747 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3778 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3790 if (symbol_name ==
nullptr) {
3801 N_NSYM_indexes.clear();
3802 N_INCL_indexes.clear();
3803 N_BRAC_indexes.clear();
3804 N_COMM_indexes.clear();
3805 N_FUN_indexes.clear();
3811 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3812 if (N_SO_has_full_path) {
3813 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3818 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3823 N_SO_index = sym_idx;
3825 }
else if ((N_SO_index == sym_idx - 1) &&
3826 ((sym_idx - 1) < num_syms)) {
3830 const char *so_path =
3832 if (so_path && so_path[0]) {
3833 std::string full_so_path(so_path);
3834 const size_t double_slash_pos = full_so_path.find(
"//");
3835 if (double_slash_pos != std::string::npos) {
3843 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3844 FileSpec::Style::native);
3847 full_so_path.erase(0, double_slash_pos + 1);
3851 if (*full_so_path.rbegin() !=
'/')
3852 full_so_path +=
'/';
3853 full_so_path += symbol_name;
3857 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3861 N_SO_index = sym_idx;
3881 N_INCL_indexes.push_back(sym_idx);
3890 if (!N_INCL_indexes.empty()) {
3894 N_INCL_indexes.pop_back();
3929 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3938 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3939 N_BRAC_indexes.push_back(sym_idx);
3948 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3949 if (!N_BRAC_indexes.empty()) {
3953 N_BRAC_indexes.pop_back();
3969 N_COMM_indexes.push_back(sym_idx);
3974 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3983 if (!N_COMM_indexes.empty()) {
3987 N_COMM_indexes.pop_back();
4001 uint8_t n_type = N_TYPE & nlist.n_type;
4002 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
4006 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4007 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
4010 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
4013 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4014 indirect_symbol_names.insert(
4015 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
4021 if (symbol_name && symbol_name[0]) {
4023 ((symbol_name[0] ==
'_') ? 1 : 0));
4024 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4037 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4039 if (!symbol_section) {
4045 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4048 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4050 switch (section_type) {
4051 case S_CSTRING_LITERALS:
4054 case S_4BYTE_LITERALS:
4057 case S_8BYTE_LITERALS:
4060 case S_LITERAL_POINTERS:
4063 case S_NON_LAZY_SYMBOL_POINTERS:
4066 case S_LAZY_SYMBOL_POINTERS:
4069 case S_SYMBOL_STUBS:
4073 case S_MOD_INIT_FUNC_POINTERS:
4076 case S_MOD_TERM_FUNC_POINTERS:
4083 case S_16BYTE_LITERALS:
4089 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4093 switch (symbol_section->GetType()) {
4115 const char *symbol_sect_name =
4116 symbol_section->GetName().AsCString();
4117 if (symbol_section->IsDescendant(text_section_sp.get())) {
4118 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4119 S_ATTR_SELF_MODIFYING_CODE |
4120 S_ATTR_SOME_INSTRUCTIONS))
4124 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4125 symbol_section->IsDescendant(
4126 data_dirty_section_sp.get()) ||
4127 symbol_section->IsDescendant(
4128 data_const_section_sp.get())) {
4129 if (symbol_sect_name &&
4130 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4134 llvm::StringRef symbol_name_ref(symbol_name);
4135 if (symbol_name_ref.starts_with(
"_OBJC_")) {
4136 llvm::StringRef g_objc_v2_prefix_class(
4138 llvm::StringRef g_objc_v2_prefix_metaclass(
4139 "_OBJC_METACLASS_$_");
4140 llvm::StringRef g_objc_v2_prefix_ivar(
4142 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
4143 symbol_name_non_abi_mangled = symbol_name + 1;
4145 symbol_name + g_objc_v2_prefix_class.size();
4147 demangled_is_synthesized =
true;
4148 }
else if (symbol_name_ref.starts_with(
4149 g_objc_v2_prefix_metaclass)) {
4150 symbol_name_non_abi_mangled = symbol_name + 1;
4152 symbol_name + g_objc_v2_prefix_metaclass.size();
4154 demangled_is_synthesized =
true;
4155 }
else if (symbol_name_ref.starts_with(
4156 g_objc_v2_prefix_ivar)) {
4157 symbol_name_non_abi_mangled = symbol_name + 1;
4159 symbol_name + g_objc_v2_prefix_ivar.size();
4161 demangled_is_synthesized =
true;
4165 }
else if (symbol_sect_name &&
4166 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4172 }
else if (symbol_sect_name &&
4173 ::strstr(symbol_sect_name,
"__IMPORT") ==
4176 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4178 if (symbol_name && symbol_name[0] ==
'.') {
4179 llvm::StringRef symbol_name_ref(symbol_name);
4180 llvm::StringRef g_objc_v1_prefix_class(
4181 ".objc_class_name_");
4182 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4183 symbol_name_non_abi_mangled = symbol_name;
4184 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4186 demangled_is_synthesized =
true;
4197 sym[sym_idx].
Clear();
4201 uint64_t symbol_value = nlist.n_value;
4203 if (symbol_name_non_abi_mangled) {
4209 if (symbol_name && symbol_name[0] ==
'_') {
4220 const char *gsym_name = sym[sym_idx]
4225 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4228 if (symbol_section) {
4229 const addr_t section_file_addr = symbol_section->GetFileAddress();
4230 symbol_value -= section_file_addr;
4239 std::pair<ValueToSymbolIndexMap::const_iterator,
4240 ValueToSymbolIndexMap::const_iterator>
4242 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4243 if (range.first != range.second) {
4244 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4245 pos != range.second; ++pos) {
4249 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4253 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4254 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4255 if (resolver_addresses.find(nlist.n_value) !=
4256 resolver_addresses.end())
4258 sym[sym_idx].
Clear();
4263 if (resolver_addresses.find(nlist.n_value) !=
4264 resolver_addresses.end())
4274 std::pair<ValueToSymbolIndexMap::const_iterator,
4275 ValueToSymbolIndexMap::const_iterator>
4277 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4278 if (range.first != range.second) {
4279 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4280 pos != range.second; ++pos) {
4284 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4288 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4289 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4290 sym[sym_idx].
Clear();
4296 const char *gsym_name = sym[sym_idx]
4301 ConstNameToSymbolIndexMap::const_iterator pos =
4302 N_GSYM_name_to_sym_idx.find(gsym_name);
4303 if (pos != N_GSYM_name_to_sym_idx.end()) {
4304 const uint32_t GSYM_sym_idx = pos->second;
4305 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4311 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4315 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4316 sym[sym_idx].
Clear();
4324 sym[sym_idx].
SetID(nlist_idx);
4330 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4332 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4333 if (nlist.n_desc & N_WEAK_REF)
4336 if (demangled_is_synthesized)
4345 std::vector<struct nlist_64> nlists;
4346 nlists.reserve(symtab_load_command.
nsyms);
4347 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4349 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4350 nlists.push_back(*nlist);
4360 for (
auto &nlist : nlists) {
4361 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4367 for (
auto &nlist : nlists) {
4372 for (
const auto &pos : reexport_shlib_needs_fixup) {
4373 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4374 if (undef_pos != undefined_name_to_desc.end()) {
4375 const uint8_t dylib_ordinal =
4376 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4377 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4385 int trie_symbol_table_augment_count = 0;
4386 for (
auto &e : external_sym_trie_entries) {
4387 if (!symbols_added.contains(e.entry.address))
4388 trie_symbol_table_augment_count++;
4391 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4392 num_syms = sym_idx + trie_symbol_table_augment_count;
4393 sym = symtab.
Resize(num_syms);
4395 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4398 for (
auto &e : external_sym_trie_entries) {
4399 if (symbols_added.contains(e.entry.address))
4405 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4407 const char *symbol_name = e.entry.name.GetCString();
4408 bool demangled_is_synthesized =
false;
4410 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4411 data_section_sp, data_dirty_section_sp,
4412 data_const_section_sp, symbol_section);
4415 if (symbol_section) {
4416 sym[sym_idx].
SetID(synthetic_sym_id++);
4418 if (demangled_is_synthesized)
4431 if (function_starts_count > 0) {
4432 uint32_t num_synthetic_function_symbols = 0;
4433 for (i = 0; i < function_starts_count; ++i) {
4434 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4435 ++num_synthetic_function_symbols;
4438 if (num_synthetic_function_symbols > 0) {
4439 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4440 num_syms = sym_idx + num_synthetic_function_symbols;
4441 sym = symtab.
Resize(num_syms);
4443 for (i = 0; i < function_starts_count; ++i) {
4444 const FunctionStarts::Entry *func_start_entry =
4445 function_starts.GetEntryAtIndex(i);
4446 if (!symbols_added.contains(func_start_entry->addr)) {
4447 addr_t symbol_file_addr = func_start_entry->addr;
4448 uint32_t symbol_flags = 0;
4449 if (func_start_entry->data)
4452 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4454 if (symbol_section) {
4455 sym[sym_idx].
SetID(synthetic_sym_id++);
4465 sym[sym_idx].
SetFlags(symbol_flags);
4476 if (sym_idx < num_syms) {
4478 sym = symtab.
Resize(num_syms);
4483 if (indirect_symbol_index_data.GetByteSize()) {
4484 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4485 m_nlist_idx_to_sym_idx.end();
4492 if (symbol_stub_byte_size == 0)
4495 const uint32_t num_symbol_stubs =
4498 if (num_symbol_stubs == 0)
4501 const uint32_t symbol_stub_index_offset =
4503 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4504 const uint32_t symbol_stub_index =
4505 symbol_stub_index_offset + stub_idx;
4508 (stub_idx * symbol_stub_byte_size);
4510 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4511 symbol_stub_offset, 4)) {
4512 const uint32_t stub_sym_id =
4513 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4514 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4517 NListIndexToSymbolIndexMap::const_iterator index_pos =
4518 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4519 Symbol *stub_symbol =
nullptr;
4520 if (index_pos != end_index_pos) {
4531 Address so_addr(symbol_stub_addr, section_list);
4538 if (resolver_addresses.find(symbol_stub_addr) ==
4539 resolver_addresses.end())
4549 if (sym_idx >= num_syms) {
4550 sym = symtab.
Resize(++num_syms);
4551 stub_symbol =
nullptr;
4553 sym[sym_idx].
SetID(synthetic_sym_id++);
4554 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4555 if (resolver_addresses.find(symbol_stub_addr) ==
4556 resolver_addresses.end())
4568 log->
Warning(
"symbol stub referencing symbol table symbol "
4569 "%u that isn't in our minimal symbol table, "
4580 if (!reexport_trie_entries.empty()) {
4581 for (
const auto &e : reexport_trie_entries) {
4582 if (e.entry.import_name) {
4585 if (indirect_symbol_names.find(e.entry.name) ==
4586 indirect_symbol_names.end()) {
4588 if (sym_idx >= num_syms)
4589 sym = symtab.
Resize(++num_syms);
4590 sym[sym_idx].
SetID(synthetic_sym_id++);
4595 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
6370 Target &target = process_sp->GetTarget();
6372 const llvm::Triple &target_triple = target_arch.
GetTriple();
6373 if (target_triple.getVendor() == llvm::Triple::Apple &&
6374 (target_triple.getOS() == llvm::Triple::MacOSX ||
6375 target_triple.getOS() == llvm::Triple::IOS ||
6376 target_triple.getOS() == llvm::Triple::WatchOS ||
6377 target_triple.getOS() == llvm::Triple::TvOS ||
6378 target_triple.getOS() == llvm::Triple::BridgeOS ||
6379 target_triple.getOS() == llvm::Triple::XROS)) {
6380 bool make_core =
false;
6382 case llvm::Triple::aarch64:
6383 case llvm::Triple::aarch64_32:
6384 case llvm::Triple::arm:
6385 case llvm::Triple::thumb:
6386 case llvm::Triple::x86:
6387 case llvm::Triple::x86_64:
6392 "unsupported core architecture: %s", target_triple.str().c_str());
6398 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6399 if (
error.Success()) {
6402 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6403 for (
const auto &core_range_info : core_ranges) {
6405 const auto &core_range = core_range_info.data;
6406 uint32_t cmd_type = LC_SEGMENT_64;
6407 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6408 if (addr_byte_size == 4) {
6409 cmd_type = LC_SEGMENT;
6410 segment_size =
sizeof(llvm::MachO::segment_command);
6414 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6416 uint32_t vm_prot = 0;
6417 if (core_range.lldb_permissions & ePermissionsReadable)
6418 vm_prot |= VM_PROT_READ;
6419 if (core_range.lldb_permissions & ePermissionsWritable)
6420 vm_prot |= VM_PROT_WRITE;
6421 if (core_range.lldb_permissions & ePermissionsExecutable)
6422 vm_prot |= VM_PROT_EXECUTE;
6423 const addr_t vm_addr = core_range.range.start();
6424 const addr_t vm_size = core_range.range.size();
6425 llvm::MachO::segment_command_64 segment = {
6437 segment_load_commands.push_back(segment);
6442 llvm::MachO::mach_header_64 mach_header;
6443 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6446 mach_header.filetype = MH_CORE;
6447 mach_header.ncmds = segment_load_commands.size();
6448 mach_header.flags = 0;
6449 mach_header.reserved = 0;
6450 ThreadList &thread_list = process_sp->GetThreadList();
6451 const uint32_t num_threads = thread_list.
GetSize();
6457 std::vector<StreamString> LC_THREAD_datas(num_threads);
6458 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6460 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6461 LC_THREAD_data.SetByteOrder(byte_order);
6463 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6466 switch (mach_header.cputype) {
6467 case llvm::MachO::CPU_TYPE_ARM64:
6468 case llvm::MachO::CPU_TYPE_ARM64_32:
6470 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6473 case llvm::MachO::CPU_TYPE_ARM:
6475 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6478 case llvm::MachO::CPU_TYPE_X86_64:
6480 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6483 case llvm::MachO::CPU_TYPE_RISCV:
6485 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6492 if (addr_byte_size == 8) {
6493 mach_header.sizeofcmds = segment_load_commands.size() *
6494 sizeof(llvm::MachO::segment_command_64);
6496 mach_header.sizeofcmds = segment_load_commands.size() *
6497 sizeof(llvm::MachO::segment_command);
6501 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6502 ++mach_header.ncmds;
6503 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6508 uint64_t address_mask = process_sp->GetCodeAddressMask();
6511 mach_header.ncmds++;
6512 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6516 mach_header.ncmds++;
6517 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6520 mach_header.ncmds++;
6521 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6524 buffer.
PutHex32(mach_header.magic);
6525 buffer.
PutHex32(mach_header.cputype);
6526 buffer.
PutHex32(mach_header.cpusubtype);
6527 buffer.
PutHex32(mach_header.filetype);
6528 buffer.
PutHex32(mach_header.ncmds);
6529 buffer.
PutHex32(mach_header.sizeofcmds);
6530 buffer.
PutHex32(mach_header.flags);
6531 if (addr_byte_size == 8) {
6532 buffer.
PutHex32(mach_header.reserved);
6537 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6539 file_offset = llvm::alignTo(file_offset, 16);
6540 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6544 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6546 addrable_bits_lcnote_up->name =
"addrable bits";
6547 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6548 int bits = std::bitset<64>(~address_mask).count();
6549 addrable_bits_lcnote_up->payload.PutHex32(4);
6550 addrable_bits_lcnote_up->payload.PutHex32(
6552 addrable_bits_lcnote_up->payload.PutHex32(
6554 addrable_bits_lcnote_up->payload.PutHex32(0);
6556 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6558 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6562 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6564 thread_extrainfo_lcnote_up->name =
"process metadata";
6565 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6568 std::make_shared<StructuredData::Dictionary>());
6570 std::make_shared<StructuredData::Array>());
6572 process_sp->CalculateCoreFileThreadList(options)) {
6574 std::make_shared<StructuredData::Dictionary>());
6575 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6576 threads->AddItem(thread);
6578 dict->AddItem(
"threads", threads);
6580 dict->Dump(strm,
false);
6584 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6585 file_offset = llvm::alignTo(file_offset, 16);
6586 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6589 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6591 all_image_infos_lcnote_up->name =
"all image infos";
6592 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6594 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6596 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6599 for (
auto &lcnote : lc_notes) {
6602 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6604 memset(namebuf, 0,
sizeof(namebuf));
6610 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6612 buffer.
PutHex64(lcnote->payload_file_offset);
6613 buffer.
PutHex64(lcnote->payload.GetSize());
6617 file_offset = llvm::alignTo(file_offset, 4096);
6619 for (
auto &segment : segment_load_commands) {
6620 segment.fileoff = file_offset;
6621 file_offset += segment.filesize;
6625 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6626 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6628 buffer.
PutHex32(8 + LC_THREAD_data_size);
6629 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6633 for (
const auto &segment : segment_load_commands) {
6636 buffer.
PutRawBytes(segment.segname,
sizeof(segment.segname));
6637 if (addr_byte_size == 8) {
6643 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmaddr));
6644 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmsize));
6645 buffer.
PutHex32(
static_cast<uint32_t
>(segment.fileoff));
6646 buffer.
PutHex32(
static_cast<uint32_t
>(segment.filesize));
6654 std::string core_file_path(outfile.
GetPath());
6662 uint8_t bytes[0x1000];
6664 size_t bytes_written = buffer.
GetString().size();
6666 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6667 if (
error.Success()) {
6669 for (
auto &lcnote : lc_notes) {
6670 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6673 "Unable to seek to corefile pos "
6674 "to write '%s' LC_NOTE payload",
6675 lcnote->name.c_str());
6678 bytes_written = lcnote->payload.GetSize();
6679 error = core_file.get()->Write(lcnote->payload.GetData(),
6681 if (!
error.Success())
6686 for (
const auto &segment : segment_load_commands) {
6687 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6689 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6690 segment.fileoff, core_file_path.c_str());
6696 " bytes of data for memory region at 0x%" PRIx64
"\n",
6697 segment.vmsize, segment.vmaddr);
6698 addr_t bytes_left = segment.vmsize;
6699 addr_t addr = segment.vmaddr;
6701 while (bytes_left > 0 &&
error.Success()) {
6702 const size_t bytes_to_read =
6703 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6708 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6711 if (bytes_read == bytes_to_read) {
6712 size_t bytes_written = bytes_read;
6713 error = core_file.get()->Write(bytes, bytes_written);
6714 bytes_left -= bytes_read;
6719 memset(bytes, 0, bytes_to_read);
6720 size_t bytes_written = bytes_to_read;
6721 error = core_file.get()->Write(bytes, bytes_written);
6722 bytes_left -= bytes_to_read;
6723 addr += bytes_to_read;