2100 llvm::StringRef file_name = file.
GetFilename().nonEmptyOr(
"<Unknown>");
2102 file_name.str().c_str());
2103 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2104 Progress progress(
"Parsing symbol table", file_name.str());
2119 llvm::DenseSet<addr_t> symbols_added;
2123 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2127 symbols_added.insert(file_addr);
2129 FunctionStarts function_starts;
2135 for (i = 0; i <
m_header.ncmds; ++i) {
2138 llvm::MachO::load_command lc;
2144 llvm::MachO::symtab_command lc_obj;
2145 if (
m_data_nsp->GetU32(&offset, &lc_obj.symoff, 4)) {
2146 lc_obj.cmd = lc.cmd;
2147 lc_obj.cmdsize = lc.cmdsize;
2148 symtab_load_command = lc_obj;
2153 case LC_DYLD_INFO_ONLY: {
2154 llvm::MachO::dyld_info_command lc_obj;
2155 if (
m_data_nsp->GetU32(&offset, &lc_obj.rebase_off, 10)) {
2156 lc_obj.cmd = lc.cmd;
2157 lc_obj.cmdsize = lc.cmdsize;
2163 case LC_LOAD_WEAK_DYLIB:
2164 case LC_REEXPORT_DYLIB:
2166 case LC_LOAD_UPWARD_DYLIB: {
2167 uint32_t name_offset = cmd_offset +
m_data_nsp->GetU32(&offset);
2168 const char *path =
m_data_nsp->PeekCStr(name_offset);
2176 if (lc.cmd == LC_REEXPORT_DYLIB) {
2180 dylib_files.
Append(file_spec);
2184 case LC_DYLD_EXPORTS_TRIE: {
2185 llvm::MachO::linkedit_data_command lc_obj;
2186 lc_obj.cmd = lc.cmd;
2187 lc_obj.cmdsize = lc.cmdsize;
2188 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2189 exports_trie_load_command = lc_obj;
2191 case LC_FUNCTION_STARTS: {
2192 llvm::MachO::linkedit_data_command lc_obj;
2193 lc_obj.cmd = lc.cmd;
2194 lc_obj.cmdsize = lc.cmdsize;
2195 if (
m_data_nsp->GetU32(&offset, &lc_obj.dataoff, 2))
2196 function_starts_load_command = lc_obj;
2200 const uint8_t *uuid_bytes =
m_data_nsp->PeekData(offset, 16);
2203 image_uuid =
UUID(uuid_bytes, 16);
2210 offset = cmd_offset + lc.cmdsize;
2213 if (!symtab_load_command.
cmd)
2217 if (section_list ==
nullptr)
2220 const uint32_t addr_byte_size =
m_data_nsp->GetAddressByteSize();
2222 bool bit_width_32 = addr_byte_size == 4;
2223 const size_t nlist_byte_size =
2224 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2226 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2227 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2228 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2229 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2231 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2233 const
addr_t nlist_data_byte_size =
2234 symtab_load_command.nsyms * nlist_byte_size;
2235 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2238 ProcessSP process_sp(m_process_wp.lock());
2239 Process *process = process_sp.get();
2243 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2253 section_list->FindSectionByName(g_segment_name_TEXT));
2255 section_list->FindSectionByName(g_segment_name_DATA));
2257 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2259 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2261 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2263 section_list->FindSectionByName(g_segment_name_OBJC));
2266 if (text_section_sp.get()) {
2267 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2268 g_section_name_eh_frame);
2269 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(
2270 g_section_name_lldb_no_nlist);
2272 eh_frame_section_sp =
2274 lldb_no_nlist_section_sp =
2278 if (process &&
m_header.filetype != llvm::MachO::MH_OBJECT &&
2279 !is_local_shared_cache_image) {
2280 Target &target = process->GetTarget();
2289 if (lldb_no_nlist_section_sp)
2294 if (linkedit_section_sp) {
2295 addr_t linkedit_load_addr =
2296 linkedit_section_sp->GetLoadBaseAddress(&target);
2306 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2307 const addr_t symoff_addr = linkedit_load_addr +
2308 symtab_load_command.
symoff -
2309 linkedit_file_offset;
2310 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2311 linkedit_file_offset;
2319 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2321 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2323 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2325 const addr_t indirect_syms_addr = linkedit_load_addr +
2327 linkedit_file_offset;
2329 process_sp, indirect_syms_addr, dysymtab.
nindirectsyms * 4));
2330 if (indirect_syms_data_sp)
2331 indirect_symbol_index_data.SetData(
2332 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2342 if (!is_shared_cache_image) {
2344 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2345 if (strtab_data_sp) {
2346 strtab_data.SetData(strtab_data_sp, 0,
2347 strtab_data_sp->GetByteSize());
2352 if (function_starts_load_command.
cmd) {
2353 const addr_t func_start_addr =
2354 linkedit_load_addr + function_starts_load_command.
dataoff -
2355 linkedit_file_offset;
2358 function_starts_load_command.
datasize));
2359 if (func_start_data_sp)
2360 function_starts_data.SetData(func_start_data_sp, 0,
2361 func_start_data_sp->GetByteSize());
2367 if (is_local_shared_cache_image && linkedit_section_sp) {
2375 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2378 symtab_load_command.
symoff += linkedit_slide;
2379 symtab_load_command.
stroff += linkedit_slide;
2382 function_starts_load_command.
dataoff += linkedit_slide;
2383 exports_trie_load_command.
dataoff += linkedit_slide;
2387 nlist_data_byte_size);
2388 strtab_data = *
m_data_nsp->GetSubsetExtractorSP(symtab_load_command.
stroff,
2389 strtab_data_byte_size);
2394 && (exports_trie_load_command.
datasize > 0)));
2398 }
else if (exports_trie_load_command.
datasize > 0) {
2401 exports_trie_load_command.
datasize);
2405 indirect_symbol_index_data = *
m_data_nsp->GetSubsetExtractorSP(
2408 if (function_starts_load_command.
cmd) {
2409 function_starts_data = *
m_data_nsp->GetSubsetExtractorSP(
2410 function_starts_load_command.
dataoff,
2411 function_starts_load_command.
datasize);
2415 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2417 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2434 if (text_section_sp && function_starts_data.GetByteSize()) {
2435 FunctionStarts::Entry function_start_entry;
2436 function_start_entry.data =
false;
2438 function_start_entry.addr = text_section_sp->GetFileAddress();
2440 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2443 function_start_entry.addr += delta;
2445 if (function_start_entry.addr & 1) {
2447 function_start_entry.data =
true;
2448 }
else if (always_thumb) {
2449 function_start_entry.data =
true;
2452 function_starts.Append(function_start_entry);
2460 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2466 addr_t text_base_addr = text_section_sp->GetFileAddress();
2467 size_t count = functions.
GetSize();
2468 for (
size_t i = 0; i < count; ++i) {
2472 FunctionStarts::Entry function_start_entry;
2473 function_start_entry.addr = func->
base - text_base_addr;
2475 if (function_start_entry.addr & 1) {
2477 function_start_entry.data =
true;
2478 }
else if (always_thumb) {
2479 function_start_entry.data =
true;
2482 function_starts.Append(function_start_entry);
2488 const size_t function_starts_count = function_starts.GetSize();
2503 if (unwind_or_symbol_log)
2504 module_sp->LogMessage(
2505 unwind_or_symbol_log,
2506 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2509 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2510 ? eh_frame_section_sp->GetID()
2516 std::vector<uint32_t> N_FUN_indexes;
2517 std::vector<uint32_t> N_NSYM_indexes;
2518 std::vector<uint32_t> N_INCL_indexes;
2519 std::vector<uint32_t> N_BRAC_indexes;
2520 std::vector<uint32_t> N_COMM_indexes;
2521 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2522 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2523 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2524 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2525 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2526 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2529 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2530 uint32_t nlist_idx = 0;
2531 Symbol *symbol_ptr =
nullptr;
2533 uint32_t sym_idx = 0;
2535 size_t num_syms = 0;
2536 std::string memory_symbol_name;
2537 uint32_t unmapped_local_symbols_found = 0;
2539 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2540 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2541 std::set<lldb::addr_t> resolver_addresses;
2543 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2544 if (dyld_trie_data_size > 0) {
2545 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2549 if (text_segment_sp)
2550 text_segment_file_addr = text_segment_sp->GetFileAddress();
2552 resolver_addresses, reexport_trie_entries,
2553 external_sym_trie_entries);
2556 typedef std::set<ConstString> IndirectSymbols;
2557 IndirectSymbols indirect_symbol_names;
2580 UUID process_shared_cache_uuid;
2581 addr_t process_shared_cache_base_addr;
2585 process_shared_cache_uuid);
2588 __block
bool found_image =
false;
2589 __block
void *nlist_buffer =
nullptr;
2590 __block
unsigned nlist_count = 0;
2591 __block
char *string_table =
nullptr;
2592 __block vm_offset_t vm_nlist_memory = 0;
2593 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2594 __block vm_offset_t vm_string_memory = 0;
2595 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2597 llvm::scope_exit _(^{
2598 if (vm_nlist_memory)
2599 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2600 if (vm_string_memory)
2601 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2604 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2605 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2606 UndefinedNameToDescMap undefined_name_to_desc;
2607 SymbolIndexToName reexport_shlib_needs_fixup;
2615 if (process_shared_cache_uuid.
IsValid() &&
2616 process_shared_cache_uuid !=
UUID(&cache_uuid, 16))
2625 if (image_uuid !=
UUID(dsc_image_uuid, 16))
2632 dyld_image_local_nlist_content_4Symbolication(
2633 image, ^(
const void *nlistStart, uint64_t nlistCount,
2634 const char *stringTable) {
2635 if (!nlistStart || !nlistCount)
2643 nlist_byte_size * nlistCount, &vm_nlist_memory,
2644 &vm_nlist_bytes_read);
2647 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2652 vm_address_t string_address = (vm_address_t)stringTable;
2653 vm_size_t region_size;
2654 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2655 vm_region_basic_info_data_t info;
2656 memory_object_name_t object;
2658 ®ion_size, VM_REGION_BASIC_INFO_64,
2659 (vm_region_info_t)&info, &info_count, &
object);
2665 ((vm_address_t)stringTable - string_address),
2666 &vm_string_memory, &vm_string_bytes_read);
2670 nlist_buffer = (
void *)vm_nlist_memory;
2671 string_table = (
char *)vm_string_memory;
2672 nlist_count = nlistCount;
2678 nlist_count * nlist_byte_size,
2679 byte_order, addr_byte_size);
2680 unmapped_local_symbols_found = nlist_count;
2686 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2691 for (uint32_t nlist_index = 0;
2692 nlist_index < nlist_count;
2696 std::optional<struct nlist_64> nlist_maybe =
2697 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2701 struct nlist_64 nlist = *nlist_maybe;
2704 const char *symbol_name = string_table + nlist.n_strx;
2706 if (symbol_name == NULL) {
2711 "DSC unmapped local symbol[{0}] has invalid "
2712 "string table offset {1:x} in {2}, ignoring symbol",
2713 nlist_index, nlist.n_strx,
2714 module_sp->GetFileSpec().GetPath()));
2717 if (symbol_name[0] ==
'\0')
2720 const char *symbol_name_non_abi_mangled = NULL;
2723 bool add_nlist =
true;
2724 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2725 bool demangled_is_synthesized =
false;
2726 bool is_gsym =
false;
2727 bool set_value =
true;
2729 assert(sym_idx < num_syms);
2734 switch (nlist.n_type) {
2754 symbol_name, symbol_name_non_abi_mangled,
2756 demangled_is_synthesized =
true;
2758 if (nlist.n_value != 0)
2760 nlist.n_sect, nlist.n_value);
2776 nlist.n_sect, nlist.n_value);
2778 N_FUN_addr_to_sym_idx.insert(
2779 std::make_pair(nlist.n_value, sym_idx));
2783 N_FUN_indexes.push_back(sym_idx);
2787 if (!N_FUN_indexes.empty()) {
2794 N_FUN_indexes.pop_back();
2806 N_STSYM_addr_to_sym_idx.insert(
2807 std::make_pair(nlist.n_value, sym_idx));
2808 symbol_section = section_info.
GetSection(nlist.n_sect,
2810 if (symbol_name && symbol_name[0]) {
2818 symbol_section = section_info.
GetSection(nlist.n_sect,
2852 symbol_section = section_info.
GetSection(nlist.n_sect,
2865 if (symbol_name == NULL) {
2876 N_NSYM_indexes.clear();
2877 N_INCL_indexes.clear();
2878 N_BRAC_indexes.clear();
2879 N_COMM_indexes.clear();
2880 N_FUN_indexes.clear();
2886 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2887 if (N_SO_has_full_path) {
2888 if ((N_SO_index == sym_idx - 1) &&
2889 ((sym_idx - 1) < num_syms)) {
2895 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2901 N_SO_index = sym_idx;
2903 }
else if ((N_SO_index == sym_idx - 1) &&
2904 ((sym_idx - 1) < num_syms)) {
2909 const char *so_path = sym[sym_idx - 1]
2913 if (so_path && so_path[0]) {
2914 std::string full_so_path(so_path);
2915 const size_t double_slash_pos =
2916 full_so_path.find(
"//");
2917 if (double_slash_pos != std::string::npos) {
2928 &full_so_path[double_slash_pos + 1],
2929 FileSpec::Style::native);
2932 full_so_path.erase(0, double_slash_pos + 1);
2936 if (*full_so_path.rbegin() !=
'/')
2937 full_so_path +=
'/';
2938 full_so_path += symbol_name;
2942 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2946 N_SO_index = sym_idx;
2967 N_INCL_indexes.push_back(sym_idx);
2977 if (!N_INCL_indexes.empty()) {
2982 N_INCL_indexes.pop_back();
3017 symbol_section = section_info.
GetSection(nlist.n_sect,
3028 symbol_section = section_info.
GetSection(nlist.n_sect,
3030 N_BRAC_indexes.push_back(sym_idx);
3040 symbol_section = section_info.
GetSection(nlist.n_sect,
3042 if (!N_BRAC_indexes.empty()) {
3047 N_BRAC_indexes.pop_back();
3064 N_COMM_indexes.push_back(sym_idx);
3069 symbol_section = section_info.
GetSection(nlist.n_sect,
3080 if (!N_COMM_indexes.empty()) {
3085 N_COMM_indexes.pop_back();
3100 uint8_t n_type = N_TYPE & nlist.n_type;
3101 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3105 const char *reexport_name_cstr =
3106 strtab_data.PeekCStr(nlist.n_value);
3107 if (reexport_name_cstr && reexport_name_cstr[0]) {
3110 reexport_name_cstr +
3111 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3114 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3116 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3122 if (symbol_name && symbol_name[0]) {
3124 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3125 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3137 symbol_section = section_info.
GetSection(nlist.n_sect,
3140 if (symbol_section == NULL) {
3146 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3149 uint32_t section_type =
3150 symbol_section->Get() & SECTION_TYPE;
3152 switch (section_type) {
3153 case S_CSTRING_LITERALS:
3156 case S_4BYTE_LITERALS:
3159 case S_8BYTE_LITERALS:
3162 case S_LITERAL_POINTERS:
3165 case S_NON_LAZY_SYMBOL_POINTERS:
3169 case S_LAZY_SYMBOL_POINTERS:
3172 case S_SYMBOL_STUBS:
3176 case S_MOD_INIT_FUNC_POINTERS:
3180 case S_MOD_TERM_FUNC_POINTERS:
3188 case S_16BYTE_LITERALS:
3194 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3198 switch (symbol_section->GetType()) {
3225 llvm::StringRef symbol_sect_name =
3226 symbol_section->GetName();
3227 if (symbol_section->IsDescendant(
3228 text_section_sp.get())) {
3229 if (symbol_section->IsClear(
3230 S_ATTR_PURE_INSTRUCTIONS |
3231 S_ATTR_SELF_MODIFYING_CODE |
3232 S_ATTR_SOME_INSTRUCTIONS))
3236 }
else if (symbol_section->IsDescendant(
3237 data_section_sp.get()) ||
3238 symbol_section->IsDescendant(
3239 data_dirty_section_sp.get()) ||
3240 symbol_section->IsDescendant(
3241 data_const_section_sp.get())) {
3242 if (symbol_sect_name.starts_with(
"__objc")) {
3247 symbol_name_non_abi_mangled, type))
3248 demangled_is_synthesized =
true;
3249 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
3254 }
else if (symbol_sect_name.starts_with(
"__IMPORT"))
3256 }
else if (symbol_section->IsDescendant(
3257 objc_section_sp.get())) {
3259 if (symbol_name && symbol_name[0] ==
'.') {
3260 llvm::StringRef symbol_name_ref(symbol_name);
3262 g_objc_v1_prefix_class(
".objc_class_name_");
3263 if (symbol_name_ref.starts_with(
3264 g_objc_v1_prefix_class)) {
3265 symbol_name_non_abi_mangled = symbol_name;
3266 symbol_name = symbol_name +
3267 g_objc_v1_prefix_class.size();
3269 demangled_is_synthesized =
true;
3280 uint64_t symbol_value = nlist.n_value;
3281 if (symbol_name_non_abi_mangled) {
3287 if (symbol_name && symbol_name[0] ==
'_') {
3294 if (is_gsym && is_debug) {
3295 const char *gsym_name =
3301 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3305 if (symbol_section) {
3306 const addr_t section_file_addr =
3307 symbol_section->GetFileAddress();
3308 symbol_value -= section_file_addr;
3311 if (is_debug ==
false) {
3319 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3320 if (range.first != range.second) {
3321 bool found_it =
false;
3322 for (
auto pos = range.first; pos != range.second;
3324 if (sym[sym_idx].GetMangled().
GetName(
3328 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3334 sym[sym_idx].IsExternal());
3335 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3337 if (resolver_addresses.find(nlist.n_value) !=
3338 resolver_addresses.end())
3340 sym[sym_idx].
Clear();
3348 if (resolver_addresses.find(nlist.n_value) !=
3349 resolver_addresses.end())
3361 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3363 if (range.first != range.second) {
3364 bool found_it =
false;
3365 for (
auto pos = range.first; pos != range.second;
3367 if (sym[sym_idx].GetMangled().
GetName(
3371 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3377 sym[sym_idx].IsExternal());
3378 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3380 sym[sym_idx].
Clear();
3388 const char *gsym_name =
3396 ConstNameToSymbolIndexMap::const_iterator pos =
3397 N_GSYM_name_to_sym_idx.find(gsym_name);
3398 if (pos != N_GSYM_name_to_sym_idx.end()) {
3399 const uint32_t GSYM_sym_idx = pos->second;
3400 m_nlist_idx_to_sym_idx[nlist_idx] =
3406 Address(symbol_section, symbol_value);
3407 add_symbol_addr(sym[GSYM_sym_idx]
3414 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3416 sym[sym_idx].
Clear();
3424 sym[sym_idx].
SetID(nlist_idx);
3428 Address(symbol_section, symbol_value);
3430 sym[sym_idx].GetAddress().GetFileAddress());
3432 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3434 if (demangled_is_synthesized)
3438 sym[sym_idx].
Clear();
3445 for (
const auto &pos : reexport_shlib_needs_fixup) {
3446 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3447 if (undef_pos != undefined_name_to_desc.end()) {
3448 const uint8_t dylib_ordinal =
3449 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3450 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3460 if (nlist_data.GetByteSize() > 0) {
3464 if (sym ==
nullptr) {
3466 symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3467 num_syms = symtab.GetNumSymbols();
3470 if (unmapped_local_symbols_found) {
3471 assert(m_dysymtab.ilocalsym == 0);
3472 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3473 nlist_idx = m_dysymtab.nlocalsym;
3478 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3479 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3480 UndefinedNameToDescMap undefined_name_to_desc;
3481 SymbolIndexToName reexport_shlib_needs_fixup;
3489 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3491 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3492 if (is_debug != debug_only)
3495 const char *symbol_name_non_abi_mangled =
nullptr;
3496 const char *symbol_name =
nullptr;
3498 if (have_strtab_data) {
3499 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3501 if (symbol_name ==
nullptr) {
3505 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3507 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3510 if (symbol_name[0] ==
'\0')
3511 symbol_name =
nullptr;
3513 const addr_t str_addr = strtab_addr + nlist.n_strx;
3515 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3517 symbol_name = memory_symbol_name.c_str();
3522 bool add_nlist =
true;
3523 bool is_gsym =
false;
3524 bool demangled_is_synthesized =
false;
3525 bool set_value =
true;
3527 assert(sym_idx < num_syms);
3528 sym[sym_idx].SetDebug(is_debug);
3531 switch (nlist.n_type) {
3546 sym[sym_idx].SetExternal(
true);
3549 symbol_name_non_abi_mangled, type)) {
3550 demangled_is_synthesized =
true;
3552 if (nlist.n_value != 0)
3554 section_info.GetSection(nlist.n_sect, nlist.n_value);
3570 section_info.GetSection(nlist.n_sect, nlist.n_value);
3572 N_FUN_addr_to_sym_idx.insert(
3573 std::make_pair(nlist.n_value, sym_idx));
3577 N_FUN_indexes.push_back(sym_idx);
3581 if (!N_FUN_indexes.empty()) {
3584 symtab.SymbolAtIndex(N_FUN_indexes.back())
3585 ->SetByteSize(nlist.n_value);
3586 N_FUN_indexes.pop_back();
3597 N_STSYM_addr_to_sym_idx.insert(
3598 std::make_pair(nlist.n_value, sym_idx));
3599 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3600 if (symbol_name && symbol_name[0]) {
3608 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3639 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3651 if (symbol_name ==
nullptr) {
3658 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
3659 symbol_ptr->SetByteSize(sym_idx);
3660 symbol_ptr->SetSizeIsSibling(
true);
3662 N_NSYM_indexes.clear();
3663 N_INCL_indexes.clear();
3664 N_BRAC_indexes.clear();
3665 N_COMM_indexes.clear();
3666 N_FUN_indexes.clear();
3672 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3673 if (N_SO_has_full_path) {
3674 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3677 sym[sym_idx - 1].GetMangled().SetValue(
3679 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3684 N_SO_index = sym_idx;
3686 }
else if ((N_SO_index == sym_idx - 1) &&
3687 ((sym_idx - 1) < num_syms)) {
3691 llvm::StringRef so_path = sym[sym_idx - 1]
3695 if (!so_path.empty()) {
3696 std::string full_so_path(so_path);
3697 const size_t double_slash_pos = full_so_path.find(
"//");
3698 if (double_slash_pos != std::string::npos) {
3706 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
3707 FileSpec::Style::native);
3710 full_so_path.erase(0, double_slash_pos + 1);
3714 if (*full_so_path.rbegin() !=
'/')
3715 full_so_path +=
'/';
3716 full_so_path += symbol_name;
3717 sym[sym_idx - 1].GetMangled().SetValue(
3720 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3724 N_SO_index = sym_idx;
3744 N_INCL_indexes.push_back(sym_idx);
3753 if (!N_INCL_indexes.empty()) {
3754 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
3755 symbol_ptr->SetByteSize(sym_idx + 1);
3756 symbol_ptr->SetSizeIsSibling(
true);
3757 N_INCL_indexes.pop_back();
3792 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3801 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3802 N_BRAC_indexes.push_back(sym_idx);
3811 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3812 if (!N_BRAC_indexes.empty()) {
3813 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
3814 symbol_ptr->SetByteSize(sym_idx + 1);
3815 symbol_ptr->SetSizeIsSibling(
true);
3816 N_BRAC_indexes.pop_back();
3832 N_COMM_indexes.push_back(sym_idx);
3837 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3846 if (!N_COMM_indexes.empty()) {
3847 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
3848 symbol_ptr->SetByteSize(sym_idx + 1);
3849 symbol_ptr->SetSizeIsSibling(
true);
3850 N_COMM_indexes.pop_back();
3864 uint8_t n_type = N_TYPE & nlist.n_type;
3865 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3869 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3870 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
3873 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3874 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3876 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3877 indirect_symbol_names.insert(
3878 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3884 if (symbol_name && symbol_name[0]) {
3886 ((symbol_name[0] ==
'_') ? 1 : 0));
3887 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3900 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
3902 if (!symbol_section) {
3908 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3911 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
3913 switch (section_type) {
3914 case S_CSTRING_LITERALS:
3917 case S_4BYTE_LITERALS:
3920 case S_8BYTE_LITERALS:
3923 case S_LITERAL_POINTERS:
3926 case S_NON_LAZY_SYMBOL_POINTERS:
3929 case S_LAZY_SYMBOL_POINTERS:
3932 case S_SYMBOL_STUBS:
3936 case S_MOD_INIT_FUNC_POINTERS:
3939 case S_MOD_TERM_FUNC_POINTERS:
3946 case S_16BYTE_LITERALS:
3952 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3956 switch (symbol_section->GetType()) {
3978 llvm::StringRef symbol_sect_name = symbol_section->GetName();
3979 if (symbol_section->IsDescendant(text_section_sp.get())) {
3980 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3981 S_ATTR_SELF_MODIFYING_CODE |
3982 S_ATTR_SOME_INSTRUCTIONS))
3986 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3987 symbol_section->IsDescendant(
3988 data_dirty_section_sp.get()) ||
3989 symbol_section->IsDescendant(
3990 data_const_section_sp.get())) {
3991 if (symbol_sect_name.starts_with(
"__objc")) {
3995 symbol_name, symbol_name_non_abi_mangled, type))
3996 demangled_is_synthesized =
true;
3997 }
else if (symbol_sect_name.starts_with(
"__gcc_except_tab")) {
4002 }
else if (symbol_sect_name.starts_with(
"__IMPORT")) {
4004 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4006 if (symbol_name && symbol_name[0] ==
'.') {
4007 llvm::StringRef symbol_name_ref(symbol_name);
4008 llvm::StringRef g_objc_v1_prefix_class(
4009 ".objc_class_name_");
4010 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4011 symbol_name_non_abi_mangled = symbol_name;
4012 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4014 demangled_is_synthesized =
true;
4025 sym[sym_idx].Clear();
4029 uint64_t symbol_value = nlist.n_value;
4031 if (symbol_name_non_abi_mangled) {
4032 sym[sym_idx].GetMangled().SetMangledName(
4034 sym[sym_idx].GetMangled().SetDemangledName(
ConstString(symbol_name));
4037 if (symbol_name && symbol_name[0] ==
'_') {
4043 sym[sym_idx].GetMangled().SetValue(const_symbol_name);
4048 const char *gsym_name = sym[sym_idx]
4053 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4056 if (symbol_section) {
4057 const addr_t section_file_addr = symbol_section->GetFileAddress();
4058 symbol_value -= section_file_addr;
4067 std::pair<ValueToSymbolIndexMap::const_iterator,
4068 ValueToSymbolIndexMap::const_iterator>
4070 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4071 if (range.first != range.second) {
4072 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4073 pos != range.second; ++pos) {
4075 sym[pos->second].GetMangled().GetName(
4077 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4081 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4082 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4083 if (resolver_addresses.find(nlist.n_value) !=
4084 resolver_addresses.end())
4086 sym[sym_idx].Clear();
4091 if (resolver_addresses.find(nlist.n_value) !=
4092 resolver_addresses.end())
4102 std::pair<ValueToSymbolIndexMap::const_iterator,
4103 ValueToSymbolIndexMap::const_iterator>
4105 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4106 if (range.first != range.second) {
4107 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4108 pos != range.second; ++pos) {
4110 sym[pos->second].GetMangled().GetName(
4112 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4116 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4117 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4118 sym[sym_idx].Clear();
4124 const char *gsym_name = sym[sym_idx]
4129 ConstNameToSymbolIndexMap::const_iterator pos =
4130 N_GSYM_name_to_sym_idx.find(gsym_name);
4131 if (pos != N_GSYM_name_to_sym_idx.end()) {
4132 const uint32_t GSYM_sym_idx = pos->second;
4133 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4136 sym[GSYM_sym_idx].GetAddressRef() =
4137 Address(symbol_section, symbol_value);
4139 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4143 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4144 sym[sym_idx].Clear();
4152 sym[sym_idx].SetID(nlist_idx);
4153 sym[sym_idx].SetType(type);
4155 sym[sym_idx].GetAddressRef() =
Address(symbol_section, symbol_value);
4157 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4159 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4160 if (nlist.n_desc & N_WEAK_REF)
4161 sym[sym_idx].SetIsWeak(
true);
4163 if (demangled_is_synthesized)
4164 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4172 std::vector<struct nlist_64> nlists;
4173 nlists.reserve(symtab_load_command.nsyms);
4174 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4176 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4177 nlists.push_back(*nlist);
4187 for (
auto &nlist : nlists) {
4188 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4194 for (
auto &nlist : nlists) {
4199 for (
const auto &pos : reexport_shlib_needs_fixup) {
4200 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4201 if (undef_pos != undefined_name_to_desc.end()) {
4202 const uint8_t dylib_ordinal =
4203 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4204 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4205 sym[pos.first].SetReExportedSymbolSharedLibrary(
4206 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4212 int trie_symbol_table_augment_count = 0;
4213 for (
auto &e : external_sym_trie_entries) {
4214 if (!symbols_added.contains(e.entry.address))
4215 trie_symbol_table_augment_count++;
4218 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4219 num_syms = sym_idx + trie_symbol_table_augment_count;
4220 sym = symtab.Resize(num_syms);
4222 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4225 for (
auto &e : external_sym_trie_entries) {
4226 if (symbols_added.contains(e.entry.address))
4232 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4234 const char *symbol_name = e.entry.name.GetCString();
4235 bool demangled_is_synthesized =
false;
4237 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4238 data_section_sp, data_dirty_section_sp,
4239 data_const_section_sp, symbol_section);
4241 sym[sym_idx].SetType(type);
4242 if (symbol_section) {
4243 sym[sym_idx].SetID(synthetic_sym_id++);
4244 sym[sym_idx].GetMangled().SetMangledName(
ConstString(symbol_name));
4245 if (demangled_is_synthesized)
4246 sym[sym_idx].SetDemangledNameIsSynthesized(
true);
4247 sym[sym_idx].SetIsSynthetic(
true);
4248 sym[sym_idx].SetExternal(
true);
4249 sym[sym_idx].GetAddressRef() = symbol_addr;
4258 if (function_starts_count > 0) {
4259 uint32_t num_synthetic_function_symbols = 0;
4260 for (i = 0; i < function_starts_count; ++i) {
4261 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4262 ++num_synthetic_function_symbols;
4265 if (num_synthetic_function_symbols > 0) {
4266 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4267 num_syms = sym_idx + num_synthetic_function_symbols;
4268 sym = symtab.Resize(num_syms);
4270 for (i = 0; i < function_starts_count; ++i) {
4271 const FunctionStarts::Entry *func_start_entry =
4272 function_starts.GetEntryAtIndex(i);
4273 if (!symbols_added.contains(func_start_entry->addr)) {
4274 addr_t symbol_file_addr = func_start_entry->addr;
4275 uint32_t symbol_flags = 0;
4276 if (func_start_entry->data)
4279 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4281 if (symbol_section) {
4282 sym[sym_idx].SetID(synthetic_sym_id++);
4286 sym[sym_idx].GetMangled().SetDemangledName(
ConstString());
4288 sym[sym_idx].SetIsSynthetic(
true);
4289 sym[sym_idx].GetAddressRef() = symbol_addr;
4292 sym[sym_idx].SetFlags(symbol_flags);
4303 if (sym_idx < num_syms) {
4305 sym = symtab.Resize(num_syms);
4309 if (m_dysymtab.nindirectsyms != 0) {
4310 if (indirect_symbol_index_data.GetByteSize()) {
4311 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4312 m_nlist_idx_to_sym_idx.end();
4314 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4316 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4318 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4319 if (symbol_stub_byte_size == 0)
4322 const uint32_t num_symbol_stubs =
4323 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4325 if (num_symbol_stubs == 0)
4328 const uint32_t symbol_stub_index_offset =
4329 m_mach_sections[sect_idx].reserved1;
4330 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4331 const uint32_t symbol_stub_index =
4332 symbol_stub_index_offset + stub_idx;
4334 m_mach_sections[sect_idx].addr +
4335 (stub_idx * symbol_stub_byte_size);
4337 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4338 symbol_stub_offset, 4)) {
4339 const uint32_t stub_sym_id =
4340 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4341 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4344 NListIndexToSymbolIndexMap::const_iterator index_pos =
4345 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4346 Symbol *stub_symbol =
nullptr;
4347 if (index_pos != end_index_pos) {
4350 stub_symbol = symtab.SymbolAtIndex(index_pos->second);
4354 stub_symbol = symtab.FindSymbolByID(stub_sym_id);
4358 Address so_addr(symbol_stub_addr, section_list);
4365 if (resolver_addresses.find(symbol_stub_addr) ==
4366 resolver_addresses.end())
4376 if (sym_idx >= num_syms) {
4377 sym = symtab.Resize(++num_syms);
4378 stub_symbol =
nullptr;
4380 sym[sym_idx].SetID(synthetic_sym_id++);
4381 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4382 if (resolver_addresses.find(symbol_stub_addr) ==
4383 resolver_addresses.end())
4387 sym[sym_idx].SetIsSynthetic(
true);
4388 sym[sym_idx].GetAddressRef() = so_addr;
4389 add_symbol_addr(so_addr.GetFileAddress());
4390 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4395 "warning: symbol stub referencing symbol table "
4396 "symbol %u that isn't in our minimal symbol table, "
4407 if (!reexport_trie_entries.empty()) {
4408 for (
const auto &e : reexport_trie_entries) {
4409 if (e.entry.import_name) {
4412 if (indirect_symbol_names.find(e.entry.name) ==
4413 indirect_symbol_names.end()) {
4415 if (sym_idx >= num_syms)
4416 sym = symtab.Resize(++num_syms);
4417 sym[sym_idx].SetID(synthetic_sym_id++);
4418 sym[sym_idx].GetMangled() =
Mangled(e.entry.name);
4420 sym[sym_idx].SetIsSynthetic(
true);
4421 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4422 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4423 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4424 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *>
Report error events.
PlatformList & GetPlatformList()
lldb::StreamUP GetAsyncOutputStream()
A plug-in interface definition class for dynamic loaders.
static llvm::Expected< lldb::ModuleSP > LocateAndLoadBinary(Process *process, BinarySpec &bin_spec)
Find a binary and load it into a Target.
virtual bool GetSharedCacheInformation(lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache, LazyBool &private_shared_cache, lldb_private::FileSpec &shared_cache_path, std::optional< uint64_t > &size)
Get information about the shared cache for a process, if possible.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
bool AppendIfUnique(const FileSpec &file)
Append a FileSpec object if unique.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
void ClearDirectory()
Clear the directory in this object.
llvm::StringRef GetFilename() const
Filename string const get accessor.
llvm::StringRef GetDirectory() const
Directory string const get accessor.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
FileSpec CopyByRemovingLastPathComponent() const
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
A class that handles mangled names.
void SetDemangledName(ConstString name)
ConstString GetDemangledName() const
Demangled name get accessor.
void SetMangledName(ConstString name)
void SetValue(ConstString name)
Set the string value in this object.
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A collection class for Module objects.
void Clear()
Clear the object's state.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
size_t GetSize() const
Gets the size of the module list.
void Append(const ModuleSpec &spec)
ModuleSpec & GetModuleSpecRefAtIndex(size_t i)
void SetObjectSize(uint64_t object_size)
ArchSpec & GetArchitecture()
void SetObjectOffset(uint64_t object_offset)
A plug-in interface definition class for object file parsers.
std::unique_ptr< lldb_private::SectionList > m_sections_up
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
std::unique_ptr< lldb_private::Symtab > m_symtab_up
const lldb::addr_t m_memory_addr
Set if the object file only exists in memory.
static lldb::SectionType GetDWARFSectionTypeFromName(llvm::StringRef name)
Parses the section type from a section name for DWARF sections.
Symtab * GetSymtab(bool can_create=true)
Gets the symbol table for the currently selected architecture (and object for archives).
DataExtractorNSP m_data_nsp
The data for this object file so things can be parsed lazily.
static lldb::WritableDataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
@ eTypeExecutable
A normal executable.
@ eTypeDebugInfo
An object file that contains only debug information.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
@ eTypeObjectFile
An intermediate object file.
@ eTypeDynamicLinker
The platform's dynamic linker executable.
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
@ eTypeSharedLibrary
A shared library that can be used during execution.
lldb::addr_t m_file_offset
The offset in bytes into the file, or the address in memory.
static lldb::SymbolType GetSymbolTypeFromName(llvm::StringRef name, lldb::SymbolType symbol_type_hint=lldb::eSymbolTypeUndefined)
bool SetModulesArchitecture(const ArchSpec &new_arch)
Sets the architecture for a module.
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
bool IsInMemory() const
Returns true if the object file exists only in memory.
lldb::ProcessWP m_process_wp
lldb::addr_t m_length
The length of this object file if it is known (can be zero if length is unknown or can't be determine...
BinaryType
If we have a corefile binary hint, this enum specifies the binary type which we can use to select the...
@ eBinaryTypeKernel
kernel binary
@ eBinaryTypeUser
user process binary, dyld addr
@ eBinaryTypeUserAllImageInfos
user process binary, dyld_all_image_infos addr
@ eBinaryTypeStandalone
standalone binary / firmware
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
void Flush()
Flush all data in the process.
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
Target & GetTarget()
Get the target object pointer for this module.
A Progress indicator helper class.
const Entry * FindEntryThatContains(B addr) const
const Entry * GetEntryAtIndex(size_t i) const
void Append(const Entry &entry)
Range< uint32_t, uint32_t > Entry
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value)=0
const void * GetBytes() const
const std::optional< lldb_private::FileSpec > GetOutputFile() const
lldb::SaveCoreStyle GetStyle() const
void SetStyle(lldb::SaveCoreStyle style)
size_t GetNumSections(uint32_t depth) const
lldb::SectionSP FindSectionByName(llvm::StringRef section_name) const
size_t AddSection(const lldb::SectionSP §ion_sp)
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
lldb::SectionSP GetSectionAtIndex(size_t idx) const
bool IsThreadSpecific() const
lldb::SectionSP GetParent() const
lldb::offset_t GetFileOffset() const
llvm::StringRef GetName() const
lldb::addr_t GetFileAddress() const
ObjectFile * GetObjectFile()
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
@ eBinary
Get and put data as binary instead of as the default string mode.
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
size_t PutRawBytes(const void *s, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
unsigned GetIndentLevel() const
Get the current indentation level.
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
Dictionary * GetAsDictionary()
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::shared_ptr< Array > ArraySP
Defines a list of symbol context objects.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Symbol * symbol
The Symbol for a given query.
bool ValueIsAddress() const
void SetReExportedSymbolName(ConstString name)
void SetType(lldb::SymbolType type)
void SetSizeIsSibling(bool b)
Address & GetAddressRef()
uint32_t GetFlags() const
bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
lldb::addr_t GetByteSize() const
lldb::SymbolType GetType() const
void SetFlags(uint32_t flags)
Address GetAddress() const
void SetByteSize(lldb::addr_t size)
void SetDemangledNameIsSynthesized(bool b)
Symbol * SymbolAtIndex(size_t idx)
Symbol * FindFirstSymbolWithNameAndType(ConstString name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
Symbol * Resize(size_t count)
Symbol * FindSymbolContainingFileAddress(lldb::addr_t file_addr)
size_t GetNumSymbols() const
MemoryModuleLoadLevel GetMemoryModuleLoadLevel() const
void ModulesDidLoad(ModuleList &module_list)
This call may preload module symbols, and may do so in parallel depending on the following target set...
Debugger & GetDebugger() const
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
bool SetSectionLoadAddress(const lldb::SectionSP §ion, lldb::addr_t load_addr, bool warn_multiple=false)
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
Represents UUID's of various sizes.
std::string GetAsString(llvm::StringRef separator="-") const
#define LLDB_INVALID_ADDRESS_MASK
Address Mask Bits not used for addressing are set to 1 in the mask; all mask bits set is an invalid v...
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_ADDRESS
lldb::ByteOrder InlHostByteOrder()
A class that represents a running process on the host machine.
constexpr uint64_t THUMB_ADDRESS_BIT_MASK
Mask that clears the low Thumb bit from an ARM function address.
bool ParseTrieEntries(DataExtractor &data, const bool is_arm, lldb::addr_t text_seg_base_addr, std::set< lldb::addr_t > &resolver_addresses, std::vector< TrieEntryWithOffset > &reexports, std::vector< TrieEntryWithOffset > &ext_symbols)
Parse the Mach-O export trie (the dyld symbol trie from LC_DYLD_INFO or LC_DYLD_EXPORTS_TRIE) startin...
@ eMemoryModuleLoadLevelPartial
@ eMemoryModuleLoadLevelComplete
@ eMemoryModuleLoadLevelMinimal
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
constexpr uint64_t TRIE_SYMBOL_IS_THUMB
Set on TrieEntry::flags for an ARM symbol whose address has the low Thumb bit set; the bit is strippe...
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::Process > ProcessSP
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ eSectionTypeDWARFDebugStrOffsets
@ eSectionTypeELFDynamicSymbols
Elf SHT_DYNSYM section.
@ eSectionTypeDWARFDebugPubNames
@ eSectionTypeDataObjCCFStrings
Objective-C const CFString/NSString objects.
@ eSectionTypeDWARFDebugLocDwo
@ eSectionTypeDWARFDebugFrame
@ eSectionTypeContainer
The section contains child sections.
@ eSectionTypeDWARFDebugLocLists
DWARF v5 .debug_loclists.
@ eSectionTypeDWARFDebugTypes
DWARF .debug_types section.
@ eSectionTypeDataSymbolAddress
Address of a symbol in the symbol table.
@ eSectionTypeELFDynamicLinkInfo
Elf SHT_DYNAMIC section.
@ eSectionTypeDWARFDebugMacInfo
@ eSectionTypeAbsoluteAddress
Dummy section for symbols with absolute address.
@ eSectionTypeCompactUnwind
compact unwind section in Mach-O, __TEXT,__unwind_info
@ eSectionTypeELFRelocationEntries
Elf SHT_REL or SHT_REL section.
@ eSectionTypeDWARFAppleNamespaces
@ eSectionTypeLLDBFormatters
@ eSectionTypeDWARFDebugNames
DWARF v5 .debug_names.
@ eSectionTypeDWARFDebugRngLists
DWARF v5 .debug_rnglists.
@ eSectionTypeDWARFDebugStrOffsetsDwo
@ eSectionTypeDWARFDebugMacro
@ eSectionTypeDWARFAppleTypes
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugTypesDwo
@ eSectionTypeDWARFDebugRanges
@ eSectionTypeDWARFDebugRngListsDwo
@ eSectionTypeLLDBTypeSummaries
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugPubTypes
@ eSectionTypeDataObjCMessageRefs
Pointer to function pointer + selector.
@ eSectionTypeDWARFDebugTuIndex
@ eSectionTypeDWARFDebugStr
@ eSectionTypeDWARFDebugLineStr
DWARF v5 .debug_line_str.
@ eSectionTypeDWARFDebugLoc
@ eSectionTypeDWARFAppleNames
@ eSectionTypeDataCStringPointers
Pointers to C string data.
@ eSectionTypeDWARFAppleObjC
@ eSectionTypeSwiftModules
@ eSectionTypeDWARFDebugCuIndex
@ eSectionTypeDWARFDebugAranges
@ eSectionTypeDWARFDebugAbbrevDwo
@ eSectionTypeDWARFGNUDebugAltLink
@ eSectionTypeDWARFDebugStrDwo
@ eSectionTypeDWARFDebugAbbrev
@ eSectionTypeDataPointers
@ eSectionTypeDWARFDebugLocListsDwo
@ eSectionTypeDWARFDebugInfoDwo
@ eSectionTypeDWARFDebugAddr
@ eSectionTypeDataCString
Inlined C string data.
@ eSectionTypeELFSymbolTable
Elf SHT_SYMTAB section.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP
Range< addr_t, addr_t > vm_range
lldb::offset_t export_off
The LC_DYSYMTAB's dysymtab_command has 32-bit file offsets that we will use as virtual address offset...
lldb::offset_t indirectsymoff
std::vector< MachOCorefileImageEntry > all_image_infos
A corefile may include metadata about all of the binaries that were present in the process when the c...
lldb::addr_t load_address
std::vector< std::tuple< lldb_private::ConstString, lldb::addr_t > > segment_load_addresses
lldb_private::SectionList & UnifiedList
SegmentParsingContext(EncryptedFileRanges EncryptedRanges, lldb_private::SectionList &UnifiedList)
const EncryptedFileRanges EncryptedRanges
bool FileAddressesChanged
image_entry(const image_entry &rhs)
uint64_t seg_addrs_offset
uint64_t cacheBaseAddress
A binary to find and load into a Target.
lldb::addr_t value
Address where the binary should be loaded, or read out of memory.
bool allow_memory_image_last_resort
If no better binary image can be found, allow reading the binary out of memory, if possible,...
UUID uuid
UUID of the binary to be loaded.
std::string name
Name of the binary, if available.
bool force_symbol_search
Allow the search to do a possibly expensive external search for the ObjectFile and/or SymbolFile.
bool set_address_in_target
Whether the address of the binary should be set in the Target if it is added.
bool notify
Whether ModulesDidLoad should be called once the binary has been added to the Target.
bool value_is_offset
A flag indicating that value is an address, or an offset to be applied to the file addresses.
BaseType GetRangeBase() const
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
void SetByteSize(SizeType s)
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_size
Size in bytes of the register.
segment_vmaddr(const segment_vmaddr &rhs)