2083 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2084 Progress progress(
"Parsing symbol table", file_name);
2099 llvm::DenseSet<addr_t> symbols_added;
2103 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2107 symbols_added.insert(file_addr);
2109 FunctionStarts function_starts;
2115 for (i = 0; i <
m_header.ncmds; ++i) {
2118 llvm::MachO::load_command lc;
2119 if (
m_data_nsp->GetU32(&offset, &lc, 2) ==
nullptr)
2124 llvm::MachO::symtab_command lc_obj;
2125 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2126 lc_obj.cmd = lc.cmd;
2127 lc_obj.cmdsize = lc.cmdsize;
2128 symtab_load_command = lc_obj;
2133 case LC_DYLD_INFO_ONLY: {
2134 llvm::MachO::dyld_info_command lc_obj;
2135 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2136 lc_obj.cmd = lc.cmd;
2137 lc_obj.cmdsize = lc.cmdsize;
2143 case LC_LOAD_WEAK_DYLIB:
2144 case LC_REEXPORT_DYLIB:
2146 case LC_LOAD_UPWARD_DYLIB: {
2147 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2148 const char *path =
m_data_nsp->PeekCStr(name_offset);
2156 if (lc.cmd == LC_REEXPORT_DYLIB) {
2160 dylib_files.
Append(file_spec);
2164 case LC_DYLD_EXPORTS_TRIE: {
2165 llvm::MachO::linkedit_data_command lc_obj;
2166 lc_obj.cmd = lc.cmd;
2167 lc_obj.cmdsize = lc.cmdsize;
2168 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2169 exports_trie_load_command = lc_obj;
2171 case LC_FUNCTION_STARTS: {
2172 llvm::MachO::linkedit_data_command lc_obj;
2173 lc_obj.cmd = lc.cmd;
2174 lc_obj.cmdsize = lc.cmdsize;
2175 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2176 function_starts_load_command = lc_obj;
2180 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2183 image_uuid =
UUID(uuid_bytes, 16);
2190 offset = cmd_offset + lc.cmdsize;
2193 if (!symtab_load_command.
cmd)
2197 if (section_list ==
nullptr)
2200 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2202 bool bit_width_32 = addr_byte_size == 4;
2203 const size_t nlist_byte_size =
2204 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2206 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2207 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2208 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2209 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2211 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2213 const
addr_t nlist_data_byte_size =
2214 symtab_load_command.nsyms * nlist_byte_size;
2215 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2218 ProcessSP process_sp(m_process_wp.lock());
2219 Process *process = process_sp.get();
2223 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2233 section_list->FindSectionByName(g_segment_name_TEXT));
2235 section_list->FindSectionByName(g_segment_name_DATA));
2237 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2239 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2241 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2243 section_list->FindSectionByName(g_segment_name_OBJC));
2246 if (text_section_sp.get()) {
2247 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2248 g_section_name_eh_frame);
2249 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2250 g_section_name_lldb_no_nlist);
2252 eh_frame_section_sp =
2254 lldb_no_nlist_section_sp =
2258 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2259 !is_local_shared_cache_image) {
2260 Target &target = process->GetTarget();
2269 if (lldb_no_nlist_section_sp)
2274 if (linkedit_section_sp) {
2275 addr_t linkedit_load_addr =
2276 linkedit_section_sp->GetLoadBaseAddress(&target);
2286 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2287 const addr_t symoff_addr = linkedit_load_addr +
2288 symtab_load_command.
symoff -
2289 linkedit_file_offset;
2290 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2291 linkedit_file_offset;
2299 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2301 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2303 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2305 const addr_t indirect_syms_addr = linkedit_load_addr +
2307 linkedit_file_offset;
2309 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2310 if (indirect_syms_data_sp)
2311 indirect_symbol_index_data.SetData(
2312 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2322 if (!is_shared_cache_image) {
2324 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2325 if (strtab_data_sp) {
2326 strtab_data.SetData(strtab_data_sp, 0,
2327 strtab_data_sp->GetByteSize());
2332 if (function_starts_load_command.
cmd) {
2333 const addr_t func_start_addr =
2334 linkedit_load_addr + function_starts_load_command.
dataoff -
2335 linkedit_file_offset;
2338 function_starts_load_command.
datasize));
2339 if (func_start_data_sp)
2340 function_starts_data.SetData(func_start_data_sp, 0,
2341 func_start_data_sp->GetByteSize());
2347 if (is_local_shared_cache_image) {
2355 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2358 symtab_load_command.
symoff += linkedit_slide;
2359 symtab_load_command.
stroff += linkedit_slide;
2362 function_starts_load_command.
dataoff += linkedit_slide;
2363 exports_trie_load_command.
dataoff += linkedit_slide;
2367 nlist_data_byte_size);
2368 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2369 strtab_data_byte_size);
2374 && (exports_trie_load_command.
datasize > 0)));
2378 }
else if (exports_trie_load_command.
datasize > 0) {
2381 exports_trie_load_command.
datasize);
2385 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2388 if (function_starts_load_command.
cmd) {
2389 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2390 function_starts_load_command.
dataoff,
2391 function_starts_load_command.
datasize);
2395 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2397 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2414 if (text_section_sp && function_starts_data.GetByteSize()) {
2415 FunctionStarts::Entry function_start_entry;
2416 function_start_entry.data =
false;
2418 function_start_entry.addr = text_section_sp->GetFileAddress();
2420 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2423 function_start_entry.addr += delta;
2425 if (function_start_entry.addr & 1) {
2427 function_start_entry.data =
true;
2428 }
else if (always_thumb) {
2429 function_start_entry.data =
true;
2432 function_starts.Append(function_start_entry);
2440 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2446 addr_t text_base_addr = text_section_sp->GetFileAddress();
2447 size_t count = functions.
GetSize();
2448 for (
size_t i = 0; i < count; ++i) {
2452 FunctionStarts::Entry function_start_entry;
2453 function_start_entry.addr = func->
base - text_base_addr;
2455 if (function_start_entry.addr & 1) {
2457 function_start_entry.data =
true;
2458 }
else if (always_thumb) {
2459 function_start_entry.data =
true;
2462 function_starts.Append(function_start_entry);
2468 const size_t function_starts_count = function_starts.GetSize();
2483 if (unwind_or_symbol_log)
2484 module_sp->LogMessage(
2485 unwind_or_symbol_log,
2486 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2489 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2490 ? eh_frame_section_sp->GetID()
2496 std::vector<uint32_t> N_FUN_indexes;
2497 std::vector<uint32_t> N_NSYM_indexes;
2498 std::vector<uint32_t> N_INCL_indexes;
2499 std::vector<uint32_t> N_BRAC_indexes;
2500 std::vector<uint32_t> N_COMM_indexes;
2501 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2502 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2503 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2504 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2505 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2506 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2509 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2510 uint32_t nlist_idx = 0;
2511 Symbol *symbol_ptr =
nullptr;
2513 uint32_t sym_idx = 0;
2515 size_t num_syms = 0;
2516 std::string memory_symbol_name;
2517 uint32_t unmapped_local_symbols_found = 0;
2519 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2520 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2521 std::set<lldb::addr_t> resolver_addresses;
2523 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2524 if (dyld_trie_data_size > 0) {
2525 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2529 if (text_segment_sp)
2530 text_segment_file_addr = text_segment_sp->GetFileAddress();
2532 resolver_addresses, reexport_trie_entries,
2533 external_sym_trie_entries);
2536 typedef std::set<ConstString> IndirectSymbols;
2537 IndirectSymbols indirect_symbol_names;
2560 UUID process_shared_cache_uuid;
2561 addr_t process_shared_cache_base_addr;
2565 process_shared_cache_uuid);
2568 __block
bool found_image =
false;
2569 __block
void *nlist_buffer =
nullptr;
2570 __block
unsigned nlist_count = 0;
2571 __block
char *string_table =
nullptr;
2572 __block vm_offset_t vm_nlist_memory = 0;
2573 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2574 __block vm_offset_t vm_string_memory = 0;
2575 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2577 llvm::scope_exit _(^{
2578 if (vm_nlist_memory)
2579 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2580 if (vm_string_memory)
2581 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2584 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2585 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2586 UndefinedNameToDescMap undefined_name_to_desc;
2587 SymbolIndexToName reexport_shlib_needs_fixup;
2595 if (process_shared_cache_uuid.
IsValid() &&
2596 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2605 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2612 dyld_image_local_nlist_content_4Symbolication(
2613 image, ^(
const void *nlistStart, uint64_t nlistCount,
2614 const char *stringTable) {
2615 if (!nlistStart || !nlistCount)
2623 nlist_byte_size * nlistCount, &vm_nlist_memory,
2624 &vm_nlist_bytes_read);
2627 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2632 vm_address_t string_address = (vm_address_t)stringTable;
2633 vm_size_t region_size;
2634 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2635 vm_region_basic_info_data_t info;
2636 memory_object_name_t object;
2638 ®ion_size, VM_REGION_BASIC_INFO_64,
2639 (vm_region_info_t)&info, &info_count, &
object);
2645 ((vm_address_t)stringTable - string_address),
2646 &vm_string_memory, &vm_string_bytes_read);
2650 nlist_buffer = (
void *)vm_nlist_memory;
2651 string_table = (
char *)vm_string_memory;
2652 nlist_count = nlistCount;
2658 nlist_count * nlist_byte_size,
2659 byte_order, addr_byte_size);
2660 unmapped_local_symbols_found = nlist_count;
2666 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2671 for (uint32_t nlist_index = 0;
2672 nlist_index < nlist_count;
2676 std::optional<struct nlist_64> nlist_maybe =
2677 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2681 struct nlist_64 nlist = *nlist_maybe;
2684 const char *symbol_name = string_table + nlist.n_strx;
2686 if (symbol_name == NULL) {
2691 "DSC unmapped local symbol[{0}] has invalid "
2692 "string table offset {1:x} in {2}, ignoring symbol",
2693 nlist_index, nlist.n_strx,
2694 module_sp->GetFileSpec().GetPath()));
2697 if (symbol_name[0] ==
'\0')
2700 const char *symbol_name_non_abi_mangled = NULL;
2703 bool add_nlist =
true;
2704 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2705 bool demangled_is_synthesized =
false;
2706 bool is_gsym =
false;
2707 bool set_value =
true;
2709 assert(sym_idx < num_syms);
2714 switch (nlist.n_type) {
2734 symbol_name, symbol_name_non_abi_mangled,
2736 demangled_is_synthesized =
true;
2738 if (nlist.n_value != 0)
2740 nlist.n_sect, nlist.n_value);
2756 nlist.n_sect, nlist.n_value);
2758 N_FUN_addr_to_sym_idx.insert(
2759 std::make_pair(nlist.n_value, sym_idx));
2763 N_FUN_indexes.push_back(sym_idx);
2767 if (!N_FUN_indexes.empty()) {
2774 N_FUN_indexes.pop_back();
2786 N_STSYM_addr_to_sym_idx.insert(
2787 std::make_pair(nlist.n_value, sym_idx));
2788 symbol_section = section_info.
GetSection(nlist.n_sect,
2790 if (symbol_name && symbol_name[0]) {
2798 symbol_section = section_info.
GetSection(nlist.n_sect,
2832 symbol_section = section_info.
GetSection(nlist.n_sect,
2845 if (symbol_name == NULL) {
2856 N_NSYM_indexes.clear();
2857 N_INCL_indexes.clear();
2858 N_BRAC_indexes.clear();
2859 N_COMM_indexes.clear();
2860 N_FUN_indexes.clear();
2866 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2867 if (N_SO_has_full_path) {
2868 if ((N_SO_index == sym_idx - 1) &&
2869 ((sym_idx - 1) < num_syms)) {
2875 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2881 N_SO_index = sym_idx;
2883 }
else if ((N_SO_index == sym_idx - 1) &&
2884 ((sym_idx - 1) < num_syms)) {
2889 const char *so_path = sym[sym_idx - 1]
2893 if (so_path && so_path[0]) {
2894 std::string full_so_path(so_path);
2895 const size_t double_slash_pos =
2896 full_so_path.find(
"//");
2897 if (double_slash_pos != std::string::npos) {
2908 &full_so_path[double_slash_pos + 1],
2909 FileSpec::Style::native);
2912 full_so_path.erase(0, double_slash_pos + 1);
2916 if (*full_so_path.rbegin() !=
'/')
2917 full_so_path +=
'/';
2918 full_so_path += symbol_name;
2922 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2926 N_SO_index = sym_idx;
2947 N_INCL_indexes.push_back(sym_idx);
2957 if (!N_INCL_indexes.empty()) {
2962 N_INCL_indexes.pop_back();
2997 symbol_section = section_info.
GetSection(nlist.n_sect,
3008 symbol_section = section_info.
GetSection(nlist.n_sect,
3010 N_BRAC_indexes.push_back(sym_idx);
3020 symbol_section = section_info.
GetSection(nlist.n_sect,
3022 if (!N_BRAC_indexes.empty()) {
3027 N_BRAC_indexes.pop_back();
3044 N_COMM_indexes.push_back(sym_idx);
3049 symbol_section = section_info.
GetSection(nlist.n_sect,
3060 if (!N_COMM_indexes.empty()) {
3065 N_COMM_indexes.pop_back();
3080 uint8_t n_type = N_TYPE & nlist.n_type;
3081 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3085 const char *reexport_name_cstr =
3086 strtab_data.PeekCStr(nlist.n_value);
3087 if (reexport_name_cstr && reexport_name_cstr[0]) {
3090 reexport_name_cstr +
3091 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3094 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3096 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3102 if (symbol_name && symbol_name[0]) {
3104 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3105 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3117 symbol_section = section_info.
GetSection(nlist.n_sect,
3120 if (symbol_section == NULL) {
3126 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3129 uint32_t section_type =
3130 symbol_section->Get() & SECTION_TYPE;
3132 switch (section_type) {
3133 case S_CSTRING_LITERALS:
3136 case S_4BYTE_LITERALS:
3139 case S_8BYTE_LITERALS:
3142 case S_LITERAL_POINTERS:
3145 case S_NON_LAZY_SYMBOL_POINTERS:
3149 case S_LAZY_SYMBOL_POINTERS:
3152 case S_SYMBOL_STUBS:
3156 case S_MOD_INIT_FUNC_POINTERS:
3160 case S_MOD_TERM_FUNC_POINTERS:
3168 case S_16BYTE_LITERALS:
3174 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3178 switch (symbol_section->GetType()) {
3205 const char *symbol_sect_name =
3206 symbol_section->GetName().AsCString(
nullptr);
3207 if (symbol_section->IsDescendant(
3208 text_section_sp.get())) {
3209 if (symbol_section->IsClear(
3210 S_ATTR_PURE_INSTRUCTIONS |
3211 S_ATTR_SELF_MODIFYING_CODE |
3212 S_ATTR_SOME_INSTRUCTIONS))
3216 }
else if (symbol_section->IsDescendant(
3217 data_section_sp.get()) ||
3218 symbol_section->IsDescendant(
3219 data_dirty_section_sp.get()) ||
3220 symbol_section->IsDescendant(
3221 data_const_section_sp.get())) {
3222 if (symbol_sect_name &&
3223 ::strstr(symbol_sect_name,
"__objc") ==
3229 symbol_name_non_abi_mangled, type))
3230 demangled_is_synthesized =
true;
3231 }
else if (symbol_sect_name &&
3232 ::strstr(symbol_sect_name,
3233 "__gcc_except_tab") ==
3239 }
else if (symbol_sect_name &&
3240 ::strstr(symbol_sect_name,
"__IMPORT") ==
3243 }
else if (symbol_section->IsDescendant(
3244 objc_section_sp.get())) {
3246 if (symbol_name && symbol_name[0] ==
'.') {
3247 llvm::StringRef symbol_name_ref(symbol_name);
3249 g_objc_v1_prefix_class(
".objc_class_name_");
3250 if (symbol_name_ref.starts_with(
3251 g_objc_v1_prefix_class)) {
3252 symbol_name_non_abi_mangled = symbol_name;
3253 symbol_name = symbol_name +
3254 g_objc_v1_prefix_class.size();
3256 demangled_is_synthesized =
true;
3267 uint64_t symbol_value = nlist.n_value;
3268 if (symbol_name_non_abi_mangled) {
3274 if (symbol_name && symbol_name[0] ==
'_') {
3281 if (is_gsym && is_debug) {
3282 const char *gsym_name =
3288 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3292 if (symbol_section) {
3293 const addr_t section_file_addr =
3294 symbol_section->GetFileAddress();
3295 symbol_value -= section_file_addr;
3298 if (is_debug ==
false) {
3306 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3307 if (range.first != range.second) {
3308 bool found_it =
false;
3309 for (
auto pos = range.first; pos != range.second;
3311 if (sym[sym_idx].GetMangled().
GetName(
3315 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3321 sym[sym_idx].IsExternal());
3322 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3324 if (resolver_addresses.find(nlist.n_value) !=
3325 resolver_addresses.end())
3327 sym[sym_idx].
Clear();
3335 if (resolver_addresses.find(nlist.n_value) !=
3336 resolver_addresses.end())
3348 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3350 if (range.first != range.second) {
3351 bool found_it =
false;
3352 for (
auto pos = range.first; pos != range.second;
3354 if (sym[sym_idx].GetMangled().
GetName(
3358 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3364 sym[sym_idx].IsExternal());
3365 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3367 sym[sym_idx].
Clear();
3375 const char *gsym_name =
3383 ConstNameToSymbolIndexMap::const_iterator pos =
3384 N_GSYM_name_to_sym_idx.find(gsym_name);
3385 if (pos != N_GSYM_name_to_sym_idx.end()) {
3386 const uint32_t GSYM_sym_idx = pos->second;
3387 m_nlist_idx_to_sym_idx[nlist_idx] =
3393 Address(symbol_section, symbol_value);
3394 add_symbol_addr(sym[GSYM_sym_idx]
3401 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3403 sym[sym_idx].
Clear();
3411 sym[sym_idx].
SetID(nlist_idx);
3415 Address(symbol_section, symbol_value);
3417 sym[sym_idx].GetAddress().GetFileAddress());
3419 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3421 if (demangled_is_synthesized)
3425 sym[sym_idx].
Clear();
3432 for (
const auto &pos : reexport_shlib_needs_fixup) {
3433 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3434 if (undef_pos != undefined_name_to_desc.end()) {
3435 const uint8_t dylib_ordinal =
3436 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3437 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3447 if (nlist_data.GetByteSize() > 0) {
3451 if (sym ==
nullptr) {
3457 if (unmapped_local_symbols_found) {
3459 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3465 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3466 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3467 UndefinedNameToDescMap undefined_name_to_desc;
3468 SymbolIndexToName reexport_shlib_needs_fixup;
3476 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3478 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3479 if (is_debug != debug_only)
3482 const char *symbol_name_non_abi_mangled =
nullptr;
3483 const char *symbol_name =
nullptr;
3485 if (have_strtab_data) {
3486 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3488 if (symbol_name ==
nullptr) {
3492 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3494 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3497 if (symbol_name[0] ==
'\0')
3498 symbol_name =
nullptr;
3500 const addr_t str_addr = strtab_addr + nlist.n_strx;
3502 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3504 symbol_name = memory_symbol_name.c_str();
3509 bool add_nlist =
true;
3510 bool is_gsym =
false;
3511 bool demangled_is_synthesized =
false;
3512 bool set_value =
true;
3514 assert(sym_idx < num_syms);
3518 switch (nlist.n_type) {
3536 symbol_name_non_abi_mangled, type)) {
3537 demangled_is_synthesized =
true;
3539 if (nlist.n_value != 0)
3541 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3557 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3559 N_FUN_addr_to_sym_idx.insert(
3560 std::make_pair(nlist.n_value, sym_idx));
3564 N_FUN_indexes.push_back(sym_idx);
3568 if (!N_FUN_indexes.empty()) {
3573 N_FUN_indexes.pop_back();
3584 N_STSYM_addr_to_sym_idx.insert(
3585 std::make_pair(nlist.n_value, sym_idx));
3586 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3587 if (symbol_name && symbol_name[0]) {
3595 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3626 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3638 if (symbol_name ==
nullptr) {
3649 N_NSYM_indexes.clear();
3650 N_INCL_indexes.clear();
3651 N_BRAC_indexes.clear();
3652 N_COMM_indexes.clear();
3653 N_FUN_indexes.clear();
3659 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3660 if (N_SO_has_full_path) {
3661 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3666 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3671 N_SO_index = sym_idx;
3673 }
else if ((N_SO_index == sym_idx - 1) &&
3674 ((sym_idx - 1) < num_syms)) {
3678 llvm::StringRef so_path = sym[sym_idx - 1]
3682 if (!so_path.empty()) {
3683 std::string full_so_path(so_path);
3684 const size_t double_slash_pos = full_so_path.find(
"//");
3685 if (double_slash_pos != std::string::npos) {
3693 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3694 FileSpec::Style::native);
3697 full_so_path.erase(0, double_slash_pos + 1);
3701 if (*full_so_path.rbegin() !=
'/')
3702 full_so_path +=
'/';
3703 full_so_path += symbol_name;
3707 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3711 N_SO_index = sym_idx;
3731 N_INCL_indexes.push_back(sym_idx);
3740 if (!N_INCL_indexes.empty()) {
3744 N_INCL_indexes.pop_back();
3779 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3788 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3789 N_BRAC_indexes.push_back(sym_idx);
3798 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3799 if (!N_BRAC_indexes.empty()) {
3803 N_BRAC_indexes.pop_back();
3819 N_COMM_indexes.push_back(sym_idx);
3824 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3833 if (!N_COMM_indexes.empty()) {
3837 N_COMM_indexes.pop_back();
3851 uint8_t n_type = N_TYPE & nlist.n_type;
3852 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3856 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3857 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3860 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3863 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3864 indirect_symbol_names.insert(
3865 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3871 if (symbol_name && symbol_name[0]) {
3873 ((symbol_name[0] ==
'_') ? 1 : 0));
3874 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3887 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3889 if (!symbol_section) {
3895 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3898 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3900 switch (section_type) {
3901 case S_CSTRING_LITERALS:
3904 case S_4BYTE_LITERALS:
3907 case S_8BYTE_LITERALS:
3910 case S_LITERAL_POINTERS:
3913 case S_NON_LAZY_SYMBOL_POINTERS:
3916 case S_LAZY_SYMBOL_POINTERS:
3919 case S_SYMBOL_STUBS:
3923 case S_MOD_INIT_FUNC_POINTERS:
3926 case S_MOD_TERM_FUNC_POINTERS:
3933 case S_16BYTE_LITERALS:
3939 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3943 switch (symbol_section->GetType()) {
3965 const char *symbol_sect_name =
3966 symbol_section->GetName().AsCString(
nullptr);
3967 if (symbol_section->IsDescendant(text_section_sp.get())) {
3968 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3969 S_ATTR_SELF_MODIFYING_CODE |
3970 S_ATTR_SOME_INSTRUCTIONS))
3974 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3975 symbol_section->IsDescendant(
3976 data_dirty_section_sp.get()) ||
3977 symbol_section->IsDescendant(
3978 data_const_section_sp.get())) {
3979 if (symbol_sect_name &&
3980 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
3984 symbol_name, symbol_name_non_abi_mangled, type))
3985 demangled_is_synthesized =
true;
3986 }
else if (symbol_sect_name &&
3987 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
3993 }
else if (symbol_sect_name &&
3994 ::strstr(symbol_sect_name,
"__IMPORT") ==
3997 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
3999 if (symbol_name && symbol_name[0] ==
'.') {
4000 llvm::StringRef symbol_name_ref(symbol_name);
4001 llvm::StringRef g_objc_v1_prefix_class(
4002 ".objc_class_name_");
4003 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4004 symbol_name_non_abi_mangled = symbol_name;
4005 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4007 demangled_is_synthesized =
true;
4018 sym[sym_idx].
Clear();
4022 uint64_t symbol_value = nlist.n_value;
4024 if (symbol_name_non_abi_mangled) {
4030 if (symbol_name && symbol_name[0] ==
'_') {
4041 const char *gsym_name = sym[sym_idx]
4046 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4049 if (symbol_section) {
4050 const addr_t section_file_addr = symbol_section->GetFileAddress();
4051 symbol_value -= section_file_addr;
4060 std::pair<ValueToSymbolIndexMap::const_iterator,
4061 ValueToSymbolIndexMap::const_iterator>
4063 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4064 if (range.first != range.second) {
4065 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4066 pos != range.second; ++pos) {
4070 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4074 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4075 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4076 if (resolver_addresses.find(nlist.n_value) !=
4077 resolver_addresses.end())
4079 sym[sym_idx].
Clear();
4084 if (resolver_addresses.find(nlist.n_value) !=
4085 resolver_addresses.end())
4095 std::pair<ValueToSymbolIndexMap::const_iterator,
4096 ValueToSymbolIndexMap::const_iterator>
4098 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4099 if (range.first != range.second) {
4100 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4101 pos != range.second; ++pos) {
4105 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4109 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4110 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4111 sym[sym_idx].
Clear();
4117 const char *gsym_name = sym[sym_idx]
4122 ConstNameToSymbolIndexMap::const_iterator pos =
4123 N_GSYM_name_to_sym_idx.find(gsym_name);
4124 if (pos != N_GSYM_name_to_sym_idx.end()) {
4125 const uint32_t GSYM_sym_idx = pos->second;
4126 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4130 Address(symbol_section, symbol_value);
4132 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4136 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4137 sym[sym_idx].
Clear();
4145 sym[sym_idx].
SetID(nlist_idx);
4150 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4152 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4153 if (nlist.n_desc & N_WEAK_REF)
4156 if (demangled_is_synthesized)
4165 std::vector<struct nlist_64> nlists;
4166 nlists.reserve(symtab_load_command.
nsyms);
4167 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4169 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4170 nlists.push_back(*nlist);
4180 for (
auto &nlist : nlists) {
4181 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4187 for (
auto &nlist : nlists) {
4192 for (
const auto &pos : reexport_shlib_needs_fixup) {
4193 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4194 if (undef_pos != undefined_name_to_desc.end()) {
4195 const uint8_t dylib_ordinal =
4196 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4197 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4205 int trie_symbol_table_augment_count = 0;
4206 for (
auto &e : external_sym_trie_entries) {
4207 if (!symbols_added.contains(e.entry.address))
4208 trie_symbol_table_augment_count++;
4211 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4212 num_syms = sym_idx + trie_symbol_table_augment_count;
4213 sym = symtab.
Resize(num_syms);
4215 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4218 for (
auto &e : external_sym_trie_entries) {
4219 if (symbols_added.contains(e.entry.address))
4225 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4227 const char *symbol_name = e.entry.name.GetCString();
4228 bool demangled_is_synthesized =
false;
4230 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4231 data_section_sp, data_dirty_section_sp,
4232 data_const_section_sp, symbol_section);
4235 if (symbol_section) {
4236 sym[sym_idx].
SetID(synthetic_sym_id++);
4238 if (demangled_is_synthesized)
4251 if (function_starts_count > 0) {
4252 uint32_t num_synthetic_function_symbols = 0;
4253 for (i = 0; i < function_starts_count; ++i) {
4254 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4255 ++num_synthetic_function_symbols;
4258 if (num_synthetic_function_symbols > 0) {
4259 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4260 num_syms = sym_idx + num_synthetic_function_symbols;
4261 sym = symtab.
Resize(num_syms);
4263 for (i = 0; i < function_starts_count; ++i) {
4264 const FunctionStarts::Entry *func_start_entry =
4265 function_starts.GetEntryAtIndex(i);
4266 if (!symbols_added.contains(func_start_entry->addr)) {
4267 addr_t symbol_file_addr = func_start_entry->addr;
4268 uint32_t symbol_flags = 0;
4269 if (func_start_entry->data)
4272 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4274 if (symbol_section) {
4275 sym[sym_idx].
SetID(synthetic_sym_id++);
4285 sym[sym_idx].
SetFlags(symbol_flags);
4296 if (sym_idx < num_syms) {
4298 sym = symtab.
Resize(num_syms);
4303 if (indirect_symbol_index_data.GetByteSize()) {
4304 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4305 m_nlist_idx_to_sym_idx.end();
4312 if (symbol_stub_byte_size == 0)
4315 const uint32_t num_symbol_stubs =
4318 if (num_symbol_stubs == 0)
4321 const uint32_t symbol_stub_index_offset =
4323 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4324 const uint32_t symbol_stub_index =
4325 symbol_stub_index_offset + stub_idx;
4328 (stub_idx * symbol_stub_byte_size);
4330 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4331 symbol_stub_offset, 4)) {
4332 const uint32_t stub_sym_id =
4333 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4334 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4337 NListIndexToSymbolIndexMap::const_iterator index_pos =
4338 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4339 Symbol *stub_symbol =
nullptr;
4340 if (index_pos != end_index_pos) {
4351 Address so_addr(symbol_stub_addr, section_list);
4358 if (resolver_addresses.find(symbol_stub_addr) ==
4359 resolver_addresses.end())
4369 if (sym_idx >= num_syms) {
4370 sym = symtab.
Resize(++num_syms);
4371 stub_symbol =
nullptr;
4373 sym[sym_idx].
SetID(synthetic_sym_id++);
4374 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4375 if (resolver_addresses.find(symbol_stub_addr) ==
4376 resolver_addresses.end())
4388 "warning: symbol stub referencing symbol table "
4389 "symbol %u that isn't in our minimal symbol table, "
4400 if (!reexport_trie_entries.empty()) {
4401 for (
const auto &e : reexport_trie_entries) {
4402 if (e.entry.import_name) {
4405 if (indirect_symbol_names.find(e.entry.name) ==
4406 indirect_symbol_names.end()) {
4408 if (sym_idx >= num_syms)
4409 sym = symtab.
Resize(++num_syms);
4410 sym[sym_idx].
SetID(synthetic_sym_id++);
4415 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
6207 Target &target = process_sp->GetTarget();
6209 const llvm::Triple &target_triple = target_arch.
GetTriple();
6210 if (target_triple.getVendor() == llvm::Triple::Apple &&
6211 (target_triple.getOS() == llvm::Triple::MacOSX ||
6212 target_triple.getOS() == llvm::Triple::IOS ||
6213 target_triple.getOS() == llvm::Triple::WatchOS ||
6214 target_triple.getOS() == llvm::Triple::TvOS ||
6215 target_triple.getOS() == llvm::Triple::BridgeOS ||
6216 target_triple.getOS() == llvm::Triple::XROS)) {
6217 bool make_core =
false;
6219 case llvm::Triple::aarch64:
6220 case llvm::Triple::aarch64_32:
6221 case llvm::Triple::arm:
6222 case llvm::Triple::thumb:
6223 case llvm::Triple::x86:
6224 case llvm::Triple::x86_64:
6229 "unsupported core architecture: %s", target_triple.str().c_str());
6235 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6236 if (
error.Success()) {
6239 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6240 for (
const auto &core_range_info : core_ranges) {
6242 const auto &core_range = core_range_info.data;
6243 uint32_t cmd_type = LC_SEGMENT_64;
6244 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6245 if (addr_byte_size == 4) {
6246 cmd_type = LC_SEGMENT;
6247 segment_size =
sizeof(llvm::MachO::segment_command);
6251 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6253 uint32_t vm_prot = 0;
6254 if (core_range.lldb_permissions & ePermissionsReadable)
6255 vm_prot |= VM_PROT_READ;
6256 if (core_range.lldb_permissions & ePermissionsWritable)
6257 vm_prot |= VM_PROT_WRITE;
6258 if (core_range.lldb_permissions & ePermissionsExecutable)
6259 vm_prot |= VM_PROT_EXECUTE;
6260 const addr_t vm_addr = core_range.range.start();
6261 const addr_t vm_size = core_range.range.size();
6262 llvm::MachO::segment_command_64
segment = {
6274 segment_load_commands.push_back(
segment);
6279 llvm::MachO::mach_header_64 mach_header;
6280 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6283 mach_header.filetype = MH_CORE;
6284 mach_header.ncmds = segment_load_commands.size();
6285 mach_header.flags = 0;
6286 mach_header.reserved = 0;
6287 ThreadList &thread_list = process_sp->GetThreadList();
6288 const uint32_t num_threads = thread_list.
GetSize();
6294 std::vector<StreamString> LC_THREAD_datas(num_threads);
6295 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6297 LC_THREAD_data.SetByteOrder(byte_order);
6299 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6302 switch (mach_header.cputype) {
6303 case llvm::MachO::CPU_TYPE_ARM64:
6304 case llvm::MachO::CPU_TYPE_ARM64_32:
6306 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6309 case llvm::MachO::CPU_TYPE_ARM:
6311 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6314 case llvm::MachO::CPU_TYPE_X86_64:
6316 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6319 case llvm::MachO::CPU_TYPE_RISCV:
6321 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6328 if (addr_byte_size == 8) {
6329 mach_header.sizeofcmds = segment_load_commands.size() *
6330 sizeof(llvm::MachO::segment_command_64);
6332 mach_header.sizeofcmds = segment_load_commands.size() *
6333 sizeof(llvm::MachO::segment_command);
6337 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6338 ++mach_header.ncmds;
6339 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6344 uint64_t address_mask = process_sp->GetCodeAddressMask();
6347 mach_header.ncmds++;
6348 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6352 mach_header.ncmds++;
6353 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6356 mach_header.ncmds++;
6357 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6360 buffer.
PutHex32(mach_header.magic);
6361 buffer.
PutHex32(mach_header.cputype);
6362 buffer.
PutHex32(mach_header.cpusubtype);
6363 buffer.
PutHex32(mach_header.filetype);
6364 buffer.
PutHex32(mach_header.ncmds);
6365 buffer.
PutHex32(mach_header.sizeofcmds);
6366 buffer.
PutHex32(mach_header.flags);
6367 if (addr_byte_size == 8) {
6368 buffer.
PutHex32(mach_header.reserved);
6373 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6375 file_offset = llvm::alignTo(file_offset, 16);
6376 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6380 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6382 addrable_bits_lcnote_up->name =
"addrable bits";
6383 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6384 int bits = std::bitset<64>(~address_mask).count();
6385 addrable_bits_lcnote_up->payload.PutHex32(4);
6386 addrable_bits_lcnote_up->payload.PutHex32(
6388 addrable_bits_lcnote_up->payload.PutHex32(
6390 addrable_bits_lcnote_up->payload.PutHex32(0);
6392 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6394 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6398 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6400 thread_extrainfo_lcnote_up->name =
"process metadata";
6401 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6404 std::make_shared<StructuredData::Dictionary>());
6406 std::make_shared<StructuredData::Array>());
6408 process_sp->CalculateCoreFileThreadList(options)) {
6410 std::make_shared<StructuredData::Dictionary>());
6411 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6412 threads->AddItem(thread);
6414 dict->AddItem(
"threads", threads);
6416 dict->Dump(strm,
false);
6417 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.
GetData(),
6420 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6421 file_offset = llvm::alignTo(file_offset, 16);
6422 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6425 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6427 all_image_infos_lcnote_up->name =
"all image infos";
6428 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6430 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6432 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6435 for (
auto &lcnote : lc_notes) {
6438 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6440 memset(namebuf, 0,
sizeof(namebuf));
6446 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6448 buffer.
PutHex64(lcnote->payload_file_offset);
6449 buffer.
PutHex64(lcnote->payload.GetSize());
6453 file_offset = llvm::alignTo(file_offset, 4096);
6455 for (
auto &
segment : segment_load_commands) {
6456 segment.fileoff = file_offset;
6457 file_offset +=
segment.filesize;
6461 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6462 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6464 buffer.
PutHex32(8 + LC_THREAD_data_size);
6465 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6469 for (
const auto &
segment : segment_load_commands) {
6473 if (addr_byte_size == 8) {
6490 std::string core_file_path(outfile.
GetPath());
6498 uint8_t bytes[0x1000];
6500 size_t bytes_written = buffer.
GetString().size();
6502 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6503 if (
error.Success()) {
6505 for (
auto &lcnote : lc_notes) {
6506 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6509 "Unable to seek to corefile pos "
6510 "to write '%s' LC_NOTE payload",
6511 lcnote->name.c_str());
6514 bytes_written = lcnote->payload.GetSize();
6515 error = core_file.get()->Write(lcnote->payload.GetData(),
6517 if (!
error.Success())
6522 for (
const auto &
segment : segment_load_commands) {
6523 if (core_file.get()->SeekFromStart(
segment.fileoff) == -1) {
6525 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6526 segment.fileoff, core_file_path.c_str());
6532 " bytes of data for memory region at 0x%" PRIx64
"\n",
6537 while (bytes_left > 0 &&
error.Success()) {
6538 const size_t bytes_to_read =
6539 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6544 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6547 if (bytes_read == bytes_to_read) {
6548 size_t bytes_written = bytes_read;
6549 error = core_file.get()->Write(bytes, bytes_written);
6550 bytes_left -= bytes_read;
6555 memset(bytes, 0, bytes_to_read);
6556 size_t bytes_written = bytes_to_read;
6557 error = core_file.get()->Write(bytes, bytes_written);
6558 bytes_left -= bytes_to_read;
6559 addr += bytes_to_read;