2078 llvm::StringRef file_name = file.
GetFilename().nonEmptyOr(
"<Unknown>");
2080 file_name.str().c_str());
2081 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2082 Progress progress(
"Parsing symbol table", file_name.str());
2097 llvm::DenseSet<addr_t> symbols_added;
2101 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2105 symbols_added.insert(file_addr);
2107 FunctionStarts function_starts;
2113 for (i = 0; i <
m_header.ncmds; ++i) {
2116 llvm::MachO::load_command lc;
2117 if (
m_data_nsp->GetU32(&offset, &lc, 2) ==
nullptr)
2122 llvm::MachO::symtab_command lc_obj;
2123 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2124 lc_obj.cmd = lc.cmd;
2125 lc_obj.cmdsize = lc.cmdsize;
2126 symtab_load_command = lc_obj;
2131 case LC_DYLD_INFO_ONLY: {
2132 llvm::MachO::dyld_info_command lc_obj;
2133 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2134 lc_obj.cmd = lc.cmd;
2135 lc_obj.cmdsize = lc.cmdsize;
2141 case LC_LOAD_WEAK_DYLIB:
2142 case LC_REEXPORT_DYLIB:
2144 case LC_LOAD_UPWARD_DYLIB: {
2145 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2146 const char *path =
m_data_nsp->PeekCStr(name_offset);
2154 if (lc.cmd == LC_REEXPORT_DYLIB) {
2158 dylib_files.
Append(file_spec);
2162 case LC_DYLD_EXPORTS_TRIE: {
2163 llvm::MachO::linkedit_data_command lc_obj;
2164 lc_obj.cmd = lc.cmd;
2165 lc_obj.cmdsize = lc.cmdsize;
2166 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2167 exports_trie_load_command = lc_obj;
2169 case LC_FUNCTION_STARTS: {
2170 llvm::MachO::linkedit_data_command lc_obj;
2171 lc_obj.cmd = lc.cmd;
2172 lc_obj.cmdsize = lc.cmdsize;
2173 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2174 function_starts_load_command = lc_obj;
2178 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2181 image_uuid =
UUID(uuid_bytes, 16);
2188 offset = cmd_offset + lc.cmdsize;
2191 if (!symtab_load_command.
cmd)
2195 if (section_list ==
nullptr)
2198 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2200 bool bit_width_32 = addr_byte_size == 4;
2201 const size_t nlist_byte_size =
2202 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2204 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2205 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2206 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2207 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2209 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2211 const
addr_t nlist_data_byte_size =
2212 symtab_load_command.nsyms * nlist_byte_size;
2213 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2216 ProcessSP process_sp(m_process_wp.lock());
2217 Process *process = process_sp.get();
2221 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2231 section_list->FindSectionByName(g_segment_name_TEXT));
2233 section_list->FindSectionByName(g_segment_name_DATA));
2235 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2237 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2239 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2241 section_list->FindSectionByName(g_segment_name_OBJC));
2244 if (text_section_sp.get()) {
2245 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2246 g_section_name_eh_frame);
2247 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2248 g_section_name_lldb_no_nlist);
2250 eh_frame_section_sp =
2252 lldb_no_nlist_section_sp =
2256 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2257 !is_local_shared_cache_image) {
2258 Target &target = process->GetTarget();
2267 if (lldb_no_nlist_section_sp)
2272 if (linkedit_section_sp) {
2273 addr_t linkedit_load_addr =
2274 linkedit_section_sp->GetLoadBaseAddress(&target);
2284 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2285 const addr_t symoff_addr = linkedit_load_addr +
2286 symtab_load_command.
symoff -
2287 linkedit_file_offset;
2288 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2289 linkedit_file_offset;
2297 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2299 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2301 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2303 const addr_t indirect_syms_addr = linkedit_load_addr +
2305 linkedit_file_offset;
2307 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2308 if (indirect_syms_data_sp)
2309 indirect_symbol_index_data.SetData(
2310 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2320 if (!is_shared_cache_image) {
2322 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2323 if (strtab_data_sp) {
2324 strtab_data.SetData(strtab_data_sp, 0,
2325 strtab_data_sp->GetByteSize());
2330 if (function_starts_load_command.
cmd) {
2331 const addr_t func_start_addr =
2332 linkedit_load_addr + function_starts_load_command.
dataoff -
2333 linkedit_file_offset;
2336 function_starts_load_command.
datasize));
2337 if (func_start_data_sp)
2338 function_starts_data.SetData(func_start_data_sp, 0,
2339 func_start_data_sp->GetByteSize());
2345 if (is_local_shared_cache_image) {
2353 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2356 symtab_load_command.
symoff += linkedit_slide;
2357 symtab_load_command.
stroff += linkedit_slide;
2360 function_starts_load_command.
dataoff += linkedit_slide;
2361 exports_trie_load_command.
dataoff += linkedit_slide;
2365 nlist_data_byte_size);
2366 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2367 strtab_data_byte_size);
2372 && (exports_trie_load_command.
datasize > 0)));
2376 }
else if (exports_trie_load_command.
datasize > 0) {
2379 exports_trie_load_command.
datasize);
2383 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2386 if (function_starts_load_command.
cmd) {
2387 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2388 function_starts_load_command.
dataoff,
2389 function_starts_load_command.
datasize);
2393 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2395 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2412 if (text_section_sp && function_starts_data.GetByteSize()) {
2413 FunctionStarts::Entry function_start_entry;
2414 function_start_entry.data =
false;
2416 function_start_entry.addr = text_section_sp->GetFileAddress();
2418 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2421 function_start_entry.addr += delta;
2423 if (function_start_entry.addr & 1) {
2425 function_start_entry.data =
true;
2426 }
else if (always_thumb) {
2427 function_start_entry.data =
true;
2430 function_starts.Append(function_start_entry);
2438 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2444 addr_t text_base_addr = text_section_sp->GetFileAddress();
2445 size_t count = functions.
GetSize();
2446 for (
size_t i = 0; i < count; ++i) {
2450 FunctionStarts::Entry function_start_entry;
2451 function_start_entry.addr = func->
base - text_base_addr;
2453 if (function_start_entry.addr & 1) {
2455 function_start_entry.data =
true;
2456 }
else if (always_thumb) {
2457 function_start_entry.data =
true;
2460 function_starts.Append(function_start_entry);
2466 const size_t function_starts_count = function_starts.GetSize();
2481 if (unwind_or_symbol_log)
2482 module_sp->LogMessage(
2483 unwind_or_symbol_log,
2484 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2487 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2488 ? eh_frame_section_sp->GetID()
2494 std::vector<uint32_t> N_FUN_indexes;
2495 std::vector<uint32_t> N_NSYM_indexes;
2496 std::vector<uint32_t> N_INCL_indexes;
2497 std::vector<uint32_t> N_BRAC_indexes;
2498 std::vector<uint32_t> N_COMM_indexes;
2499 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2500 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2501 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2502 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2503 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2504 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2507 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2508 uint32_t nlist_idx = 0;
2509 Symbol *symbol_ptr =
nullptr;
2511 uint32_t sym_idx = 0;
2513 size_t num_syms = 0;
2514 std::string memory_symbol_name;
2515 uint32_t unmapped_local_symbols_found = 0;
2517 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2518 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2519 std::set<lldb::addr_t> resolver_addresses;
2521 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2522 if (dyld_trie_data_size > 0) {
2523 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2527 if (text_segment_sp)
2528 text_segment_file_addr = text_segment_sp->GetFileAddress();
2530 resolver_addresses, reexport_trie_entries,
2531 external_sym_trie_entries);
2534 typedef std::set<ConstString> IndirectSymbols;
2535 IndirectSymbols indirect_symbol_names;
2558 UUID process_shared_cache_uuid;
2559 addr_t process_shared_cache_base_addr;
2563 process_shared_cache_uuid);
2566 __block
bool found_image =
false;
2567 __block
void *nlist_buffer =
nullptr;
2568 __block
unsigned nlist_count = 0;
2569 __block
char *string_table =
nullptr;
2570 __block vm_offset_t vm_nlist_memory = 0;
2571 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2572 __block vm_offset_t vm_string_memory = 0;
2573 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2575 llvm::scope_exit _(^{
2576 if (vm_nlist_memory)
2577 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2578 if (vm_string_memory)
2579 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2582 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2583 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2584 UndefinedNameToDescMap undefined_name_to_desc;
2585 SymbolIndexToName reexport_shlib_needs_fixup;
2593 if (process_shared_cache_uuid.
IsValid() &&
2594 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2603 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2610 dyld_image_local_nlist_content_4Symbolication(
2611 image, ^(
const void *nlistStart, uint64_t nlistCount,
2612 const char *stringTable) {
2613 if (!nlistStart || !nlistCount)
2621 nlist_byte_size * nlistCount, &vm_nlist_memory,
2622 &vm_nlist_bytes_read);
2625 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2630 vm_address_t string_address = (vm_address_t)stringTable;
2631 vm_size_t region_size;
2632 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2633 vm_region_basic_info_data_t info;
2634 memory_object_name_t object;
2636 ®ion_size, VM_REGION_BASIC_INFO_64,
2637 (vm_region_info_t)&info, &info_count, &
object);
2643 ((vm_address_t)stringTable - string_address),
2644 &vm_string_memory, &vm_string_bytes_read);
2648 nlist_buffer = (
void *)vm_nlist_memory;
2649 string_table = (
char *)vm_string_memory;
2650 nlist_count = nlistCount;
2656 nlist_count * nlist_byte_size,
2657 byte_order, addr_byte_size);
2658 unmapped_local_symbols_found = nlist_count;
2664 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2669 for (uint32_t nlist_index = 0;
2670 nlist_index < nlist_count;
2674 std::optional<struct nlist_64> nlist_maybe =
2675 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2679 struct nlist_64 nlist = *nlist_maybe;
2682 const char *symbol_name = string_table + nlist.n_strx;
2684 if (symbol_name == NULL) {
2689 "DSC unmapped local symbol[{0}] has invalid "
2690 "string table offset {1:x} in {2}, ignoring symbol",
2691 nlist_index, nlist.n_strx,
2692 module_sp->GetFileSpec().GetPath()));
2695 if (symbol_name[0] ==
'\0')
2698 const char *symbol_name_non_abi_mangled = NULL;
2701 bool add_nlist =
true;
2702 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2703 bool demangled_is_synthesized =
false;
2704 bool is_gsym =
false;
2705 bool set_value =
true;
2707 assert(sym_idx < num_syms);
2712 switch (nlist.n_type) {
2732 symbol_name, symbol_name_non_abi_mangled,
2734 demangled_is_synthesized =
true;
2736 if (nlist.n_value != 0)
2738 nlist.n_sect, nlist.n_value);
2754 nlist.n_sect, nlist.n_value);
2756 N_FUN_addr_to_sym_idx.insert(
2757 std::make_pair(nlist.n_value, sym_idx));
2761 N_FUN_indexes.push_back(sym_idx);
2765 if (!N_FUN_indexes.empty()) {
2772 N_FUN_indexes.pop_back();
2784 N_STSYM_addr_to_sym_idx.insert(
2785 std::make_pair(nlist.n_value, sym_idx));
2786 symbol_section = section_info.
GetSection(nlist.n_sect,
2788 if (symbol_name && symbol_name[0]) {
2796 symbol_section = section_info.
GetSection(nlist.n_sect,
2830 symbol_section = section_info.
GetSection(nlist.n_sect,
2843 if (symbol_name == NULL) {
2854 N_NSYM_indexes.clear();
2855 N_INCL_indexes.clear();
2856 N_BRAC_indexes.clear();
2857 N_COMM_indexes.clear();
2858 N_FUN_indexes.clear();
2864 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2865 if (N_SO_has_full_path) {
2866 if ((N_SO_index == sym_idx - 1) &&
2867 ((sym_idx - 1) < num_syms)) {
2873 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2879 N_SO_index = sym_idx;
2881 }
else if ((N_SO_index == sym_idx - 1) &&
2882 ((sym_idx - 1) < num_syms)) {
2887 const char *so_path = sym[sym_idx - 1]
2891 if (so_path && so_path[0]) {
2892 std::string full_so_path(so_path);
2893 const size_t double_slash_pos =
2894 full_so_path.find(
"//");
2895 if (double_slash_pos != std::string::npos) {
2906 &full_so_path[double_slash_pos + 1],
2907 FileSpec::Style::native);
2910 full_so_path.erase(0, double_slash_pos + 1);
2914 if (*full_so_path.rbegin() !=
'/')
2915 full_so_path +=
'/';
2916 full_so_path += symbol_name;
2920 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2924 N_SO_index = sym_idx;
2945 N_INCL_indexes.push_back(sym_idx);
2955 if (!N_INCL_indexes.empty()) {
2960 N_INCL_indexes.pop_back();
2995 symbol_section = section_info.
GetSection(nlist.n_sect,
3006 symbol_section = section_info.
GetSection(nlist.n_sect,
3008 N_BRAC_indexes.push_back(sym_idx);
3018 symbol_section = section_info.
GetSection(nlist.n_sect,
3020 if (!N_BRAC_indexes.empty()) {
3025 N_BRAC_indexes.pop_back();
3042 N_COMM_indexes.push_back(sym_idx);
3047 symbol_section = section_info.
GetSection(nlist.n_sect,
3058 if (!N_COMM_indexes.empty()) {
3063 N_COMM_indexes.pop_back();
3078 uint8_t n_type = N_TYPE & nlist.n_type;
3079 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3083 const char *reexport_name_cstr =
3084 strtab_data.PeekCStr(nlist.n_value);
3085 if (reexport_name_cstr && reexport_name_cstr[0]) {
3088 reexport_name_cstr +
3089 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3092 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3094 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3100 if (symbol_name && symbol_name[0]) {
3102 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3103 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3115 symbol_section = section_info.
GetSection(nlist.n_sect,
3118 if (symbol_section == NULL) {
3124 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3127 uint32_t section_type =
3128 symbol_section->Get() & SECTION_TYPE;
3130 switch (section_type) {
3131 case S_CSTRING_LITERALS:
3134 case S_4BYTE_LITERALS:
3137 case S_8BYTE_LITERALS:
3140 case S_LITERAL_POINTERS:
3143 case S_NON_LAZY_SYMBOL_POINTERS:
3147 case S_LAZY_SYMBOL_POINTERS:
3150 case S_SYMBOL_STUBS:
3154 case S_MOD_INIT_FUNC_POINTERS:
3158 case S_MOD_TERM_FUNC_POINTERS:
3166 case S_16BYTE_LITERALS:
3172 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3176 switch (symbol_section->GetType()) {
3203 const char *symbol_sect_name =
3204 symbol_section->GetName().AsCString(
nullptr);
3205 if (symbol_section->IsDescendant(
3206 text_section_sp.get())) {
3207 if (symbol_section->IsClear(
3208 S_ATTR_PURE_INSTRUCTIONS |
3209 S_ATTR_SELF_MODIFYING_CODE |
3210 S_ATTR_SOME_INSTRUCTIONS))
3214 }
else if (symbol_section->IsDescendant(
3215 data_section_sp.get()) ||
3216 symbol_section->IsDescendant(
3217 data_dirty_section_sp.get()) ||
3218 symbol_section->IsDescendant(
3219 data_const_section_sp.get())) {
3220 if (symbol_sect_name &&
3221 ::strstr(symbol_sect_name,
"__objc") ==
3227 symbol_name_non_abi_mangled, type))
3228 demangled_is_synthesized =
true;
3229 }
else if (symbol_sect_name &&
3230 ::strstr(symbol_sect_name,
3231 "__gcc_except_tab") ==
3237 }
else if (symbol_sect_name &&
3238 ::strstr(symbol_sect_name,
"__IMPORT") ==
3241 }
else if (symbol_section->IsDescendant(
3242 objc_section_sp.get())) {
3244 if (symbol_name && symbol_name[0] ==
'.') {
3245 llvm::StringRef symbol_name_ref(symbol_name);
3247 g_objc_v1_prefix_class(
".objc_class_name_");
3248 if (symbol_name_ref.starts_with(
3249 g_objc_v1_prefix_class)) {
3250 symbol_name_non_abi_mangled = symbol_name;
3251 symbol_name = symbol_name +
3252 g_objc_v1_prefix_class.size();
3254 demangled_is_synthesized =
true;
3265 uint64_t symbol_value = nlist.n_value;
3266 if (symbol_name_non_abi_mangled) {
3272 if (symbol_name && symbol_name[0] ==
'_') {
3279 if (is_gsym && is_debug) {
3280 const char *gsym_name =
3286 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3290 if (symbol_section) {
3291 const addr_t section_file_addr =
3292 symbol_section->GetFileAddress();
3293 symbol_value -= section_file_addr;
3296 if (is_debug ==
false) {
3304 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3305 if (range.first != range.second) {
3306 bool found_it =
false;
3307 for (
auto pos = range.first; pos != range.second;
3309 if (sym[sym_idx].GetMangled().
GetName(
3313 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3319 sym[sym_idx].IsExternal());
3320 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3322 if (resolver_addresses.find(nlist.n_value) !=
3323 resolver_addresses.end())
3325 sym[sym_idx].
Clear();
3333 if (resolver_addresses.find(nlist.n_value) !=
3334 resolver_addresses.end())
3346 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3348 if (range.first != range.second) {
3349 bool found_it =
false;
3350 for (
auto pos = range.first; pos != range.second;
3352 if (sym[sym_idx].GetMangled().
GetName(
3356 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3362 sym[sym_idx].IsExternal());
3363 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3365 sym[sym_idx].
Clear();
3373 const char *gsym_name =
3381 ConstNameToSymbolIndexMap::const_iterator pos =
3382 N_GSYM_name_to_sym_idx.find(gsym_name);
3383 if (pos != N_GSYM_name_to_sym_idx.end()) {
3384 const uint32_t GSYM_sym_idx = pos->second;
3385 m_nlist_idx_to_sym_idx[nlist_idx] =
3391 Address(symbol_section, symbol_value);
3392 add_symbol_addr(sym[GSYM_sym_idx]
3399 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3401 sym[sym_idx].
Clear();
3409 sym[sym_idx].
SetID(nlist_idx);
3413 Address(symbol_section, symbol_value);
3415 sym[sym_idx].GetAddress().GetFileAddress());
3417 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3419 if (demangled_is_synthesized)
3423 sym[sym_idx].
Clear();
3430 for (
const auto &pos : reexport_shlib_needs_fixup) {
3431 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3432 if (undef_pos != undefined_name_to_desc.end()) {
3433 const uint8_t dylib_ordinal =
3434 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3435 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3445 if (nlist_data.GetByteSize() > 0) {
3449 if (sym ==
nullptr) {
3455 if (unmapped_local_symbols_found) {
3457 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3463 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3464 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3465 UndefinedNameToDescMap undefined_name_to_desc;
3466 SymbolIndexToName reexport_shlib_needs_fixup;
3474 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3476 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3477 if (is_debug != debug_only)
3480 const char *symbol_name_non_abi_mangled =
nullptr;
3481 const char *symbol_name =
nullptr;
3483 if (have_strtab_data) {
3484 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3486 if (symbol_name ==
nullptr) {
3490 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3492 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3495 if (symbol_name[0] ==
'\0')
3496 symbol_name =
nullptr;
3498 const addr_t str_addr = strtab_addr + nlist.n_strx;
3500 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3502 symbol_name = memory_symbol_name.c_str();
3507 bool add_nlist =
true;
3508 bool is_gsym =
false;
3509 bool demangled_is_synthesized =
false;
3510 bool set_value =
true;
3512 assert(sym_idx < num_syms);
3516 switch (nlist.n_type) {
3534 symbol_name_non_abi_mangled, type)) {
3535 demangled_is_synthesized =
true;
3537 if (nlist.n_value != 0)
3539 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3555 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3557 N_FUN_addr_to_sym_idx.insert(
3558 std::make_pair(nlist.n_value, sym_idx));
3562 N_FUN_indexes.push_back(sym_idx);
3566 if (!N_FUN_indexes.empty()) {
3571 N_FUN_indexes.pop_back();
3582 N_STSYM_addr_to_sym_idx.insert(
3583 std::make_pair(nlist.n_value, sym_idx));
3584 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3585 if (symbol_name && symbol_name[0]) {
3593 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3624 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3636 if (symbol_name ==
nullptr) {
3647 N_NSYM_indexes.clear();
3648 N_INCL_indexes.clear();
3649 N_BRAC_indexes.clear();
3650 N_COMM_indexes.clear();
3651 N_FUN_indexes.clear();
3657 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3658 if (N_SO_has_full_path) {
3659 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3664 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3669 N_SO_index = sym_idx;
3671 }
else if ((N_SO_index == sym_idx - 1) &&
3672 ((sym_idx - 1) < num_syms)) {
3676 llvm::StringRef so_path = sym[sym_idx - 1]
3680 if (!so_path.empty()) {
3681 std::string full_so_path(so_path);
3682 const size_t double_slash_pos = full_so_path.find(
"//");
3683 if (double_slash_pos != std::string::npos) {
3691 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3692 FileSpec::Style::native);
3695 full_so_path.erase(0, double_slash_pos + 1);
3699 if (*full_so_path.rbegin() !=
'/')
3700 full_so_path +=
'/';
3701 full_so_path += symbol_name;
3705 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3709 N_SO_index = sym_idx;
3729 N_INCL_indexes.push_back(sym_idx);
3738 if (!N_INCL_indexes.empty()) {
3742 N_INCL_indexes.pop_back();
3777 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3786 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3787 N_BRAC_indexes.push_back(sym_idx);
3796 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3797 if (!N_BRAC_indexes.empty()) {
3801 N_BRAC_indexes.pop_back();
3817 N_COMM_indexes.push_back(sym_idx);
3822 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3831 if (!N_COMM_indexes.empty()) {
3835 N_COMM_indexes.pop_back();
3849 uint8_t n_type = N_TYPE & nlist.n_type;
3850 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3854 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3855 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3858 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3861 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3862 indirect_symbol_names.insert(
3863 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3869 if (symbol_name && symbol_name[0]) {
3871 ((symbol_name[0] ==
'_') ? 1 : 0));
3872 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3885 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3887 if (!symbol_section) {
3893 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3896 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3898 switch (section_type) {
3899 case S_CSTRING_LITERALS:
3902 case S_4BYTE_LITERALS:
3905 case S_8BYTE_LITERALS:
3908 case S_LITERAL_POINTERS:
3911 case S_NON_LAZY_SYMBOL_POINTERS:
3914 case S_LAZY_SYMBOL_POINTERS:
3917 case S_SYMBOL_STUBS:
3921 case S_MOD_INIT_FUNC_POINTERS:
3924 case S_MOD_TERM_FUNC_POINTERS:
3931 case S_16BYTE_LITERALS:
3937 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3941 switch (symbol_section->GetType()) {
3963 const char *symbol_sect_name =
3964 symbol_section->GetName().AsCString(
nullptr);
3965 if (symbol_section->IsDescendant(text_section_sp.get())) {
3966 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3967 S_ATTR_SELF_MODIFYING_CODE |
3968 S_ATTR_SOME_INSTRUCTIONS))
3972 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3973 symbol_section->IsDescendant(
3974 data_dirty_section_sp.get()) ||
3975 symbol_section->IsDescendant(
3976 data_const_section_sp.get())) {
3977 if (symbol_sect_name &&
3978 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
3982 symbol_name, symbol_name_non_abi_mangled, type))
3983 demangled_is_synthesized =
true;
3984 }
else if (symbol_sect_name &&
3985 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
3991 }
else if (symbol_sect_name &&
3992 ::strstr(symbol_sect_name,
"__IMPORT") ==
3995 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
3997 if (symbol_name && symbol_name[0] ==
'.') {
3998 llvm::StringRef symbol_name_ref(symbol_name);
3999 llvm::StringRef g_objc_v1_prefix_class(
4000 ".objc_class_name_");
4001 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4002 symbol_name_non_abi_mangled = symbol_name;
4003 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4005 demangled_is_synthesized =
true;
4016 sym[sym_idx].
Clear();
4020 uint64_t symbol_value = nlist.n_value;
4022 if (symbol_name_non_abi_mangled) {
4028 if (symbol_name && symbol_name[0] ==
'_') {
4039 const char *gsym_name = sym[sym_idx]
4044 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4047 if (symbol_section) {
4048 const addr_t section_file_addr = symbol_section->GetFileAddress();
4049 symbol_value -= section_file_addr;
4058 std::pair<ValueToSymbolIndexMap::const_iterator,
4059 ValueToSymbolIndexMap::const_iterator>
4061 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4062 if (range.first != range.second) {
4063 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4064 pos != range.second; ++pos) {
4068 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4072 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4073 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4074 if (resolver_addresses.find(nlist.n_value) !=
4075 resolver_addresses.end())
4077 sym[sym_idx].
Clear();
4082 if (resolver_addresses.find(nlist.n_value) !=
4083 resolver_addresses.end())
4093 std::pair<ValueToSymbolIndexMap::const_iterator,
4094 ValueToSymbolIndexMap::const_iterator>
4096 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4097 if (range.first != range.second) {
4098 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4099 pos != range.second; ++pos) {
4103 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4107 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4108 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4109 sym[sym_idx].
Clear();
4115 const char *gsym_name = sym[sym_idx]
4120 ConstNameToSymbolIndexMap::const_iterator pos =
4121 N_GSYM_name_to_sym_idx.find(gsym_name);
4122 if (pos != N_GSYM_name_to_sym_idx.end()) {
4123 const uint32_t GSYM_sym_idx = pos->second;
4124 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4128 Address(symbol_section, symbol_value);
4130 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4134 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4135 sym[sym_idx].
Clear();
4143 sym[sym_idx].
SetID(nlist_idx);
4148 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4150 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4151 if (nlist.n_desc & N_WEAK_REF)
4154 if (demangled_is_synthesized)
4163 std::vector<struct nlist_64> nlists;
4164 nlists.reserve(symtab_load_command.
nsyms);
4165 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4167 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4168 nlists.push_back(*nlist);
4178 for (
auto &nlist : nlists) {
4179 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4185 for (
auto &nlist : nlists) {
4190 for (
const auto &pos : reexport_shlib_needs_fixup) {
4191 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4192 if (undef_pos != undefined_name_to_desc.end()) {
4193 const uint8_t dylib_ordinal =
4194 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4195 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4203 int trie_symbol_table_augment_count = 0;
4204 for (
auto &e : external_sym_trie_entries) {
4205 if (!symbols_added.contains(e.entry.address))
4206 trie_symbol_table_augment_count++;
4209 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4210 num_syms = sym_idx + trie_symbol_table_augment_count;
4211 sym = symtab.
Resize(num_syms);
4213 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4216 for (
auto &e : external_sym_trie_entries) {
4217 if (symbols_added.contains(e.entry.address))
4223 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4225 const char *symbol_name = e.entry.name.GetCString();
4226 bool demangled_is_synthesized =
false;
4228 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4229 data_section_sp, data_dirty_section_sp,
4230 data_const_section_sp, symbol_section);
4233 if (symbol_section) {
4234 sym[sym_idx].
SetID(synthetic_sym_id++);
4236 if (demangled_is_synthesized)
4249 if (function_starts_count > 0) {
4250 uint32_t num_synthetic_function_symbols = 0;
4251 for (i = 0; i < function_starts_count; ++i) {
4252 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4253 ++num_synthetic_function_symbols;
4256 if (num_synthetic_function_symbols > 0) {
4257 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4258 num_syms = sym_idx + num_synthetic_function_symbols;
4259 sym = symtab.
Resize(num_syms);
4261 for (i = 0; i < function_starts_count; ++i) {
4262 const FunctionStarts::Entry *func_start_entry =
4263 function_starts.GetEntryAtIndex(i);
4264 if (!symbols_added.contains(func_start_entry->addr)) {
4265 addr_t symbol_file_addr = func_start_entry->addr;
4266 uint32_t symbol_flags = 0;
4267 if (func_start_entry->data)
4270 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4272 if (symbol_section) {
4273 sym[sym_idx].
SetID(synthetic_sym_id++);
4283 sym[sym_idx].
SetFlags(symbol_flags);
4294 if (sym_idx < num_syms) {
4296 sym = symtab.
Resize(num_syms);
4301 if (indirect_symbol_index_data.GetByteSize()) {
4302 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4303 m_nlist_idx_to_sym_idx.end();
4310 if (symbol_stub_byte_size == 0)
4313 const uint32_t num_symbol_stubs =
4316 if (num_symbol_stubs == 0)
4319 const uint32_t symbol_stub_index_offset =
4321 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4322 const uint32_t symbol_stub_index =
4323 symbol_stub_index_offset + stub_idx;
4326 (stub_idx * symbol_stub_byte_size);
4328 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4329 symbol_stub_offset, 4)) {
4330 const uint32_t stub_sym_id =
4331 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4332 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4335 NListIndexToSymbolIndexMap::const_iterator index_pos =
4336 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4337 Symbol *stub_symbol =
nullptr;
4338 if (index_pos != end_index_pos) {
4349 Address so_addr(symbol_stub_addr, section_list);
4356 if (resolver_addresses.find(symbol_stub_addr) ==
4357 resolver_addresses.end())
4367 if (sym_idx >= num_syms) {
4368 sym = symtab.
Resize(++num_syms);
4369 stub_symbol =
nullptr;
4371 sym[sym_idx].
SetID(synthetic_sym_id++);
4372 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4373 if (resolver_addresses.find(symbol_stub_addr) ==
4374 resolver_addresses.end())
4386 "warning: symbol stub referencing symbol table "
4387 "symbol %u that isn't in our minimal symbol table, "
4398 if (!reexport_trie_entries.empty()) {
4399 for (
const auto &e : reexport_trie_entries) {
4400 if (e.entry.import_name) {
4403 if (indirect_symbol_names.find(e.entry.name) ==
4404 indirect_symbol_names.end()) {
4406 if (sym_idx >= num_syms)
4407 sym = symtab.
Resize(++num_syms);
4408 sym[sym_idx].
SetID(synthetic_sym_id++);
4413 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
6203 Target &target = process_sp->GetTarget();
6205 const llvm::Triple &target_triple = target_arch.
GetTriple();
6206 if (target_triple.getVendor() == llvm::Triple::Apple &&
6207 (target_triple.getOS() == llvm::Triple::MacOSX ||
6208 target_triple.getOS() == llvm::Triple::IOS ||
6209 target_triple.getOS() == llvm::Triple::WatchOS ||
6210 target_triple.getOS() == llvm::Triple::TvOS ||
6211 target_triple.getOS() == llvm::Triple::BridgeOS ||
6212 target_triple.getOS() == llvm::Triple::XROS)) {
6213 bool make_core =
false;
6215 case llvm::Triple::aarch64:
6216 case llvm::Triple::aarch64_32:
6217 case llvm::Triple::arm:
6218 case llvm::Triple::thumb:
6219 case llvm::Triple::x86:
6220 case llvm::Triple::x86_64:
6225 "unsupported core architecture: %s", target_triple.str().c_str());
6231 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6232 if (
error.Success()) {
6235 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6236 for (
const auto &core_range_info : core_ranges) {
6238 const auto &core_range = core_range_info.data;
6239 uint32_t cmd_type = LC_SEGMENT_64;
6240 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6241 if (addr_byte_size == 4) {
6242 cmd_type = LC_SEGMENT;
6243 segment_size =
sizeof(llvm::MachO::segment_command);
6247 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6249 uint32_t vm_prot = 0;
6250 if (core_range.lldb_permissions & ePermissionsReadable)
6251 vm_prot |= VM_PROT_READ;
6252 if (core_range.lldb_permissions & ePermissionsWritable)
6253 vm_prot |= VM_PROT_WRITE;
6254 if (core_range.lldb_permissions & ePermissionsExecutable)
6255 vm_prot |= VM_PROT_EXECUTE;
6256 const addr_t vm_addr = core_range.range.start();
6257 const addr_t vm_size = core_range.range.size();
6258 llvm::MachO::segment_command_64
segment = {
6270 segment_load_commands.push_back(
segment);
6275 llvm::MachO::mach_header_64 mach_header;
6276 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6279 mach_header.filetype = MH_CORE;
6280 mach_header.ncmds = segment_load_commands.size();
6281 mach_header.flags = 0;
6282 mach_header.reserved = 0;
6283 ThreadList &thread_list = process_sp->GetThreadList();
6284 const uint32_t num_threads = thread_list.
GetSize();
6290 std::vector<StreamString> LC_THREAD_datas(num_threads);
6291 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6293 LC_THREAD_data.SetByteOrder(byte_order);
6295 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6298 switch (mach_header.cputype) {
6299 case llvm::MachO::CPU_TYPE_ARM64:
6300 case llvm::MachO::CPU_TYPE_ARM64_32:
6302 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6305 case llvm::MachO::CPU_TYPE_ARM:
6307 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6310 case llvm::MachO::CPU_TYPE_X86_64:
6312 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6315 case llvm::MachO::CPU_TYPE_RISCV:
6317 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6324 if (addr_byte_size == 8) {
6325 mach_header.sizeofcmds = segment_load_commands.size() *
6326 sizeof(llvm::MachO::segment_command_64);
6328 mach_header.sizeofcmds = segment_load_commands.size() *
6329 sizeof(llvm::MachO::segment_command);
6333 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6334 ++mach_header.ncmds;
6335 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6340 uint64_t address_mask = process_sp->GetCodeAddressMask();
6343 mach_header.ncmds++;
6344 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6348 mach_header.ncmds++;
6349 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6352 mach_header.ncmds++;
6353 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6356 buffer.
PutHex32(mach_header.magic);
6357 buffer.
PutHex32(mach_header.cputype);
6358 buffer.
PutHex32(mach_header.cpusubtype);
6359 buffer.
PutHex32(mach_header.filetype);
6360 buffer.
PutHex32(mach_header.ncmds);
6361 buffer.
PutHex32(mach_header.sizeofcmds);
6362 buffer.
PutHex32(mach_header.flags);
6363 if (addr_byte_size == 8) {
6364 buffer.
PutHex32(mach_header.reserved);
6369 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6371 file_offset = llvm::alignTo(file_offset, 16);
6372 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6376 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6378 addrable_bits_lcnote_up->name =
"addrable bits";
6379 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6380 int bits = std::bitset<64>(~address_mask).count();
6381 addrable_bits_lcnote_up->payload.PutHex32(4);
6382 addrable_bits_lcnote_up->payload.PutHex32(
6384 addrable_bits_lcnote_up->payload.PutHex32(
6386 addrable_bits_lcnote_up->payload.PutHex32(0);
6388 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6390 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6394 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6396 thread_extrainfo_lcnote_up->name =
"process metadata";
6397 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6400 std::make_shared<StructuredData::Dictionary>());
6402 std::make_shared<StructuredData::Array>());
6404 process_sp->CalculateCoreFileThreadList(options)) {
6406 std::make_shared<StructuredData::Dictionary>());
6407 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6408 threads->AddItem(thread);
6410 dict->AddItem(
"threads", threads);
6412 dict->Dump(strm,
false);
6413 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.
GetData(),
6416 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6417 file_offset = llvm::alignTo(file_offset, 16);
6418 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6421 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6423 all_image_infos_lcnote_up->name =
"all image infos";
6424 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6426 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6428 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6431 for (
auto &lcnote : lc_notes) {
6434 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6436 memset(namebuf, 0,
sizeof(namebuf));
6442 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6444 buffer.
PutHex64(lcnote->payload_file_offset);
6445 buffer.
PutHex64(lcnote->payload.GetSize());
6449 file_offset = llvm::alignTo(file_offset, 4096);
6451 for (
auto &
segment : segment_load_commands) {
6452 segment.fileoff = file_offset;
6453 file_offset +=
segment.filesize;
6457 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6458 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6460 buffer.
PutHex32(8 + LC_THREAD_data_size);
6461 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6465 for (
const auto &
segment : segment_load_commands) {
6469 if (addr_byte_size == 8) {
6486 std::string core_file_path(outfile.
GetPath());
6494 uint8_t bytes[0x1000];
6496 size_t bytes_written = buffer.
GetString().size();
6498 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6499 if (
error.Success()) {
6501 for (
auto &lcnote : lc_notes) {
6502 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6505 "Unable to seek to corefile pos "
6506 "to write '%s' LC_NOTE payload",
6507 lcnote->name.c_str());
6510 bytes_written = lcnote->payload.GetSize();
6511 error = core_file.get()->Write(lcnote->payload.GetData(),
6513 if (!
error.Success())
6518 for (
const auto &
segment : segment_load_commands) {
6519 if (core_file.get()->SeekFromStart(
segment.fileoff) == -1) {
6521 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6522 segment.fileoff, core_file_path.c_str());
6528 " bytes of data for memory region at 0x%" PRIx64
"\n",
6533 while (bytes_left > 0 &&
error.Success()) {
6534 const size_t bytes_to_read =
6535 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6540 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6543 if (bytes_read == bytes_to_read) {
6544 size_t bytes_written = bytes_read;
6545 error = core_file.get()->Write(bytes, bytes_written);
6546 bytes_left -= bytes_read;
6551 memset(bytes, 0, bytes_to_read);
6552 size_t bytes_written = bytes_to_read;
6553 error = core_file.get()->Write(bytes, bytes_written);
6554 bytes_left -= bytes_to_read;
6555 addr += bytes_to_read;