2118 llvm::StringRef file_name = file.
GetFilename().nonEmptyOr(
"<Unknown>");
2120 file_name.str().c_str());
2121 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2122 Progress progress(
"Parsing symbol table", file_name.str());
2137 llvm::DenseSet<addr_t> symbols_added;
2141 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2145 symbols_added.insert(file_addr);
2147 FunctionStarts function_starts;
2153 for (i = 0; i <
m_header.ncmds; ++i) {
2156 llvm::MachO::load_command lc;
2162 llvm::MachO::symtab_command lc_obj;
2163 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2164 lc_obj.cmd = lc.cmd;
2165 lc_obj.cmdsize = lc.cmdsize;
2166 symtab_load_command = lc_obj;
2171 case LC_DYLD_INFO_ONLY: {
2172 llvm::MachO::dyld_info_command lc_obj;
2173 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2174 lc_obj.cmd = lc.cmd;
2175 lc_obj.cmdsize = lc.cmdsize;
2181 case LC_LOAD_WEAK_DYLIB:
2182 case LC_REEXPORT_DYLIB:
2184 case LC_LOAD_UPWARD_DYLIB: {
2185 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2186 if (std::optional<llvm::StringRef> path =
2191 if (path->starts_with(
"@"))
2194 if (lc.cmd == LC_REEXPORT_DYLIB) {
2198 dylib_files.
Append(file_spec);
2202 case LC_DYLD_EXPORTS_TRIE: {
2203 llvm::MachO::linkedit_data_command lc_obj;
2204 lc_obj.cmd = lc.cmd;
2205 lc_obj.cmdsize = lc.cmdsize;
2206 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2207 exports_trie_load_command = lc_obj;
2209 case LC_FUNCTION_STARTS: {
2210 llvm::MachO::linkedit_data_command lc_obj;
2211 lc_obj.cmd = lc.cmd;
2212 lc_obj.cmdsize = lc.cmdsize;
2213 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2214 function_starts_load_command = lc_obj;
2218 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2221 image_uuid =
UUID(uuid_bytes, 16);
2228 offset = cmd_offset + lc.cmdsize;
2231 if (!symtab_load_command.
cmd)
2235 if (section_list ==
nullptr)
2238 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2240 bool bit_width_32 = addr_byte_size == 4;
2241 const size_t nlist_byte_size =
2242 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2244 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2245 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2246 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2247 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2249 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2251 const
addr_t nlist_data_byte_size =
2252 symtab_load_command.nsyms * nlist_byte_size;
2253 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2256 ProcessSP process_sp(m_process_wp.lock());
2257 Process *process = process_sp.get();
2261 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2264 section_list->FindSectionByName(GetSegmentNameTEXT()));
2266 section_list->FindSectionByName(GetSegmentNameDATA()));
2268 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2270 section_list->FindSectionByName(GetSegmentNameDATA_DIRTY()));
2272 section_list->FindSectionByName(GetSegmentNameDATA_CONST()));
2274 section_list->FindSectionByName(GetSegmentNameOBJC()));
2279 if (text_section_sp.get()) {
2280 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2281 g_section_name_eh_frame);
2282 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2283 g_section_name_lldb_no_nlist);
2285 eh_frame_section_sp =
2287 lldb_no_nlist_section_sp =
2291 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2292 !is_local_shared_cache_image) {
2293 Target &target = process->GetTarget();
2302 if (lldb_no_nlist_section_sp)
2307 if (linkedit_section_sp) {
2308 addr_t linkedit_load_addr =
2309 linkedit_section_sp->GetLoadBaseAddress(&target);
2319 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2320 const addr_t symoff_addr = linkedit_load_addr +
2321 symtab_load_command.
symoff -
2322 linkedit_file_offset;
2323 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2324 linkedit_file_offset;
2332 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2334 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2336 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2338 const addr_t indirect_syms_addr = linkedit_load_addr +
2340 linkedit_file_offset;
2342 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2343 if (indirect_syms_data_sp)
2344 indirect_symbol_index_data.SetData(
2345 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2355 if (!is_shared_cache_image) {
2357 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2358 if (strtab_data_sp) {
2359 strtab_data.SetData(strtab_data_sp, 0,
2360 strtab_data_sp->GetByteSize());
2365 if (function_starts_load_command.
cmd) {
2366 const addr_t func_start_addr =
2367 linkedit_load_addr + function_starts_load_command.
dataoff -
2368 linkedit_file_offset;
2371 function_starts_load_command.
datasize));
2372 if (func_start_data_sp)
2373 function_starts_data.SetData(func_start_data_sp, 0,
2374 func_start_data_sp->GetByteSize());
2380 if (is_local_shared_cache_image && linkedit_section_sp) {
2388 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2391 symtab_load_command.
symoff += linkedit_slide;
2392 symtab_load_command.
stroff += linkedit_slide;
2395 function_starts_load_command.
dataoff += linkedit_slide;
2396 exports_trie_load_command.
dataoff += linkedit_slide;
2400 nlist_data_byte_size);
2401 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2402 strtab_data_byte_size);
2407 && (exports_trie_load_command.
datasize > 0)));
2411 }
else if (exports_trie_load_command.
datasize > 0) {
2414 exports_trie_load_command.
datasize);
2418 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2421 if (function_starts_load_command.
cmd) {
2422 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2423 function_starts_load_command.
dataoff,
2424 function_starts_load_command.
datasize);
2428 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2430 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2447 if (text_section_sp && function_starts_data.GetByteSize()) {
2448 FunctionStarts::Entry function_start_entry;
2449 function_start_entry.data =
false;
2451 function_start_entry.addr = text_section_sp->GetFileAddress();
2453 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2456 function_start_entry.addr += delta;
2458 if (function_start_entry.addr & 1) {
2460 function_start_entry.data =
true;
2461 }
else if (always_thumb) {
2462 function_start_entry.data =
true;
2465 function_starts.Append(function_start_entry);
2473 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2479 addr_t text_base_addr = text_section_sp->GetFileAddress();
2480 size_t count = functions.
GetSize();
2481 for (
size_t i = 0; i < count; ++i) {
2485 FunctionStarts::Entry function_start_entry;
2486 function_start_entry.addr = func->
base - text_base_addr;
2488 if (function_start_entry.addr & 1) {
2490 function_start_entry.data =
true;
2491 }
else if (always_thumb) {
2492 function_start_entry.data =
true;
2495 function_starts.Append(function_start_entry);
2501 const size_t function_starts_count = function_starts.GetSize();
2516 if (unwind_or_symbol_log)
2517 module_sp->LogMessage(
2518 unwind_or_symbol_log,
2519 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2522 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2523 ? eh_frame_section_sp->GetID()
2529 std::vector<uint32_t> N_FUN_indexes;
2530 std::vector<uint32_t> N_NSYM_indexes;
2531 std::vector<uint32_t> N_INCL_indexes;
2532 std::vector<uint32_t> N_BRAC_indexes;
2533 std::vector<uint32_t> N_COMM_indexes;
2534 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2535 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2536 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2537 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2538 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2539 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2542 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2543 uint32_t nlist_idx = 0;
2544 Symbol *symbol_ptr =
nullptr;
2546 uint32_t sym_idx = 0;
2548 size_t num_syms = 0;
2549 std::string memory_symbol_name;
2550 uint32_t unmapped_local_symbols_found = 0;
2552 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2553 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2554 std::set<lldb::addr_t> resolver_addresses;
2556 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2557 if (dyld_trie_data_size > 0) {
2558 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2562 if (text_segment_sp)
2563 text_segment_file_addr = text_segment_sp->GetFileAddress();
2565 resolver_addresses, reexport_trie_entries,
2566 external_sym_trie_entries);
2569 typedef std::set<ConstString> IndirectSymbols;
2570 IndirectSymbols indirect_symbol_names;
2593 UUID process_shared_cache_uuid;
2594 addr_t process_shared_cache_base_addr;
2598 process_shared_cache_uuid);
2601 __block
bool found_image =
false;
2602 __block
void *nlist_buffer =
nullptr;
2603 __block
unsigned nlist_count = 0;
2604 __block
char *string_table =
nullptr;
2605 __block vm_offset_t vm_nlist_memory = 0;
2606 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2607 __block vm_offset_t vm_string_memory = 0;
2608 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2610 llvm::scope_exit _(^{
2611 if (vm_nlist_memory)
2612 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2613 if (vm_string_memory)
2614 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2617 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2618 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2619 UndefinedNameToDescMap undefined_name_to_desc;
2620 SymbolIndexToName reexport_shlib_needs_fixup;
2628 if (process_shared_cache_uuid.
IsValid() &&
2629 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2638 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2645 dyld_image_local_nlist_content_4Symbolication(
2646 image, ^(
const void *nlistStart, uint64_t nlistCount,
2647 const char *stringTable) {
2648 if (!nlistStart || !nlistCount)
2656 nlist_byte_size * nlistCount, &vm_nlist_memory,
2657 &vm_nlist_bytes_read);
2660 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2665 vm_address_t string_address = (vm_address_t)stringTable;
2666 vm_size_t region_size;
2667 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2668 vm_region_basic_info_data_t info;
2669 memory_object_name_t object;
2671 ®ion_size, VM_REGION_BASIC_INFO_64,
2672 (vm_region_info_t)&info, &info_count, &
object);
2678 ((vm_address_t)stringTable - string_address),
2679 &vm_string_memory, &vm_string_bytes_read);
2683 nlist_buffer = (
void *)vm_nlist_memory;
2684 string_table = (
char *)vm_string_memory;
2685 nlist_count = nlistCount;
2691 nlist_count * nlist_byte_size,
2692 byte_order, addr_byte_size);
2693 DataExtractor dsc_string_table_data(string_table, vm_string_bytes_read,
2694 byte_order, addr_byte_size);
2695 unmapped_local_symbols_found = nlist_count;
2701 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2706 for (uint32_t nlist_index = 0;
2707 nlist_index < nlist_count;
2711 std::optional<struct nlist_64> nlist_maybe =
2712 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2716 struct nlist_64 nlist = *nlist_maybe;
2719 const char *symbol_name = NULL;
2720 std::optional<llvm::StringRef> name =
2721 dsc_string_table_data.
PeekCStr(nlist.n_strx);
2728 "DSC unmapped local symbol[{0}] has invalid or "
2729 "unterminated string table offset {1:x} in {2}, "
2731 nlist_index, nlist.n_strx,
2732 module_sp->GetFileSpec().GetPath()));
2737 symbol_name = name->data();
2739 const char *symbol_name_non_abi_mangled = NULL;
2742 bool add_nlist =
true;
2743 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2744 bool demangled_is_synthesized =
false;
2745 bool is_gsym =
false;
2746 bool set_value =
true;
2748 assert(sym_idx < num_syms);
2753 switch (nlist.n_type) {
2773 symbol_name, symbol_name_non_abi_mangled,
2775 demangled_is_synthesized =
true;
2777 if (nlist.n_value != 0)
2779 nlist.n_sect, nlist.n_value);
2795 nlist.n_sect, nlist.n_value);
2797 N_FUN_addr_to_sym_idx.insert(
2798 std::make_pair(nlist.n_value, sym_idx));
2802 N_FUN_indexes.push_back(sym_idx);
2806 if (!N_FUN_indexes.empty()) {
2813 N_FUN_indexes.pop_back();
2825 N_STSYM_addr_to_sym_idx.insert(
2826 std::make_pair(nlist.n_value, sym_idx));
2827 symbol_section = section_info.
GetSection(nlist.n_sect,
2829 if (symbol_name && symbol_name[0]) {
2837 symbol_section = section_info.
GetSection(nlist.n_sect,
2871 symbol_section = section_info.
GetSection(nlist.n_sect,
2884 if (symbol_name == NULL) {
2895 N_NSYM_indexes.clear();
2896 N_INCL_indexes.clear();
2897 N_BRAC_indexes.clear();
2898 N_COMM_indexes.clear();
2899 N_FUN_indexes.clear();
2905 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2906 if (N_SO_has_full_path) {
2907 if ((N_SO_index == sym_idx - 1) &&
2908 ((sym_idx - 1) < num_syms)) {
2914 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2920 N_SO_index = sym_idx;
2922 }
else if ((N_SO_index == sym_idx - 1) &&
2923 ((sym_idx - 1) < num_syms)) {
2928 const char *so_path = sym[sym_idx - 1]
2932 if (so_path && so_path[0]) {
2933 std::string full_so_path(so_path);
2934 const size_t double_slash_pos =
2935 full_so_path.find(
"//");
2936 if (double_slash_pos != std::string::npos) {
2947 &full_so_path[double_slash_pos + 1],
2948 FileSpec::Style::native);
2951 full_so_path.erase(0, double_slash_pos + 1);
2955 if (*full_so_path.rbegin() !=
'/')
2956 full_so_path +=
'/';
2957 full_so_path += symbol_name;
2961 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2965 N_SO_index = sym_idx;
2986 N_INCL_indexes.push_back(sym_idx);
2996 if (!N_INCL_indexes.empty()) {
3001 N_INCL_indexes.pop_back();
3036 symbol_section = section_info.
GetSection(nlist.n_sect,
3047 symbol_section = section_info.
GetSection(nlist.n_sect,
3049 N_BRAC_indexes.push_back(sym_idx);
3059 symbol_section = section_info.
GetSection(nlist.n_sect,
3061 if (!N_BRAC_indexes.empty()) {
3066 N_BRAC_indexes.pop_back();
3083 N_COMM_indexes.push_back(sym_idx);
3088 symbol_section = section_info.
GetSection(nlist.n_sect,
3099 if (!N_COMM_indexes.empty()) {
3104 N_COMM_indexes.pop_back();
3119 uint8_t n_type = N_TYPE & nlist.n_type;
3120 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3124 std::optional<llvm::StringRef> reexport_name_str =
3125 strtab_data.PeekCStr(nlist.n_value);
3126 if (reexport_name_str && !reexport_name_str->empty()) {
3129 reexport_name_str->drop_front(
3130 reexport_name_str->front() ==
'_' ? 1 : 0));
3133 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3135 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3141 if (symbol_name && symbol_name[0]) {
3143 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3144 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3156 symbol_section = section_info.
GetSection(nlist.n_sect,
3159 if (symbol_section == NULL) {
3165 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3168 uint32_t section_type =
3169 symbol_section->Get() & SECTION_TYPE;
3171 switch (section_type) {
3172 case S_CSTRING_LITERALS:
3175 case S_4BYTE_LITERALS:
3178 case S_8BYTE_LITERALS:
3181 case S_LITERAL_POINTERS:
3184 case S_NON_LAZY_SYMBOL_POINTERS:
3188 case S_LAZY_SYMBOL_POINTERS:
3191 case S_SYMBOL_STUBS:
3195 case S_MOD_INIT_FUNC_POINTERS:
3199 case S_MOD_TERM_FUNC_POINTERS:
3207 case S_16BYTE_LITERALS:
3213 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3217 switch (symbol_section->GetType()) {
3244 llvm::StringRef symbol_sect_name =
3245 symbol_section->GetName();
3246 if (symbol_section->IsDescendant(
3247 text_section_sp.get())) {
3248 if (symbol_section->IsClear(
3249 S_ATTR_PURE_INSTRUCTIONS |
3250 S_ATTR_SELF_MODIFYING_CODE |
3251 S_ATTR_SOME_INSTRUCTIONS))
3255 }
else if (symbol_section->IsDescendant(
3256 data_section_sp.get()) ||
3257 symbol_section->IsDescendant(
3258 data_dirty_section_sp.get()) ||
3259 symbol_section->IsDescendant(
3260 data_const_section_sp.get())) {
3261 if (symbol_sect_name.starts_with(
"__objc")) {
3266 symbol_name_non_abi_mangled, type))
3267 demangled_is_synthesized =
true;
3268 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
3273 }
else if (symbol_sect_name.starts_with(
"__IMPORT"))
3275 }
else if (symbol_section->IsDescendant(
3276 objc_section_sp.get())) {
3278 if (symbol_name && symbol_name[0] ==
'.') {
3279 llvm::StringRef symbol_name_ref(symbol_name);
3281 g_objc_v1_prefix_class(
".objc_class_name_");
3282 if (symbol_name_ref.starts_with(
3283 g_objc_v1_prefix_class)) {
3284 symbol_name_non_abi_mangled = symbol_name;
3285 symbol_name = symbol_name +
3286 g_objc_v1_prefix_class.size();
3288 demangled_is_synthesized =
true;
3299 uint64_t symbol_value = nlist.n_value;
3300 if (symbol_name_non_abi_mangled) {
3306 if (symbol_name && symbol_name[0] ==
'_') {
3313 if (is_gsym && is_debug) {
3314 const char *gsym_name =
3320 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3324 if (symbol_section) {
3325 const addr_t section_file_addr =
3326 symbol_section->GetFileAddress();
3327 symbol_value -= section_file_addr;
3330 if (is_debug ==
false) {
3338 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3339 if (range.first != range.second) {
3340 bool found_it =
false;
3341 for (
auto pos = range.first; pos != range.second;
3343 if (sym[sym_idx].GetMangled().
GetName(
3347 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3353 sym[sym_idx].IsExternal());
3354 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3356 if (resolver_addresses.find(nlist.n_value) !=
3357 resolver_addresses.end())
3359 sym[sym_idx].
Clear();
3367 if (resolver_addresses.find(nlist.n_value) !=
3368 resolver_addresses.end())
3380 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3382 if (range.first != range.second) {
3383 bool found_it =
false;
3384 for (
auto pos = range.first; pos != range.second;
3386 if (sym[sym_idx].GetMangled().
GetName(
3390 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3396 sym[sym_idx].IsExternal());
3397 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3399 sym[sym_idx].
Clear();
3407 const char *gsym_name =
3415 ConstNameToSymbolIndexMap::const_iterator pos =
3416 N_GSYM_name_to_sym_idx.find(gsym_name);
3417 if (pos != N_GSYM_name_to_sym_idx.end()) {
3418 const uint32_t GSYM_sym_idx = pos->second;
3419 m_nlist_idx_to_sym_idx[nlist_idx] =
3425 Address(symbol_section, symbol_value);
3426 add_symbol_addr(sym[GSYM_sym_idx]
3433 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3435 sym[sym_idx].
Clear();
3443 sym[sym_idx].
SetID(nlist_idx);
3447 Address(symbol_section, symbol_value);
3449 sym[sym_idx].GetAddress().GetFileAddress());
3451 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3453 if (demangled_is_synthesized)
3457 sym[sym_idx].
Clear();
3464 for (
const auto &pos : reexport_shlib_needs_fixup) {
3465 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3466 if (undef_pos != undefined_name_to_desc.end()) {
3467 const uint8_t dylib_ordinal =
3468 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3469 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3479 if (nlist_data.GetByteSize() > 0) {
3481 const uint64_t max_nsyms = nlist_data.GetByteSize() / nlist_byte_size;
3482 const uint64_t max_nindirectsyms =
3483 indirect_symbol_index_data.GetByteSize() /
sizeof(uint32_t);
3487 if (sym ==
nullptr) {
3488 sym = symtab.Resize(
3489 std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms) +
3490 std::min<uint64_t>(m_dysymtab.nindirectsyms, max_nindirectsyms));
3491 num_syms = symtab.GetNumSymbols();
3494 if (unmapped_local_symbols_found) {
3495 assert(m_dysymtab.ilocalsym == 0);
3496 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3497 nlist_idx = m_dysymtab.nlocalsym;
3502 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3503 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3504 UndefinedNameToDescMap undefined_name_to_desc;
3505 SymbolIndexToName reexport_shlib_needs_fixup;
3513 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3515 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3516 if (is_debug != debug_only)
3519 const char *symbol_name_non_abi_mangled =
nullptr;
3520 const char *symbol_name =
nullptr;
3522 if (have_strtab_data) {
3523 std::optional<llvm::StringRef> name =
3524 strtab_data.PeekCStr(nlist.n_strx);
3530 "symbol[{0}] has invalid or unterminated string table offset "
3531 "{1:x} in {2}, ignoring symbol",
3532 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3537 symbol_name = name->data();
3539 const addr_t str_addr = strtab_addr + nlist.n_strx;
3541 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3543 symbol_name = memory_symbol_name.c_str();
3548 bool add_nlist =
true;
3549 bool is_gsym =
false;
3550 bool demangled_is_synthesized =
false;
3551 bool set_value =
true;
3553 assert(sym_idx < num_syms);
3554 sym[sym_idx].SetDebug(is_debug);
3557 switch (nlist.n_type) {
3572 sym[sym_idx].SetExternal(
true);
3575 symbol_name_non_abi_mangled, type)) {
3576 demangled_is_synthesized =
true;
3578 if (nlist.n_value != 0)
3580 section_info.GetSection(nlist.n_sect, nlist.n_value);
3596 section_info.GetSection(nlist.n_sect, nlist.n_value);
3598 N_FUN_addr_to_sym_idx.insert(
3599 std::make_pair(nlist.n_value, sym_idx));
3603 N_FUN_indexes.push_back(sym_idx);
3607 if (!N_FUN_indexes.empty()) {
3610 symtab.SymbolAtIndex(N_FUN_indexes.back())
3611 ->SetByteSize(nlist.n_value);
3612 N_FUN_indexes.pop_back();
3623 N_STSYM_addr_to_sym_idx.insert(
3624 std::make_pair(nlist.n_value, sym_idx));
3625 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3626 if (symbol_name && symbol_name[0]) {
3634 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3665 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3677 if (symbol_name ==
nullptr) {
3684 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3685 symbol_ptr->SetByteSize(sym_idx);
3686 symbol_ptr->SetSizeIsSibling(
true);
3688 N_NSYM_indexes.clear();
3689 N_INCL_indexes.clear();
3690 N_BRAC_indexes.clear();
3691 N_COMM_indexes.clear();
3692 N_FUN_indexes.clear();
3698 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3699 if (N_SO_has_full_path) {
3700 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3703 sym[sym_idx - 1].GetMangled().SetValue(
3705 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3710 N_SO_index = sym_idx;
3712 }
else if ((N_SO_index == sym_idx - 1) &&
3713 ((sym_idx - 1) < num_syms)) {
3717 llvm::StringRef so_path = sym[sym_idx - 1]
3721 if (!so_path.empty()) {
3722 std::string full_so_path(so_path);
3723 const size_t double_slash_pos = full_so_path.find(
"//");
3724 if (double_slash_pos != std::string::npos) {
3732 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3733 FileSpec::Style::native);
3736 full_so_path.erase(0, double_slash_pos + 1);
3740 if (*full_so_path.rbegin() !=
'/')
3741 full_so_path +=
'/';
3742 full_so_path += symbol_name;
3743 sym[sym_idx - 1].GetMangled().SetValue(
3746 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3750 N_SO_index = sym_idx;
3770 N_INCL_indexes.push_back(sym_idx);
3779 if (!N_INCL_indexes.empty()) {
3780 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3781 symbol_ptr->SetByteSize(sym_idx + 1);
3782 symbol_ptr->SetSizeIsSibling(
true);
3783 N_INCL_indexes.pop_back();
3818 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3827 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3828 N_BRAC_indexes.push_back(sym_idx);
3837 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3838 if (!N_BRAC_indexes.empty()) {
3839 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3840 symbol_ptr->SetByteSize(sym_idx + 1);
3841 symbol_ptr->SetSizeIsSibling(
true);
3842 N_BRAC_indexes.pop_back();
3858 N_COMM_indexes.push_back(sym_idx);
3863 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3872 if (!N_COMM_indexes.empty()) {
3873 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3874 symbol_ptr->SetByteSize(sym_idx + 1);
3875 symbol_ptr->SetSizeIsSibling(
true);
3876 N_COMM_indexes.pop_back();
3890 uint8_t n_type = N_TYPE & nlist.n_type;
3891 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3895 std::optional<llvm::StringRef> reexport_name_str =
3896 strtab_data.PeekCStr(nlist.n_value);
3897 if (reexport_name_str && !reexport_name_str->empty() && symbol_name) {
3899 ConstString reexport_name(reexport_name_str->drop_front(
3900 reexport_name_str->front() ==
'_' ? 1 : 0));
3901 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3903 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3904 indirect_symbol_names.insert(
3905 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3911 if (symbol_name && symbol_name[0]) {
3913 ((symbol_name[0] ==
'_') ? 1 : 0));
3914 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3927 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3929 if (!symbol_section) {
3935 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3938 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3940 switch (section_type) {
3941 case S_CSTRING_LITERALS:
3944 case S_4BYTE_LITERALS:
3947 case S_8BYTE_LITERALS:
3950 case S_LITERAL_POINTERS:
3953 case S_NON_LAZY_SYMBOL_POINTERS:
3956 case S_LAZY_SYMBOL_POINTERS:
3959 case S_SYMBOL_STUBS:
3963 case S_MOD_INIT_FUNC_POINTERS:
3966 case S_MOD_TERM_FUNC_POINTERS:
3973 case S_16BYTE_LITERALS:
3979 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3983 switch (symbol_section->GetType()) {
4005 llvm::StringRef symbol_sect_name = symbol_section->GetName();
4006 if (symbol_section->IsDescendant(text_section_sp.get())) {
4007 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4008 S_ATTR_SELF_MODIFYING_CODE |
4009 S_ATTR_SOME_INSTRUCTIONS))
4013 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4014 symbol_section->IsDescendant(
4015 data_dirty_section_sp.get()) ||
4016 symbol_section->IsDescendant(
4017 data_const_section_sp.get())) {
4018 if (symbol_sect_name.starts_with(
"__objc")) {
4022 symbol_name, symbol_name_non_abi_mangled, type))
4023 demangled_is_synthesized =
true;
4024 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
4029 }
else if (symbol_sect_name.starts_with(
"__IMPORT")) {
4031 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4033 if (symbol_name && symbol_name[0] ==
'.') {
4034 llvm::StringRef symbol_name_ref(symbol_name);
4035 llvm::StringRef g_objc_v1_prefix_class(
4036 ".objc_class_name_");
4037 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4038 symbol_name_non_abi_mangled = symbol_name;
4039 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4041 demangled_is_synthesized =
true;
4052 sym[sym_idx].Clear();
4056 uint64_t symbol_value = nlist.n_value;
4058 if (symbol_name_non_abi_mangled) {
4059 sym[sym_idx].GetMangled().SetMangledName(
4061 sym[sym_idx].GetMangled().SetDemangledName(
ConstString(symbol_name));
4064 if (symbol_name && symbol_name[0] ==
'_') {
4070 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4075 const char *gsym_name = sym[sym_idx]
4080 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4083 if (symbol_section) {
4084 const addr_t section_file_addr = symbol_section->GetFileAddress();
4085 symbol_value -= section_file_addr;
4094 std::pair<ValueToSymbolIndexMap::const_iterator,
4095 ValueToSymbolIndexMap::const_iterator>
4097 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4098 if (range.first != range.second) {
4099 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4100 pos != range.second; ++pos) {
4102 sym[pos->second].GetMangled().GetName(
4104 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4108 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4109 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4110 if (resolver_addresses.find(nlist.n_value) !=
4111 resolver_addresses.end())
4113 sym[sym_idx].Clear();
4118 if (resolver_addresses.find(nlist.n_value) !=
4119 resolver_addresses.end())
4129 std::pair<ValueToSymbolIndexMap::const_iterator,
4130 ValueToSymbolIndexMap::const_iterator>
4132 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4133 if (range.first != range.second) {
4134 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4135 pos != range.second; ++pos) {
4137 sym[pos->second].GetMangled().GetName(
4139 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4143 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4144 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4145 sym[sym_idx].Clear();
4151 const char *gsym_name = sym[sym_idx]
4156 ConstNameToSymbolIndexMap::const_iterator pos =
4157 N_GSYM_name_to_sym_idx.find(gsym_name);
4158 if (pos != N_GSYM_name_to_sym_idx.end()) {
4159 const uint32_t GSYM_sym_idx = pos->second;
4160 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4163 sym[GSYM_sym_idx].GetAddressRef() =
4164 Address(symbol_section, symbol_value);
4166 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4170 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4171 sym[sym_idx].Clear();
4179 sym[sym_idx].SetID(nlist_idx);
4180 sym[sym_idx].SetType(type);
4182 sym[sym_idx].GetAddressRef() =
Address(symbol_section, symbol_value);
4184 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4186 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4187 if (nlist.n_desc & N_WEAK_REF)
4188 sym[sym_idx].SetIsWeak(
true);
4190 if (demangled_is_synthesized)
4191 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4199 std::vector<struct nlist_64> nlists;
4200 nlists.reserve(std::min<uint64_t>(symtab_load_command.nsyms, max_nsyms));
4201 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4203 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4204 nlists.push_back(*nlist);
4214 for (
auto &nlist : nlists) {
4215 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4221 for (
auto &nlist : nlists) {
4226 for (
const auto &pos : reexport_shlib_needs_fixup) {
4227 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4228 if (undef_pos != undefined_name_to_desc.end()) {
4229 const uint8_t dylib_ordinal =
4230 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4231 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4232 sym[pos.first].SetReExportedSymbolSharedLibrary(
4233 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4239 int trie_symbol_table_augment_count = 0;
4240 for (
auto &e : external_sym_trie_entries) {
4241 if (!symbols_added.contains(e.entry.address))
4242 trie_symbol_table_augment_count++;
4245 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4246 num_syms = sym_idx + trie_symbol_table_augment_count;
4247 sym = symtab.Resize(num_syms);
4249 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4252 for (
auto &e : external_sym_trie_entries) {
4253 if (symbols_added.contains(e.entry.address))
4259 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4261 const char *symbol_name = e.entry.name.GetCString();
4262 bool demangled_is_synthesized =
false;
4264 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4265 data_section_sp, data_dirty_section_sp,
4266 data_const_section_sp, symbol_section);
4268 sym[sym_idx].SetType(type);
4269 if (symbol_section) {
4270 sym[sym_idx].SetID(synthetic_sym_id++);
4271 sym[sym_idx].GetMangled().SetMangledName(
ConstString(symbol_name));
4272 if (demangled_is_synthesized)
4273 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4274 sym[sym_idx].SetIsSynthetic(
true);
4275 sym[sym_idx].SetExternal(
true);
4276 sym[sym_idx].GetAddressRef() = symbol_addr;
4285 if (function_starts_count > 0) {
4286 uint32_t num_synthetic_function_symbols = 0;
4287 for (i = 0; i < function_starts_count; ++i) {
4288 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4289 ++num_synthetic_function_symbols;
4292 if (num_synthetic_function_symbols > 0) {
4293 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4294 num_syms = sym_idx + num_synthetic_function_symbols;
4295 sym = symtab.Resize(num_syms);
4297 for (i = 0; i < function_starts_count; ++i) {
4298 const FunctionStarts::Entry *func_start_entry =
4299 function_starts.GetEntryAtIndex(i);
4300 if (!symbols_added.contains(func_start_entry->addr)) {
4301 addr_t symbol_file_addr = func_start_entry->addr;
4302 uint32_t symbol_flags = 0;
4303 if (func_start_entry->data)
4306 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4308 if (symbol_section) {
4309 sym[sym_idx].SetID(synthetic_sym_id++);
4313 sym[sym_idx].GetMangled().SetDemangledName(
ConstString());
4315 sym[sym_idx].SetIsSynthetic(
true);
4316 sym[sym_idx].GetAddressRef() = symbol_addr;
4319 sym[sym_idx].SetFlags(symbol_flags);
4330 if (sym_idx < num_syms) {
4332 sym = symtab.Resize(num_syms);
4336 if (m_dysymtab.nindirectsyms != 0) {
4337 if (indirect_symbol_index_data.GetByteSize()) {
4338 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4339 m_nlist_idx_to_sym_idx.end();
4341 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4343 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4345 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4346 if (symbol_stub_byte_size == 0)
4349 const uint32_t num_symbol_stubs =
4350 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4352 if (num_symbol_stubs == 0)
4355 const uint32_t symbol_stub_index_offset =
4356 m_mach_sections[sect_idx].reserved1;
4357 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4358 const uint32_t symbol_stub_index =
4359 symbol_stub_index_offset + stub_idx;
4361 m_mach_sections[sect_idx].addr +
4362 (stub_idx * symbol_stub_byte_size);
4364 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4365 symbol_stub_offset, 4)) {
4366 const uint32_t stub_sym_id =
4367 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4368 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4371 NListIndexToSymbolIndexMap::const_iterator index_pos =
4372 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4373 Symbol *stub_symbol =
nullptr;
4374 if (index_pos != end_index_pos) {
4377 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4381 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4385 Address so_addr(symbol_stub_addr, section_list);
4392 if (resolver_addresses.find(symbol_stub_addr) ==
4393 resolver_addresses.end())
4403 if (sym_idx >= num_syms) {
4404 sym = symtab.Resize(++num_syms);
4405 stub_symbol =
nullptr;
4407 sym[sym_idx].SetID(synthetic_sym_id++);
4408 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4409 if (resolver_addresses.find(symbol_stub_addr) ==
4410 resolver_addresses.end())
4414 sym[sym_idx].SetIsSynthetic(
true);
4415 sym[sym_idx].GetAddressRef() = so_addr;
4416 add_symbol_addr(so_addr.GetFileAddress());
4417 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4422 "warning: symbol stub referencing symbol table "
4423 "symbol %u that isn't in our minimal symbol table, "
4434 if (!reexport_trie_entries.empty()) {
4435 for (
const auto &e : reexport_trie_entries) {
4436 if (e.entry.import_name) {
4439 if (indirect_symbol_names.find(e.entry.name) ==
4440 indirect_symbol_names.end()) {
4442 if (sym_idx >= num_syms)
4443 sym = symtab.Resize(++num_syms);
4444 sym[sym_idx].SetID(synthetic_sym_id++);
4445 sym[sym_idx].GetMangled() =
Mangled(e.entry.name);
4447 sym[sym_idx].SetIsSynthetic(
true);
4448 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4449 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4450 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4451 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
6282 Target &target = process_sp->GetTarget();
6284 const llvm::Triple &target_triple = target_arch.
GetTriple();
6285 if (target_triple.getVendor() == llvm::Triple::Apple &&
6286 (target_triple.getOS() == llvm::Triple::MacOSX ||
6287 target_triple.getOS() == llvm::Triple::IOS ||
6288 target_triple.getOS() == llvm::Triple::WatchOS ||
6289 target_triple.getOS() == llvm::Triple::TvOS ||
6290 target_triple.getOS() == llvm::Triple::BridgeOS ||
6291 target_triple.getOS() == llvm::Triple::XROS)) {
6292 bool make_core =
false;
6294 case llvm::Triple::aarch64:
6295 case llvm::Triple::aarch64_32:
6296 case llvm::Triple::arm:
6297 case llvm::Triple::thumb:
6298 case llvm::Triple::x86:
6299 case llvm::Triple::x86_64:
6304 "unsupported core architecture: %s", target_triple.str().c_str());
6310 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6311 if (
error.Success()) {
6314 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6315 for (
const auto &core_range_info : core_ranges) {
6317 const auto &core_range = core_range_info.data;
6318 uint32_t cmd_type = LC_SEGMENT_64;
6319 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6320 if (addr_byte_size == 4) {
6321 cmd_type = LC_SEGMENT;
6322 segment_size =
sizeof(llvm::MachO::segment_command);
6326 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6328 uint32_t vm_prot = 0;
6329 if (core_range.lldb_permissions & ePermissionsReadable)
6330 vm_prot |= VM_PROT_READ;
6331 if (core_range.lldb_permissions & ePermissionsWritable)
6332 vm_prot |= VM_PROT_WRITE;
6333 if (core_range.lldb_permissions & ePermissionsExecutable)
6334 vm_prot |= VM_PROT_EXECUTE;
6335 const addr_t vm_addr = core_range.range.start();
6336 const addr_t vm_size = core_range.range.size();
6337 llvm::MachO::segment_command_64 segment = {
6349 segment_load_commands.push_back(segment);
6354 llvm::MachO::mach_header_64 mach_header;
6355 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6358 mach_header.filetype = MH_CORE;
6359 mach_header.ncmds = segment_load_commands.size();
6360 mach_header.flags = 0;
6361 mach_header.reserved = 0;
6362 ThreadList &thread_list = process_sp->GetThreadList();
6363 const uint32_t num_threads = thread_list.
GetSize();
6369 std::vector<StreamString> LC_THREAD_datas(num_threads);
6370 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6372 LC_THREAD_data.SetByteOrder(byte_order);
6374 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6377 switch (mach_header.cputype) {
6378 case llvm::MachO::CPU_TYPE_ARM64:
6379 case llvm::MachO::CPU_TYPE_ARM64_32:
6381 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6384 case llvm::MachO::CPU_TYPE_ARM:
6386 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6389 case llvm::MachO::CPU_TYPE_X86_64:
6391 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6394 case llvm::MachO::CPU_TYPE_RISCV:
6396 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6403 if (addr_byte_size == 8) {
6404 mach_header.sizeofcmds = segment_load_commands.size() *
6405 sizeof(llvm::MachO::segment_command_64);
6407 mach_header.sizeofcmds = segment_load_commands.size() *
6408 sizeof(llvm::MachO::segment_command);
6412 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6413 ++mach_header.ncmds;
6414 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6419 uint64_t address_mask = process_sp->GetCodeAddressMask();
6422 mach_header.ncmds++;
6423 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6427 mach_header.ncmds++;
6428 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6431 mach_header.ncmds++;
6432 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6435 buffer.
PutHex32(mach_header.magic);
6436 buffer.
PutHex32(mach_header.cputype);
6437 buffer.
PutHex32(mach_header.cpusubtype);
6438 buffer.
PutHex32(mach_header.filetype);
6439 buffer.
PutHex32(mach_header.ncmds);
6440 buffer.
PutHex32(mach_header.sizeofcmds);
6441 buffer.
PutHex32(mach_header.flags);
6442 if (addr_byte_size == 8) {
6443 buffer.
PutHex32(mach_header.reserved);
6448 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6450 file_offset = llvm::alignTo(file_offset, 16);
6451 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6455 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6457 addrable_bits_lcnote_up->name =
"addrable bits";
6458 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6459 int bits = std::bitset<64>(~address_mask).count();
6460 addrable_bits_lcnote_up->payload.PutHex32(4);
6461 addrable_bits_lcnote_up->payload.PutHex32(
6463 addrable_bits_lcnote_up->payload.PutHex32(
6465 addrable_bits_lcnote_up->payload.PutHex32(0);
6467 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6469 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6473 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6475 thread_extrainfo_lcnote_up->name =
"process metadata";
6476 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6479 std::make_shared<StructuredData::Dictionary>());
6481 std::make_shared<StructuredData::Array>());
6483 process_sp->CalculateCoreFileThreadList(options)) {
6485 std::make_shared<StructuredData::Dictionary>());
6486 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6487 threads->AddItem(thread);
6489 dict->AddItem(
"threads", threads);
6491 dict->Dump(strm,
false);
6492 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.
GetData(),
6495 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6496 file_offset = llvm::alignTo(file_offset, 16);
6497 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6500 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6502 all_image_infos_lcnote_up->name =
"all image infos";
6503 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6505 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6507 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6510 for (
auto &lcnote : lc_notes) {
6513 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6515 memset(namebuf, 0,
sizeof(namebuf));
6521 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6523 buffer.
PutHex64(lcnote->payload_file_offset);
6524 buffer.
PutHex64(lcnote->payload.GetSize());
6528 file_offset = llvm::alignTo(file_offset, 4096);
6530 for (
auto &segment : segment_load_commands) {
6531 segment.fileoff = file_offset;
6532 file_offset += segment.filesize;
6536 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6537 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6539 buffer.
PutHex32(8 + LC_THREAD_data_size);
6540 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6544 for (
const auto &segment : segment_load_commands) {
6547 buffer.
PutRawBytes(segment.segname,
sizeof(segment.segname));
6548 if (addr_byte_size == 8) {
6554 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmaddr));
6555 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmsize));
6556 buffer.
PutHex32(
static_cast<uint32_t
>(segment.fileoff));
6557 buffer.
PutHex32(
static_cast<uint32_t
>(segment.filesize));
6565 std::string core_file_path(outfile.
GetPath());
6573 uint8_t bytes[0x1000];
6575 size_t bytes_written = buffer.
GetString().size();
6577 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6578 if (
error.Success()) {
6580 for (
auto &lcnote : lc_notes) {
6581 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6584 "Unable to seek to corefile pos "
6585 "to write '%s' LC_NOTE payload",
6586 lcnote->name.c_str());
6589 bytes_written = lcnote->payload.GetSize();
6590 error = core_file.get()->Write(lcnote->payload.GetData(),
6592 if (!
error.Success())
6597 for (
const auto &segment : segment_load_commands) {
6598 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6600 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6601 segment.fileoff, core_file_path.c_str());
6607 " bytes of data for memory region at 0x%" PRIx64
"\n",
6608 segment.vmsize, segment.vmaddr);
6609 addr_t bytes_left = segment.vmsize;
6610 addr_t addr = segment.vmaddr;
6612 while (bytes_left > 0 &&
error.Success()) {
6613 const size_t bytes_to_read =
6614 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6619 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6622 if (bytes_read == bytes_to_read) {
6623 size_t bytes_written = bytes_read;
6624 error = core_file.get()->Write(bytes, bytes_written);
6625 bytes_left -= bytes_read;
6630 memset(bytes, 0, bytes_to_read);
6631 size_t bytes_written = bytes_to_read;
6632 error = core_file.get()->Write(bytes, bytes_written);
6633 bytes_left -= bytes_to_read;
6634 addr += bytes_to_read;