9 #include "llvm/ADT/ScopeExit.h"
10 #include "llvm/ADT/StringRef.h"
50 #include "llvm/ADT/DenseSet.h"
51 #include "llvm/Support/FormatVariadic.h"
52 #include "llvm/Support/MemoryBuffer.h"
56 #if defined(__APPLE__)
57 #include <TargetConditionals.h>
60 #include <mach/mach_init.h>
61 #include <mach/vm_map.h>
68 #include <uuid/uuid.h>
82 #ifdef CPU_TYPE_ARM64_32
83 #undef CPU_TYPE_ARM64_32
88 #ifdef CPU_TYPE_X86_64
89 #undef CPU_TYPE_X86_64
97 #ifdef LC_VERSION_MIN_MACOSX
98 #undef LC_VERSION_MIN_MACOSX
100 #ifdef LC_VERSION_MIN_IPHONEOS
101 #undef LC_VERSION_MIN_IPHONEOS
103 #ifdef LC_VERSION_MIN_TVOS
104 #undef LC_VERSION_MIN_TVOS
106 #ifdef LC_VERSION_MIN_WATCHOS
107 #undef LC_VERSION_MIN_WATCHOS
109 #ifdef LC_BUILD_VERSION
110 #undef LC_BUILD_VERSION
112 #ifdef PLATFORM_MACOS
113 #undef PLATFORM_MACOS
115 #ifdef PLATFORM_MACCATALYST
116 #undef PLATFORM_MACCATALYST
121 #ifdef PLATFORM_IOSSIMULATOR
122 #undef PLATFORM_IOSSIMULATOR
127 #ifdef PLATFORM_TVOSSIMULATOR
128 #undef PLATFORM_TVOSSIMULATOR
130 #ifdef PLATFORM_WATCHOS
131 #undef PLATFORM_WATCHOS
133 #ifdef PLATFORM_WATCHOSSIMULATOR
134 #undef PLATFORM_WATCHOSSIMULATOR
137 #define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
138 using namespace lldb;
140 using namespace llvm::MachO;
165 const char *alt_name,
size_t reg_byte_size,
168 if (reg_info ==
nullptr)
173 if (reg_info->byte_size >= reg_byte_size)
177 for (
size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n; ++i)
184 for (
size_t i = 0; i < reg_byte_size; ++i)
193 SetRegisterDataFrom_LC_THREAD(data);
202 SetError(GPRRegSet, Read, -1);
203 SetError(FPURegSet, Read, -1);
204 SetError(EXCRegSet, Read, -1);
208 int flavor = data.
GetU32(&offset);
216 for (i = 0; i < count; ++i)
217 (&gpr.rax)[i] = data.
GetU64(&offset);
218 SetError(GPRRegSet, Read, 0);
229 exc.trapno = data.
GetU32(&offset);
230 exc.err = data.
GetU32(&offset);
231 exc.faultvaddr = data.
GetU64(&offset);
232 SetError(EXCRegSet, Read, 0);
398 SetRegisterDataFrom_LC_THREAD(data);
407 SetError(GPRRegSet, Read, -1);
408 SetError(FPURegSet, Read, -1);
409 SetError(EXCRegSet, Read, -1);
413 int flavor = data.
GetU32(&offset);
421 for (i = 0; i < count; ++i)
422 (&gpr.eax)[i] = data.
GetU32(&offset);
423 SetError(GPRRegSet, Read, 0);
434 exc.trapno = data.
GetU32(&offset);
435 exc.err = data.
GetU32(&offset);
436 exc.faultvaddr = data.
GetU32(&offset);
437 SetError(EXCRegSet, Read, 0);
514 SetRegisterDataFrom_LC_THREAD(data);
523 SetError(GPRRegSet, Read, -1);
524 SetError(FPURegSet, Read, -1);
525 SetError(EXCRegSet, Read, -1);
529 int flavor = data.
GetU32(&offset);
540 if (count > 0 && count <=
sizeof(gpr.r) /
sizeof(gpr.r[0])) {
541 for (
uint32_t i = 0; i < (count - 1); ++i) {
542 gpr.r[i] = data.
GetU32(&offset);
546 gpr.cpsr = data.
GetU32(&offset);
548 SetError(GPRRegSet, Read, 0);
549 offset = next_thread_state;
553 uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats;
554 const int fpu_reg_buf_size =
sizeof(fpu.floats);
556 fpu_reg_buf) == fpu_reg_buf_size) {
557 offset += fpu_reg_buf_size;
558 fpu.fpscr = data.
GetU32(&offset);
559 SetError(FPURegSet, Read, 0);
564 offset = next_thread_state;
569 exc.exception = data.
GetU32(&offset);
570 exc.fsr = data.
GetU32(&offset);
571 exc.far = data.
GetU32(&offset);
572 SetError(EXCRegSet, Read, 0);
575 offset = next_thread_state;
652 SetRegisterDataFrom_LC_THREAD(data);
661 SetError(GPRRegSet, Read, -1);
662 SetError(FPURegSet, Read, -1);
663 SetError(EXCRegSet, Read, -1);
666 int flavor = data.
GetU32(&offset);
673 if (count >= (33 * 2) + 1) {
675 gpr.x[i] = data.
GetU64(&offset);
676 gpr.fp = data.
GetU64(&offset);
677 gpr.lr = data.
GetU64(&offset);
678 gpr.sp = data.
GetU64(&offset);
679 gpr.pc = data.
GetU64(&offset);
680 gpr.cpsr = data.
GetU32(&offset);
681 SetError(GPRRegSet, Read, 0);
683 offset = next_thread_state;
686 uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];
687 const int fpu_reg_buf_size =
sizeof(fpu);
688 if (fpu_reg_buf_size == count *
sizeof(
uint32_t) &&
690 fpu_reg_buf) == fpu_reg_buf_size) {
691 SetError(FPURegSet, Read, 0);
696 offset = next_thread_state;
700 exc.far = data.
GetU64(&offset);
701 exc.esr = data.
GetU32(&offset);
702 exc.exception = data.
GetU32(&offset);
703 SetError(EXCRegSet, Read, 0);
705 offset = next_thread_state;
798 return sizeof(
struct llvm::MachO::mach_header);
802 return sizeof(
struct llvm::MachO::mach_header_64);
811 #define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
816 PluginManager::RegisterPlugin(
817 GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
818 CreateMemoryInstance, GetModuleSpecifications, SaveCore);
822 PluginManager::UnregisterPlugin(CreateInstance);
826 DataBufferSP data_sp,
832 data_sp = MapFileData(*file, length, file_offset);
842 if (data_sp->GetByteSize() < length) {
843 data_sp = MapFileData(*file, length, file_offset);
848 auto objfile_up = std::make_unique<ObjectFileMachO>(
849 module_sp, data_sp, data_offset, file, file_offset, length);
850 if (!objfile_up || !objfile_up->ParseHeader())
853 return objfile_up.release();
857 const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
858 const ProcessSP &process_sp,
lldb::addr_t header_addr) {
860 std::unique_ptr<ObjectFile> objfile_up(
862 if (objfile_up.get() && objfile_up->ParseHeader())
863 return objfile_up.release();
872 const size_t initial_count = specs.
GetSize();
877 llvm::MachO::mach_header header;
878 if (ParseHeader(data, &data_offset, header)) {
879 size_t header_and_load_cmds =
881 if (header_and_load_cmds >= data_sp->GetByteSize()) {
882 data_sp = MapFileData(file, header_and_load_cmds, file_offset);
891 GetAllArchSpecs(header, data, data_offset, base_spec, specs);
895 return specs.
GetSize() - initial_count;
900 return g_segment_name_TEXT;
905 return g_segment_name_DATA;
910 return g_segment_name;
915 return g_segment_name;
920 return g_segment_name_OBJC;
924 static ConstString g_section_name_LINKEDIT(
"__LINKEDIT");
925 return g_section_name_LINKEDIT;
930 return g_section_name;
934 static ConstString g_section_name_eh_frame(
"__eh_frame");
935 return g_section_name_eh_frame;
942 data.
SetData(data_sp, data_offset, data_length);
953 if (filetype == llvm::MachO::MH_FILESET)
960 DataBufferSP data_sp,
965 :
ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
966 m_mach_segments(), m_mach_sections(), m_entry_point_address(),
967 m_thread_context_offsets(), m_thread_context_offsets_valid(false),
968 m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
974 lldb::WritableDataBufferSP header_data_sp,
975 const lldb::ProcessSP &process_sp,
977 :
ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
978 m_mach_segments(), m_mach_sections(), m_entry_point_address(),
979 m_thread_context_offsets(), m_thread_context_offsets_valid(false),
980 m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
987 llvm::MachO::mach_header &header) {
990 header.magic = data.
GetU32(data_offset_ptr);
991 bool can_parse =
false;
992 bool is_64_bit =
false;
993 switch (header.magic) {
1029 data.
GetU32(data_offset_ptr, &header.cputype, 6);
1031 *data_offset_ptr += 4;
1034 memset(&header, 0,
sizeof(header));
1044 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1045 bool can_parse =
false;
1089 base_spec, all_specs);
1091 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
1096 const ArchSpec &module_arch = module_sp->GetArchitecture();
1101 const size_t header_and_lc_size =
1104 DataBufferSP data_sp;
1111 if (data_sp->GetByteSize() != header_and_lc_size)
1123 memset(&
m_header, 0,
sizeof(
struct llvm::MachO::mach_header));
1133 return m_header.filetype == MH_EXECUTE;
1137 return m_header.filetype == MH_DYLINKER;
1141 return m_header.flags & MH_DYLIB_IN_CACHE;
1151 return AddressClass::eUnknown;
1159 switch (section_type) {
1161 return AddressClass::eUnknown;
1164 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1168 return AddressClass::eCodeAlternateISA;
1170 return AddressClass::eCode;
1173 return AddressClass::eUnknown;
1187 return AddressClass::eData;
1224 return AddressClass::eDebug;
1230 return AddressClass::eRuntime;
1238 return AddressClass::eUnknown;
1244 switch (symbol_type) {
1246 return AddressClass::eUnknown;
1248 return AddressClass::eUnknown;
1253 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1257 return AddressClass::eCodeAlternateISA;
1259 return AddressClass::eCode;
1262 return AddressClass::eData;
1264 return AddressClass::eRuntime;
1266 return AddressClass::eRuntime;
1268 return AddressClass::eDebug;
1270 return AddressClass::eDebug;
1272 return AddressClass::eDebug;
1274 return AddressClass::eDebug;
1276 return AddressClass::eDebug;
1278 return AddressClass::eData;
1280 return AddressClass::eData;
1282 return AddressClass::eData;
1284 return AddressClass::eDebug;
1286 return AddressClass::eDebug;
1288 return AddressClass::eDebug;
1290 return AddressClass::eDebug;
1292 return AddressClass::eDebug;
1294 return AddressClass::eUnknown;
1296 return AddressClass::eDebug;
1298 return AddressClass::eDebug;
1300 return AddressClass::eUnknown;
1302 return AddressClass::eRuntime;
1304 return AddressClass::eRuntime;
1306 return AddressClass::eRuntime;
1308 return AddressClass::eRuntime;
1311 return AddressClass::eUnknown;
1322 llvm::MachO::load_command lc = {};
1325 if (lc.cmd == LC_DYSYMTAB) {
1336 offset = load_cmd_offset + lc.cmdsize;
1349 llvm::MachO::encryption_info_command encryption_cmd;
1352 if (
m_data.
GetU32(&offset, &encryption_cmd, 2) ==
nullptr)
1357 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
1358 encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
1359 if (
m_data.
GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
1360 if (encryption_cmd.cryptid != 0) {
1368 offset = load_cmd_offset + encryption_cmd.cmdsize;
1375 llvm::MachO::segment_command_64 &seg_cmd,
uint32_t cmd_idx) {
1376 if (
m_length == 0 || seg_cmd.filesize == 0)
1384 if (strncmp(seg_cmd.segname,
"__TEXT",
sizeof(seg_cmd.segname)) == 0)
1386 if (strncmp(seg_cmd.segname,
"__LINKEDIT",
sizeof(seg_cmd.segname)) == 0)
1399 const char *lc_segment_name =
1400 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1402 "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "
1403 "the end of the file ({3:x16}), ignoring this section",
1404 cmd_idx, lc_segment_name, seg_cmd.fileoff,
m_length);
1406 seg_cmd.fileoff = 0;
1407 seg_cmd.filesize = 0;
1410 if (seg_cmd.fileoff + seg_cmd.filesize >
m_length) {
1417 const char *lc_segment_name =
1418 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1420 "load command {0} {1} has a fileoff + filesize ({2:x16}) that "
1421 "extends beyond the end of the file ({4:x16}), the segment will be "
1422 "truncated to match",
1423 cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize,
m_length);
1426 seg_cmd.filesize =
m_length - seg_cmd.fileoff;
1433 if (seg_cmd.initprot & VM_PROT_READ)
1434 result |= ePermissionsReadable;
1435 if (seg_cmd.initprot & VM_PROT_WRITE)
1436 result |= ePermissionsWritable;
1437 if (seg_cmd.initprot & VM_PROT_EXECUTE)
1438 result |= ePermissionsExecutable;
1445 if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1448 uint32_t mach_sect_type = flags & SECTION_TYPE;
1449 static ConstString g_sect_name_objc_data(
"__objc_data");
1450 static ConstString g_sect_name_objc_msgrefs(
"__objc_msgrefs");
1451 static ConstString g_sect_name_objc_selrefs(
"__objc_selrefs");
1452 static ConstString g_sect_name_objc_classrefs(
"__objc_classrefs");
1453 static ConstString g_sect_name_objc_superrefs(
"__objc_superrefs");
1454 static ConstString g_sect_name_objc_const(
"__objc_const");
1455 static ConstString g_sect_name_objc_classlist(
"__objc_classlist");
1456 static ConstString g_sect_name_cfstring(
"__cfstring");
1458 static ConstString g_sect_name_dwarf_debug_abbrev(
"__debug_abbrev");
1459 static ConstString g_sect_name_dwarf_debug_aranges(
"__debug_aranges");
1460 static ConstString g_sect_name_dwarf_debug_frame(
"__debug_frame");
1461 static ConstString g_sect_name_dwarf_debug_info(
"__debug_info");
1462 static ConstString g_sect_name_dwarf_debug_line(
"__debug_line");
1463 static ConstString g_sect_name_dwarf_debug_loc(
"__debug_loc");
1464 static ConstString g_sect_name_dwarf_debug_loclists(
"__debug_loclists");
1465 static ConstString g_sect_name_dwarf_debug_macinfo(
"__debug_macinfo");
1466 static ConstString g_sect_name_dwarf_debug_names(
"__debug_names");
1467 static ConstString g_sect_name_dwarf_debug_pubnames(
"__debug_pubnames");
1468 static ConstString g_sect_name_dwarf_debug_pubtypes(
"__debug_pubtypes");
1469 static ConstString g_sect_name_dwarf_debug_ranges(
"__debug_ranges");
1470 static ConstString g_sect_name_dwarf_debug_str(
"__debug_str");
1471 static ConstString g_sect_name_dwarf_debug_types(
"__debug_types");
1472 static ConstString g_sect_name_dwarf_apple_names(
"__apple_names");
1473 static ConstString g_sect_name_dwarf_apple_types(
"__apple_types");
1474 static ConstString g_sect_name_dwarf_apple_namespaces(
"__apple_namespac");
1475 static ConstString g_sect_name_dwarf_apple_objc(
"__apple_objc");
1476 static ConstString g_sect_name_eh_frame(
"__eh_frame");
1477 static ConstString g_sect_name_compact_unwind(
"__unwind_info");
1480 static ConstString g_sect_name_go_symtab(
"__gosymtab");
1482 if (section_name == g_sect_name_dwarf_debug_abbrev)
1484 if (section_name == g_sect_name_dwarf_debug_aranges)
1486 if (section_name == g_sect_name_dwarf_debug_frame)
1488 if (section_name == g_sect_name_dwarf_debug_info)
1490 if (section_name == g_sect_name_dwarf_debug_line)
1492 if (section_name == g_sect_name_dwarf_debug_loc)
1494 if (section_name == g_sect_name_dwarf_debug_loclists)
1496 if (section_name == g_sect_name_dwarf_debug_macinfo)
1498 if (section_name == g_sect_name_dwarf_debug_names)
1500 if (section_name == g_sect_name_dwarf_debug_pubnames)
1502 if (section_name == g_sect_name_dwarf_debug_pubtypes)
1504 if (section_name == g_sect_name_dwarf_debug_ranges)
1506 if (section_name == g_sect_name_dwarf_debug_str)
1508 if (section_name == g_sect_name_dwarf_debug_types)
1510 if (section_name == g_sect_name_dwarf_apple_names)
1512 if (section_name == g_sect_name_dwarf_apple_types)
1514 if (section_name == g_sect_name_dwarf_apple_namespaces)
1516 if (section_name == g_sect_name_dwarf_apple_objc)
1518 if (section_name == g_sect_name_objc_selrefs)
1520 if (section_name == g_sect_name_objc_msgrefs)
1522 if (section_name == g_sect_name_eh_frame)
1524 if (section_name == g_sect_name_compact_unwind)
1526 if (section_name == g_sect_name_cfstring)
1528 if (section_name == g_sect_name_go_symtab)
1530 if (section_name == g_sect_name_objc_data ||
1531 section_name == g_sect_name_objc_classrefs ||
1532 section_name == g_sect_name_objc_superrefs ||
1533 section_name == g_sect_name_objc_const ||
1534 section_name == g_sect_name_objc_classlist) {
1538 switch (mach_sect_type) {
1541 if (section_name == g_sect_name_text)
1543 if (section_name == g_sect_name_data)
1548 case S_CSTRING_LITERALS:
1550 case S_4BYTE_LITERALS:
1552 case S_8BYTE_LITERALS:
1554 case S_LITERAL_POINTERS:
1556 case S_NON_LAZY_SYMBOL_POINTERS:
1558 case S_LAZY_SYMBOL_POINTERS:
1560 case S_SYMBOL_STUBS:
1563 case S_MOD_INIT_FUNC_POINTERS:
1566 case S_MOD_TERM_FUNC_POINTERS:
1576 case S_16BYTE_LITERALS:
1580 case S_LAZY_DYLIB_SYMBOL_POINTERS:
1600 const llvm::MachO::load_command &load_cmd_,
lldb::offset_t offset,
1602 llvm::MachO::segment_command_64 load_cmd;
1603 memcpy(&load_cmd, &load_cmd_,
sizeof(load_cmd_));
1605 if (!
m_data.
GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
1610 const bool is_dsym = (
m_header.filetype == MH_DSYM);
1611 bool add_section =
true;
1612 bool add_to_unified =
true;
1614 load_cmd.segname, strnlen(load_cmd.segname,
sizeof(load_cmd.segname)));
1616 SectionSP unified_section_sp(
1618 if (is_dsym && unified_section_sp) {
1622 add_to_unified =
false;
1626 add_section =
false;
1639 const bool segment_is_encrypted =
1640 (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
1648 SectionSP segment_sp;
1649 if (add_section && (const_segname || is_core)) {
1650 segment_sp = std::make_shared<Section>(
1670 segment_sp->SetIsEncrypted(segment_is_encrypted);
1672 segment_sp->SetPermissions(segment_permissions);
1675 }
else if (unified_section_sp) {
1685 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
1689 "Installing dSYM's %s segment file address over ObjectFile's "
1690 "so symbol table/debug info resolves correctly for %s",
1692 module_sp->GetFileSpec().GetFilename().AsCString());
1697 module_sp->GetObjectFile()->GetSymtab();
1703 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
1712 llvm::MachO::section_64 sect64;
1713 ::memset(§64, 0,
sizeof(sect64));
1721 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
1722 for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
1723 ++segment_sect_idx) {
1724 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.sectname,
1725 sizeof(sect64.sectname)) ==
nullptr)
1727 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.segname,
1728 sizeof(sect64.segname)) ==
nullptr)
1733 if (
m_data.
GetU32(&offset, §64.offset, num_u32s) ==
nullptr)
1746 sect64.sectname, strnlen(sect64.sectname,
sizeof(sect64.sectname)));
1747 if (!const_segname) {
1755 sizeof(sect64.segname));
1757 if (segment_sp.get()) {
1758 Section *segment = segment_sp.get();
1761 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1765 curr_seg_min_addr + curr_seg_byte_size;
1766 if (sect64_min_addr >= curr_seg_min_addr) {
1768 sect64_max_addr - curr_seg_min_addr;
1770 if (new_seg_byte_size > curr_seg_byte_size)
1776 sect64_min_addr - curr_seg_min_addr;
1777 segment->
Slide(slide_amount,
false);
1779 segment->
SetByteSize(curr_seg_max_addr - sect64_min_addr);
1783 if (sect64.offset) {
1789 const lldb::addr_t section_min_file_offset = sect64.offset;
1791 section_min_file_offset + sect64.size;
1793 std::min(section_min_file_offset, segment_min_file_offset);
1795 std::max(section_max_file_offset, segment_max_file_offset) -
1802 segment_sp = std::make_shared<Section>(
1819 sect64.offset ? sect64.size : 0,
1824 segment_sp->SetIsFake(
true);
1825 segment_sp->SetPermissions(segment_permissions);
1829 segment_sp->SetIsEncrypted(segment_is_encrypted);
1832 assert(segment_sp.get());
1836 SectionSP section_sp(
new Section(
1837 segment_sp, module_sp,
this, ++context.
NextSectionIdx, section_name,
1838 sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
1839 sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
1843 bool section_is_encrypted =
false;
1844 if (!segment_is_encrypted && load_cmd.filesize != 0)
1846 sect64.offset) !=
nullptr;
1848 section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
1849 section_sp->SetPermissions(segment_permissions);
1850 segment_sp->GetChildren().AddSection(section_sp);
1852 if (segment_sp->IsFake()) {
1854 const_segname.
Clear();
1858 if (segment_sp && is_dsym) {
1861 for (sect_uid = first_segment_sectID; sect_uid <= context.
NextSectionIdx;
1863 SectionSP curr_section_sp(
1864 segment_sp->GetChildren().FindSectionByID(sect_uid));
1865 SectionSP next_section_sp;
1868 segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
1870 if (curr_section_sp.get()) {
1871 if (curr_section_sp->GetByteSize() == 0) {
1872 if (next_section_sp.get() !=
nullptr)
1873 curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
1874 curr_section_sp->GetFileAddress());
1876 curr_section_sp->SetByteSize(load_cmd.vmsize);
1885 const llvm::MachO::load_command &load_cmd,
lldb::offset_t offset) {
1905 llvm::MachO::load_command load_cmd;
1911 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
1913 else if (load_cmd.cmd == LC_DYSYMTAB)
1916 offset = load_cmd_offset + load_cmd.cmdsize;
1920 module_sp->SectionFileAddressesChanged();
1942 section_sp->GetFileAddress());
1944 section_sp->GetByteSize());
1948 if (first_section_sp)
1949 filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
1951 Debugger::ReportError(
1952 llvm::formatv(
"unable to find section {0} for a symbol in "
1953 "{1}, corrupt file?",
1983 #define TRIE_SYMBOL_IS_THUMB (1ULL << 63)
1986 printf(
"0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
1987 static_cast<unsigned long long>(
address),
1988 static_cast<unsigned long long>(
flags),
2011 printf(
"[%3u] 0x%16.16llx: ", idx,
2012 static_cast<unsigned long long>(
nodeOffset));
2022 const bool is_arm,
addr_t text_seg_base_addr,
2023 std::vector<llvm::StringRef> &nameSlices,
2024 std::set<lldb::addr_t> &resolver_addresses,
2025 std::vector<TrieEntryWithOffset> &reexports,
2026 std::vector<TrieEntryWithOffset> &ext_symbols) {
2032 const uint64_t terminalSize = data.
GetULEB128(&offset);
2034 if (terminalSize != 0) {
2037 const char *import_name =
nullptr;
2038 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
2041 import_name = data.
GetCStr(&offset);
2046 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
2050 resolver_addr += text_seg_base_addr;
2053 resolver_addresses.insert(resolver_addr);
2057 bool add_this_entry =
false;
2059 import_name && import_name[0]) {
2061 add_this_entry =
true;
2063 (import_name ==
nullptr || import_name[0] ==
'\0')) {
2066 add_this_entry =
true;
2068 if (add_this_entry) {
2070 if (!nameSlices.empty()) {
2071 for (
auto name_slice : nameSlices)
2072 name.append(name_slice.data(), name_slice.size());
2074 if (name.size() > 1) {
2083 reexports.push_back(e);
2089 ext_symbols.push_back(e);
2094 const uint8_t childrenCount = data.
GetU8(&children_offset);
2095 for (uint8_t i = 0; i < childrenCount; ++i) {
2096 const char *cstr = data.
GetCStr(&children_offset);
2098 nameSlices.push_back(llvm::StringRef(cstr));
2102 if (childNodeOffset) {
2104 nameSlices, resolver_addresses, reexports,
2109 nameSlices.pop_back();
2115 bool &demangled_is_synthesized,
2116 const SectionSP &text_section_sp,
2117 const SectionSP &data_section_sp,
2118 const SectionSP &data_dirty_section_sp,
2119 const SectionSP &data_const_section_sp,
2120 const SectionSP &symbol_section) {
2123 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2124 if (symbol_section->IsDescendant(text_section_sp.get())) {
2125 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
2126 S_ATTR_SELF_MODIFYING_CODE |
2127 S_ATTR_SOME_INSTRUCTIONS))
2131 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
2132 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
2133 symbol_section->IsDescendant(data_const_section_sp.get())) {
2134 if (symbol_sect_name &&
2135 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
2139 llvm::StringRef symbol_name_ref(symbol_name);
2140 if (symbol_name_ref.startswith(
"OBJC_")) {
2141 static const llvm::StringRef g_objc_v2_prefix_class(
"OBJC_CLASS_$_");
2142 static const llvm::StringRef g_objc_v2_prefix_metaclass(
2143 "OBJC_METACLASS_$_");
2144 static const llvm::StringRef g_objc_v2_prefix_ivar(
"OBJC_IVAR_$_");
2145 if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
2146 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2148 demangled_is_synthesized =
true;
2149 }
else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) {
2150 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2152 demangled_is_synthesized =
true;
2153 }
else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) {
2154 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2156 demangled_is_synthesized =
true;
2160 }
else if (symbol_sect_name &&
2161 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
2167 }
else if (symbol_sect_name &&
2168 ::strstr(symbol_sect_name,
"__IMPORT") == symbol_sect_name) {
2183 DataExtractor dsc_header_data(DscData, byte_order, addr_byte_size);
2185 char version_str[7];
2187 memcpy(version_str, dsc_header_data.
GetData(&offset, 6), 6);
2188 version_str[6] =
'\0';
2189 if (strcmp(version_str,
"dyld_v") == 0) {
2195 if (log && dsc_uuid.
IsValid()) {
2196 LLDB_LOGF(log,
"Shared cache %s has UUID %s",
2197 dyld_shared_cache.
GetPath().c_str(),
2203 static std::optional<struct nlist_64>
2205 size_t nlist_byte_size) {
2206 struct nlist_64 nlist;
2227 Progress progress(llvm::formatv(
"Parsing symbol table for {0}", file_name));
2229 llvm::MachO::symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
2230 llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
2231 llvm::MachO::linkedit_data_command exports_trie_load_command = {0, 0, 0, 0};
2232 llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2233 llvm::MachO::dysymtab_command dysymtab =
m_dysymtab;
2242 llvm::DenseSet<addr_t> symbols_added;
2246 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2250 symbols_added.insert(file_addr);
2252 FunctionStarts function_starts;
2255 FileSpecList dylib_files;
2257 llvm::StringRef g_objc_v2_prefix_class(
"_OBJC_CLASS_$_");
2258 llvm::StringRef g_objc_v2_prefix_metaclass(
"_OBJC_METACLASS_$_");
2259 llvm::StringRef g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
2262 for (i = 0; i <
m_header.ncmds; ++i) {
2265 llvm::MachO::load_command lc;
2271 symtab_load_command.cmd = lc.cmd;
2272 symtab_load_command.cmdsize = lc.cmdsize;
2274 if (
m_data.
GetU32(&offset, &symtab_load_command.symoff, 4) ==
2280 case LC_DYLD_INFO_ONLY:
2281 if (
m_data.
GetU32(&offset, &dyld_info.rebase_off, 10)) {
2282 dyld_info.cmd = lc.cmd;
2283 dyld_info.cmdsize = lc.cmdsize;
2285 memset(&dyld_info, 0,
sizeof(dyld_info));
2290 case LC_LOAD_WEAK_DYLIB:
2291 case LC_REEXPORT_DYLIB:
2293 case LC_LOAD_UPWARD_DYLIB: {
2303 if (lc.cmd == LC_REEXPORT_DYLIB) {
2307 dylib_files.Append(file_spec);
2311 case LC_DYLD_EXPORTS_TRIE:
2312 exports_trie_load_command.cmd = lc.cmd;
2313 exports_trie_load_command.cmdsize = lc.cmdsize;
2314 if (
m_data.
GetU32(&offset, &exports_trie_load_command.dataoff, 2) ==
2316 memset(&exports_trie_load_command, 0,
2317 sizeof(exports_trie_load_command));
2319 case LC_FUNCTION_STARTS:
2320 function_starts_load_command.cmd = lc.cmd;
2321 function_starts_load_command.cmdsize = lc.cmdsize;
2322 if (
m_data.
GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
2324 memset(&function_starts_load_command, 0,
2325 sizeof(function_starts_load_command));
2332 image_uuid =
UUID(uuid_bytes, 16);
2339 offset = cmd_offset + lc.cmdsize;
2342 if (!symtab_load_command.cmd)
2346 if (section_list ==
nullptr)
2351 bool bit_width_32 = addr_byte_size == 4;
2352 const size_t nlist_byte_size =
2353 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2355 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2356 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2357 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2358 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2360 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2362 const
addr_t nlist_data_byte_size =
2363 symtab_load_command.nsyms * nlist_byte_size;
2364 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2367 ProcessSP process_sp(m_process_wp.lock());
2368 Process *process = process_sp.get();
2372 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2373 SectionSP linkedit_section_sp(
2374 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2376 if (process && m_header.filetype != llvm::MachO::MH_OBJECT &&
2377 !is_local_shared_cache_image) {
2378 Target &target = process->GetTarget();
2384 if (linkedit_section_sp) {
2385 addr_t linkedit_load_addr =
2386 linkedit_section_sp->GetLoadBaseAddress(&target);
2396 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2397 const addr_t symoff_addr = linkedit_load_addr +
2398 symtab_load_command.symoff -
2399 linkedit_file_offset;
2400 strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
2401 linkedit_file_offset;
2409 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2410 DataBufferSP nlist_data_sp(
2411 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2413 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2414 if (dysymtab.nindirectsyms != 0) {
2415 const addr_t indirect_syms_addr = linkedit_load_addr +
2416 dysymtab.indirectsymoff -
2417 linkedit_file_offset;
2418 DataBufferSP indirect_syms_data_sp(
ReadMemory(
2419 process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
2420 if (indirect_syms_data_sp)
2421 indirect_symbol_index_data.SetData(
2422 indirect_syms_data_sp, 0,
2423 indirect_syms_data_sp->GetByteSize());
2433 if (!is_shared_cache_image) {
2434 DataBufferSP strtab_data_sp(
2435 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2436 if (strtab_data_sp) {
2437 strtab_data.SetData(strtab_data_sp, 0,
2438 strtab_data_sp->GetByteSize());
2443 if (function_starts_load_command.cmd) {
2444 const addr_t func_start_addr =
2445 linkedit_load_addr + function_starts_load_command.dataoff -
2446 linkedit_file_offset;
2447 DataBufferSP func_start_data_sp(
2449 function_starts_load_command.datasize));
2450 if (func_start_data_sp)
2451 function_starts_data.SetData(func_start_data_sp, 0,
2452 func_start_data_sp->GetByteSize());
2458 if (is_local_shared_cache_image) {
2466 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2469 symtab_load_command.symoff += linkedit_slide;
2470 symtab_load_command.stroff += linkedit_slide;
2471 dyld_info.export_off += linkedit_slide;
2472 dysymtab.indirectsymoff += linkedit_slide;
2473 function_starts_load_command.dataoff += linkedit_slide;
2474 exports_trie_load_command.dataoff += linkedit_slide;
2477 nlist_data.SetData(
m_data, symtab_load_command.symoff,
2478 nlist_data_byte_size);
2479 strtab_data.SetData(
m_data, symtab_load_command.stroff,
2480 strtab_data_byte_size);
2485 && (exports_trie_load_command.datasize > 0)));
2486 if (dyld_info.export_size > 0) {
2487 dyld_trie_data.SetData(
m_data, dyld_info.export_off,
2488 dyld_info.export_size);
2489 }
else if (exports_trie_load_command.datasize > 0) {
2490 dyld_trie_data.SetData(
m_data, exports_trie_load_command.dataoff,
2491 exports_trie_load_command.datasize);
2494 if (dysymtab.nindirectsyms != 0) {
2495 indirect_symbol_index_data.SetData(
m_data, dysymtab.indirectsymoff,
2496 dysymtab.nindirectsyms * 4);
2498 if (function_starts_load_command.cmd) {
2499 function_starts_data.SetData(
m_data, function_starts_load_command.dataoff,
2500 function_starts_load_command.datasize);
2504 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2512 SectionSP text_section_sp(
2514 SectionSP data_section_sp(
2516 SectionSP data_dirty_section_sp(
2518 SectionSP data_const_section_sp(
2520 SectionSP objc_section_sp(
2522 SectionSP eh_frame_section_sp;
2523 if (text_section_sp.get())
2524 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2525 g_section_name_eh_frame);
2527 eh_frame_section_sp =
2530 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2547 if (text_section_sp && function_starts_data.GetByteSize()) {
2549 function_start_entry.data =
false;
2551 function_start_entry.addr = text_section_sp->GetFileAddress();
2553 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2556 function_start_entry.addr += delta;
2558 if (function_start_entry.addr & 1) {
2560 function_start_entry.data =
true;
2561 }
else if (always_thumb) {
2562 function_start_entry.data =
true;
2565 function_starts.Append(function_start_entry);
2573 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2576 DWARFCallFrameInfo::EH);
2579 addr_t text_base_addr = text_section_sp->GetFileAddress();
2580 size_t count = functions.
GetSize();
2581 for (
size_t i = 0; i < count; ++i) {
2586 function_start_entry.addr = func->
base - text_base_addr;
2588 if (function_start_entry.addr & 1) {
2590 function_start_entry.data =
true;
2591 }
else if (always_thumb) {
2592 function_start_entry.data =
true;
2595 function_starts.Append(function_start_entry);
2601 const size_t function_starts_count = function_starts.GetSize();
2614 Log *unwind_or_symbol_log(
GetLog(LLDBLog::Symbols | LLDBLog::Unwind));
2616 if (unwind_or_symbol_log)
2617 module_sp->LogMessage(
2618 unwind_or_symbol_log,
2619 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2622 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2623 ? eh_frame_section_sp->GetID()
2629 std::vector<uint32_t> N_FUN_indexes;
2630 std::vector<uint32_t> N_NSYM_indexes;
2631 std::vector<uint32_t> N_INCL_indexes;
2632 std::vector<uint32_t> N_BRAC_indexes;
2633 std::vector<uint32_t> N_COMM_indexes;
2634 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2635 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2636 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2637 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2638 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2639 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2642 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2644 Symbol *symbol_ptr =
nullptr;
2648 size_t num_syms = 0;
2650 uint32_t unmapped_local_symbols_found = 0;
2652 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2653 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2654 std::set<lldb::addr_t> resolver_addresses;
2656 if (dyld_trie_data.GetByteSize() > 0) {
2658 SectionSP text_segment_sp =
2661 if (text_segment_sp)
2662 text_segment_file_addr = text_segment_sp->GetFileAddress();
2663 std::vector<llvm::StringRef> nameSlices;
2665 nameSlices, resolver_addresses, reexport_trie_entries,
2666 external_sym_trie_entries);
2669 typedef std::set<ConstString> IndirectSymbols;
2670 IndirectSymbols indirect_symbol_names;
2672 #if TARGET_OS_IPHONE
2693 UUID process_shared_cache_uuid;
2694 addr_t process_shared_cache_base_addr;
2698 process_shared_cache_uuid);
2701 __block
bool found_image =
false;
2702 __block
void *nlist_buffer =
nullptr;
2703 __block
unsigned nlist_count = 0;
2704 __block
char *string_table =
nullptr;
2705 __block vm_offset_t vm_nlist_memory = 0;
2706 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2707 __block vm_offset_t vm_string_memory = 0;
2708 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2710 auto _ = llvm::make_scope_exit(^{
2711 if (vm_nlist_memory)
2712 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2713 if (vm_string_memory)
2714 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2717 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2718 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2719 UndefinedNameToDescMap undefined_name_to_desc;
2720 SymbolIndexToName reexport_shlib_needs_fixup;
2722 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2724 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2728 if (process_shared_cache_uuid.
IsValid() &&
2729 process_shared_cache_uuid != UUID::fromData(&cache_uuid, 16))
2732 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2737 dyld_image_copy_uuid(image, &dsc_image_uuid);
2738 if (image_uuid != UUID::fromData(dsc_image_uuid, 16))
2745 dyld_image_local_nlist_content_4Symbolication(
2746 image, ^(
const void *nlistStart, uint64_t nlistCount,
2747 const char *stringTable) {
2748 if (!nlistStart || !nlistCount)
2756 nlist_byte_size * nlistCount, &vm_nlist_memory,
2757 &vm_nlist_bytes_read);
2760 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2765 vm_address_t string_address = (vm_address_t)stringTable;
2766 vm_size_t region_size;
2767 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2768 vm_region_basic_info_data_t info;
2769 memory_object_name_t object;
2771 ®ion_size, VM_REGION_BASIC_INFO_64,
2772 (vm_region_info_t)&info, &info_count, &
object);
2778 ((vm_address_t)stringTable - string_address),
2779 &vm_string_memory, &vm_string_bytes_read);
2783 nlist_buffer = (
void *)vm_nlist_memory;
2784 string_table = (
char *)vm_string_memory;
2785 nlist_count = nlistCount;
2791 nlist_count * nlist_byte_size,
2792 byte_order, addr_byte_size);
2793 unmapped_local_symbols_found = nlist_count;
2798 symtab_load_command.nsyms +
m_dysymtab.nindirectsyms +
2799 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2805 nlist_index < nlist_count;
2809 std::optional<struct nlist_64> nlist_maybe =
2810 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2814 struct nlist_64 nlist = *nlist_maybe;
2817 const char *symbol_name = string_table + nlist.n_strx;
2819 if (symbol_name == NULL) {
2823 Debugger::ReportError(llvm::formatv(
2824 "DSC unmapped local symbol[{0}] has invalid "
2825 "string table offset {1:x} in {2}, ignoring symbol",
2826 nlist_index, nlist.n_strx,
2827 module_sp->GetFileSpec().GetPath());
2830 if (symbol_name[0] ==
'\0')
2833 const char *symbol_name_non_abi_mangled = NULL;
2835 SectionSP symbol_section;
2837 bool add_nlist =
true;
2838 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2839 bool demangled_is_synthesized =
false;
2840 bool is_gsym =
false;
2841 bool set_value =
true;
2843 assert(sym_idx < num_syms);
2848 switch (nlist.n_type) {
2867 if (symbol_name && symbol_name[0] ==
'_' &&
2868 symbol_name[1] ==
'O') {
2869 llvm::StringRef symbol_name_ref(symbol_name);
2870 if (symbol_name_ref.startswith(
2871 g_objc_v2_prefix_class)) {
2872 symbol_name_non_abi_mangled = symbol_name + 1;
2874 symbol_name + g_objc_v2_prefix_class.size();
2876 demangled_is_synthesized =
true;
2878 }
else if (symbol_name_ref.startswith(
2879 g_objc_v2_prefix_metaclass)) {
2880 symbol_name_non_abi_mangled = symbol_name + 1;
2882 symbol_name + g_objc_v2_prefix_metaclass.size();
2884 demangled_is_synthesized =
true;
2885 }
else if (symbol_name_ref.startswith(
2886 g_objc_v2_prefix_ivar)) {
2887 symbol_name_non_abi_mangled = symbol_name + 1;
2889 symbol_name + g_objc_v2_prefix_ivar.size();
2891 demangled_is_synthesized =
true;
2894 if (nlist.n_value != 0)
2896 nlist.n_sect, nlist.n_value);
2911 nlist.n_sect, nlist.n_value);
2913 N_FUN_addr_to_sym_idx.insert(
2914 std::make_pair(nlist.n_value, sym_idx));
2918 N_FUN_indexes.push_back(sym_idx);
2922 if (!N_FUN_indexes.empty()) {
2929 N_FUN_indexes.pop_back();
2941 N_STSYM_addr_to_sym_idx.insert(
2942 std::make_pair(nlist.n_value, sym_idx));
2943 symbol_section = section_info.
GetSection(nlist.n_sect,
2945 if (symbol_name && symbol_name[0]) {
2946 type = ObjectFile::GetSymbolTypeFromName(
2953 symbol_section = section_info.
GetSection(nlist.n_sect,
2987 symbol_section = section_info.
GetSection(nlist.n_sect,
3000 if (symbol_name == NULL) {
3011 N_NSYM_indexes.clear();
3012 N_INCL_indexes.clear();
3013 N_BRAC_indexes.clear();
3014 N_COMM_indexes.clear();
3015 N_FUN_indexes.clear();
3021 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3022 if (N_SO_has_full_path) {
3023 if ((N_SO_index == sym_idx - 1) &&
3024 ((sym_idx - 1) < num_syms)) {
3030 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3036 N_SO_index = sym_idx;
3038 }
else if ((N_SO_index == sym_idx - 1) &&
3039 ((sym_idx - 1) < num_syms)) {
3044 const char *so_path = sym[sym_idx - 1]
3048 if (so_path && so_path[0]) {
3050 const size_t double_slash_pos =
3051 full_so_path.find(
"//");
3052 if (double_slash_pos != std::string::npos) {
3061 if (!FileSystem::Instance().Exists(so_dir)) {
3063 &full_so_path[double_slash_pos + 1],
3064 FileSpec::Style::native);
3065 if (FileSystem::Instance().Exists(so_dir)) {
3067 full_so_path.erase(0, double_slash_pos + 1);
3071 if (*full_so_path.rbegin() !=
'/')
3072 full_so_path +=
'/';
3073 full_so_path += symbol_name;
3077 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3081 N_SO_index = sym_idx;
3102 N_INCL_indexes.push_back(sym_idx);
3112 if (!N_INCL_indexes.empty()) {
3117 N_INCL_indexes.pop_back();
3152 symbol_section = section_info.
GetSection(nlist.n_sect,
3163 symbol_section = section_info.
GetSection(nlist.n_sect,
3165 N_BRAC_indexes.push_back(sym_idx);
3175 symbol_section = section_info.
GetSection(nlist.n_sect,
3177 if (!N_BRAC_indexes.empty()) {
3182 N_BRAC_indexes.pop_back();
3199 N_COMM_indexes.push_back(sym_idx);
3204 symbol_section = section_info.
GetSection(nlist.n_sect,
3215 if (!N_COMM_indexes.empty()) {
3220 N_COMM_indexes.pop_back();
3235 uint8_t n_type = N_TYPE & nlist.n_type;
3236 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3240 const char *reexport_name_cstr =
3241 strtab_data.PeekCStr(nlist.n_value);
3242 if (reexport_name_cstr && reexport_name_cstr[0]) {
3245 reexport_name_cstr +
3246 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3249 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3251 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3257 if (symbol_name && symbol_name[0]) {
3259 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3260 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3272 symbol_section = section_info.
GetSection(nlist.n_sect,
3275 if (symbol_section == NULL) {
3281 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3285 symbol_section->Get() & SECTION_TYPE;
3287 switch (section_type) {
3288 case S_CSTRING_LITERALS:
3291 case S_4BYTE_LITERALS:
3294 case S_8BYTE_LITERALS:
3297 case S_LITERAL_POINTERS:
3300 case S_NON_LAZY_SYMBOL_POINTERS:
3304 case S_LAZY_SYMBOL_POINTERS:
3307 case S_SYMBOL_STUBS:
3311 case S_MOD_INIT_FUNC_POINTERS:
3315 case S_MOD_TERM_FUNC_POINTERS:
3323 case S_16BYTE_LITERALS:
3329 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3333 switch (symbol_section->GetType()) {
3360 const char *symbol_sect_name =
3361 symbol_section->GetName().AsCString();
3362 if (symbol_section->IsDescendant(
3363 text_section_sp.get())) {
3364 if (symbol_section->IsClear(
3365 S_ATTR_PURE_INSTRUCTIONS |
3366 S_ATTR_SELF_MODIFYING_CODE |
3367 S_ATTR_SOME_INSTRUCTIONS))
3371 }
else if (symbol_section->IsDescendant(
3372 data_section_sp.get()) ||
3373 symbol_section->IsDescendant(
3374 data_dirty_section_sp.get()) ||
3375 symbol_section->IsDescendant(
3376 data_const_section_sp.get())) {
3377 if (symbol_sect_name &&
3378 ::strstr(symbol_sect_name,
"__objc") ==
3383 llvm::StringRef symbol_name_ref(symbol_name);
3384 if (symbol_name_ref.startswith(
"_OBJC_")) {
3386 g_objc_v2_prefix_class(
3389 g_objc_v2_prefix_metaclass(
3390 "_OBJC_METACLASS_$_");
3392 g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
3393 if (symbol_name_ref.startswith(
3394 g_objc_v2_prefix_class)) {
3395 symbol_name_non_abi_mangled =
3399 g_objc_v2_prefix_class.size();
3401 demangled_is_synthesized =
true;
3403 symbol_name_ref.startswith(
3404 g_objc_v2_prefix_metaclass)) {
3405 symbol_name_non_abi_mangled =
3409 g_objc_v2_prefix_metaclass.size();
3411 demangled_is_synthesized =
true;
3412 }
else if (symbol_name_ref.startswith(
3413 g_objc_v2_prefix_ivar)) {
3414 symbol_name_non_abi_mangled =
3418 g_objc_v2_prefix_ivar.size();
3420 demangled_is_synthesized =
true;
3424 }
else if (symbol_sect_name &&
3425 ::strstr(symbol_sect_name,
3426 "__gcc_except_tab") ==
3432 }
else if (symbol_sect_name &&
3433 ::strstr(symbol_sect_name,
"__IMPORT") ==
3436 }
else if (symbol_section->IsDescendant(
3437 objc_section_sp.get())) {
3439 if (symbol_name && symbol_name[0] ==
'.') {
3440 llvm::StringRef symbol_name_ref(symbol_name);
3442 g_objc_v1_prefix_class(
".objc_class_name_");
3443 if (symbol_name_ref.startswith(
3444 g_objc_v1_prefix_class)) {
3445 symbol_name_non_abi_mangled = symbol_name;
3446 symbol_name = symbol_name +
3447 g_objc_v1_prefix_class.size();
3449 demangled_is_synthesized =
true;
3460 uint64_t symbol_value = nlist.n_value;
3461 if (symbol_name_non_abi_mangled) {
3467 bool symbol_name_is_mangled =
false;
3469 if (symbol_name && symbol_name[0] ==
'_') {
3470 symbol_name_is_mangled = symbol_name[1] ==
'_';
3477 const_symbol_name, symbol_name_is_mangled);
3478 if (is_gsym && is_debug) {
3479 const char *gsym_name =
3482 .GetName(Mangled::ePreferMangled)
3485 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3489 if (symbol_section) {
3490 const addr_t section_file_addr =
3491 symbol_section->GetFileAddress();
3492 if (symbol_byte_size == 0 &&
3493 function_starts_count > 0) {
3494 addr_t symbol_lookup_file_addr = nlist.n_value;
3500 function_starts.FindEntry(symbol_lookup_file_addr,
3502 if (is_arm && func_start_entry) {
3506 if (func_start_entry->addr !=
3507 symbol_lookup_file_addr &&
3508 func_start_entry->addr !=
3509 (symbol_lookup_file_addr + 1)) {
3511 func_start_entry = NULL;
3514 if (func_start_entry) {
3515 func_start_entry->data =
true;
3517 addr_t symbol_file_addr = func_start_entry->addr;
3520 if (symbol_file_addr & 1)
3526 function_starts.FindNextEntry(func_start_entry);
3527 const addr_t section_end_file_addr =
3529 symbol_section->GetByteSize();
3530 if (next_func_start_entry) {
3531 addr_t next_symbol_file_addr =
3532 next_func_start_entry->addr;
3538 symbol_byte_size = std::min<lldb::addr_t>(
3539 next_symbol_file_addr - symbol_file_addr,
3540 section_end_file_addr - symbol_file_addr);
3543 section_end_file_addr - symbol_file_addr;
3547 symbol_value -= section_file_addr;
3550 if (is_debug ==
false) {
3558 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3559 if (range.first != range.second) {
3560 bool found_it =
false;
3561 for (
auto pos = range.first; pos != range.second;
3563 if (sym[sym_idx].GetMangled().
GetName(
3564 Mangled::ePreferMangled) ==
3566 Mangled::ePreferMangled)) {
3567 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3573 sym[sym_idx].IsExternal());
3574 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3576 if (resolver_addresses.find(nlist.n_value) !=
3577 resolver_addresses.end())
3579 sym[sym_idx].
Clear();
3587 if (resolver_addresses.find(nlist.n_value) !=
3588 resolver_addresses.end())
3600 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3602 if (range.first != range.second) {
3603 bool found_it =
false;
3604 for (
auto pos = range.first; pos != range.second;
3606 if (sym[sym_idx].GetMangled().
GetName(
3607 Mangled::ePreferMangled) ==
3609 Mangled::ePreferMangled)) {
3610 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3616 sym[sym_idx].IsExternal());
3617 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3619 sym[sym_idx].
Clear();
3627 const char *gsym_name =
3630 .GetName(Mangled::ePreferMangled)
3635 ConstNameToSymbolIndexMap::const_iterator pos =
3636 N_GSYM_name_to_sym_idx.find(gsym_name);
3637 if (pos != N_GSYM_name_to_sym_idx.end()) {
3638 const uint32_t GSYM_sym_idx = pos->second;
3639 m_nlist_idx_to_sym_idx[nlist_idx] =
3648 add_symbol_addr(sym[GSYM_sym_idx]
3655 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3657 sym[sym_idx].
Clear();
3665 sym[sym_idx].
SetID(nlist_idx);
3671 sym[sym_idx].GetAddress().GetFileAddress());
3673 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3675 if (symbol_byte_size > 0)
3678 if (demangled_is_synthesized)
3682 sym[sym_idx].
Clear();
3689 for (
const auto &pos : reexport_shlib_needs_fixup) {
3690 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3691 if (undef_pos != undefined_name_to_desc.end()) {
3692 const uint8_t dylib_ordinal =
3693 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3694 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
3696 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
3704 if (nlist_data.GetByteSize() > 0) {
3708 if (sym ==
nullptr) {
3714 if (unmapped_local_symbols_found) {
3716 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3722 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3723 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3724 UndefinedNameToDescMap undefined_name_to_desc;
3725 SymbolIndexToName reexport_shlib_needs_fixup;
3733 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist,
uint32_t nlist_idx,
3735 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3736 if (is_debug != debug_only)
3739 const char *symbol_name_non_abi_mangled =
nullptr;
3740 const char *symbol_name =
nullptr;
3742 if (have_strtab_data) {
3743 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3745 if (symbol_name ==
nullptr) {
3748 Debugger::ReportError(llvm::formatv(
3749 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3751 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3754 if (symbol_name[0] ==
'\0')
3755 symbol_name =
nullptr;
3757 const addr_t str_addr = strtab_addr + nlist.n_strx;
3759 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3761 symbol_name = memory_symbol_name.c_str();
3765 SectionSP symbol_section;
3767 bool add_nlist =
true;
3768 bool is_gsym =
false;
3769 bool demangled_is_synthesized =
false;
3770 bool set_value =
true;
3772 assert(sym_idx < num_syms);
3776 switch (nlist.n_type) {
3793 if (symbol_name && symbol_name[0] ==
'_' && symbol_name[1] ==
'O') {
3794 llvm::StringRef symbol_name_ref(symbol_name);
3795 if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
3796 symbol_name_non_abi_mangled = symbol_name + 1;
3797 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3799 demangled_is_synthesized =
true;
3801 }
else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) {
3802 symbol_name_non_abi_mangled = symbol_name + 1;
3803 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3805 demangled_is_synthesized =
true;
3806 }
else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) {
3807 symbol_name_non_abi_mangled = symbol_name + 1;
3808 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3810 demangled_is_synthesized =
true;
3813 if (nlist.n_value != 0)
3815 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3830 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3832 N_FUN_addr_to_sym_idx.insert(
3833 std::make_pair(nlist.n_value, sym_idx));
3837 N_FUN_indexes.push_back(sym_idx);
3841 if (!N_FUN_indexes.empty()) {
3846 N_FUN_indexes.pop_back();
3857 N_STSYM_addr_to_sym_idx.insert(
3858 std::make_pair(nlist.n_value, sym_idx));
3859 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3860 if (symbol_name && symbol_name[0]) {
3861 type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,
3868 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3899 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3911 if (symbol_name ==
nullptr) {
3922 N_NSYM_indexes.clear();
3923 N_INCL_indexes.clear();
3924 N_BRAC_indexes.clear();
3925 N_COMM_indexes.clear();
3926 N_FUN_indexes.clear();
3932 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3933 if (N_SO_has_full_path) {
3934 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3939 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3944 N_SO_index = sym_idx;
3946 }
else if ((N_SO_index == sym_idx - 1) &&
3947 ((sym_idx - 1) < num_syms)) {
3951 const char *so_path =
3952 sym[sym_idx - 1].
GetMangled().GetDemangledName().AsCString();
3953 if (so_path && so_path[0]) {
3955 const size_t double_slash_pos = full_so_path.find(
"//");
3956 if (double_slash_pos != std::string::npos) {
3963 if (!FileSystem::Instance().Exists(so_dir)) {
3964 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3965 FileSpec::Style::native);
3966 if (FileSystem::Instance().Exists(so_dir)) {
3968 full_so_path.erase(0, double_slash_pos + 1);
3972 if (*full_so_path.rbegin() !=
'/')
3973 full_so_path +=
'/';
3974 full_so_path += symbol_name;
3978 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3982 N_SO_index = sym_idx;
4002 N_INCL_indexes.push_back(sym_idx);
4011 if (!N_INCL_indexes.empty()) {
4015 N_INCL_indexes.pop_back();
4050 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4059 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4060 N_BRAC_indexes.push_back(sym_idx);
4069 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4070 if (!N_BRAC_indexes.empty()) {
4074 N_BRAC_indexes.pop_back();
4090 N_COMM_indexes.push_back(sym_idx);
4095 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4104 if (!N_COMM_indexes.empty()) {
4108 N_COMM_indexes.pop_back();
4122 uint8_t n_type = N_TYPE & nlist.n_type;
4123 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
4127 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4128 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
4131 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
4134 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4135 indirect_symbol_names.insert(
4136 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
4142 if (symbol_name && symbol_name[0]) {
4144 ((symbol_name[0] ==
'_') ? 1 : 0));
4145 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4158 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4160 if (!symbol_section) {
4166 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4169 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4171 switch (section_type) {
4172 case S_CSTRING_LITERALS:
4175 case S_4BYTE_LITERALS:
4178 case S_8BYTE_LITERALS:
4181 case S_LITERAL_POINTERS:
4184 case S_NON_LAZY_SYMBOL_POINTERS:
4187 case S_LAZY_SYMBOL_POINTERS:
4190 case S_SYMBOL_STUBS:
4194 case S_MOD_INIT_FUNC_POINTERS:
4197 case S_MOD_TERM_FUNC_POINTERS:
4204 case S_16BYTE_LITERALS:
4210 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4214 switch (symbol_section->GetType()) {
4236 const char *symbol_sect_name =
4237 symbol_section->GetName().AsCString();
4238 if (symbol_section->IsDescendant(text_section_sp.get())) {
4239 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4240 S_ATTR_SELF_MODIFYING_CODE |
4241 S_ATTR_SOME_INSTRUCTIONS))
4245 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4246 symbol_section->IsDescendant(
4247 data_dirty_section_sp.get()) ||
4248 symbol_section->IsDescendant(
4249 data_const_section_sp.get())) {
4250 if (symbol_sect_name &&
4251 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4255 llvm::StringRef symbol_name_ref(symbol_name);
4256 if (symbol_name_ref.startswith(
"_OBJC_")) {
4257 llvm::StringRef g_objc_v2_prefix_class(
4259 llvm::StringRef g_objc_v2_prefix_metaclass(
4260 "_OBJC_METACLASS_$_");
4261 llvm::StringRef g_objc_v2_prefix_ivar(
4263 if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
4264 symbol_name_non_abi_mangled = symbol_name + 1;
4266 symbol_name + g_objc_v2_prefix_class.size();
4268 demangled_is_synthesized =
true;
4269 }
else if (symbol_name_ref.startswith(
4270 g_objc_v2_prefix_metaclass)) {
4271 symbol_name_non_abi_mangled = symbol_name + 1;
4273 symbol_name + g_objc_v2_prefix_metaclass.size();
4275 demangled_is_synthesized =
true;
4276 }
else if (symbol_name_ref.startswith(
4277 g_objc_v2_prefix_ivar)) {
4278 symbol_name_non_abi_mangled = symbol_name + 1;
4280 symbol_name + g_objc_v2_prefix_ivar.size();
4282 demangled_is_synthesized =
true;
4286 }
else if (symbol_sect_name &&
4287 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4293 }
else if (symbol_sect_name &&
4294 ::strstr(symbol_sect_name,
"__IMPORT") ==
4297 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4299 if (symbol_name && symbol_name[0] ==
'.') {
4300 llvm::StringRef symbol_name_ref(symbol_name);
4301 llvm::StringRef g_objc_v1_prefix_class(
4302 ".objc_class_name_");
4303 if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) {
4304 symbol_name_non_abi_mangled = symbol_name;
4305 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4307 demangled_is_synthesized =
true;
4318 sym[sym_idx].
Clear();
4322 uint64_t symbol_value = nlist.n_value;
4324 if (symbol_name_non_abi_mangled) {
4329 bool symbol_name_is_mangled =
false;
4331 if (symbol_name && symbol_name[0] ==
'_') {
4332 symbol_name_is_mangled = symbol_name[1] ==
'_';
4338 sym[sym_idx].
GetMangled().SetValue(const_symbol_name,
4339 symbol_name_is_mangled);
4344 const char *gsym_name = sym[sym_idx]
4346 .GetName(Mangled::ePreferMangled)
4349 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4352 if (symbol_section) {
4353 const addr_t section_file_addr = symbol_section->GetFileAddress();
4354 if (symbol_byte_size == 0 && function_starts_count > 0) {
4355 addr_t symbol_lookup_file_addr = nlist.n_value;
4360 function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
4361 if (is_arm && func_start_entry) {
4364 if (func_start_entry->addr != symbol_lookup_file_addr &&
4365 func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
4367 func_start_entry =
nullptr;
4370 if (func_start_entry) {
4371 func_start_entry->data =
true;
4373 addr_t symbol_file_addr = func_start_entry->addr;
4378 function_starts.FindNextEntry(func_start_entry);
4379 const addr_t section_end_file_addr =
4380 section_file_addr + symbol_section->GetByteSize();
4381 if (next_func_start_entry) {
4382 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4387 symbol_byte_size = std::min<lldb::addr_t>(
4388 next_symbol_file_addr - symbol_file_addr,
4389 section_end_file_addr - symbol_file_addr);
4391 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4395 symbol_value -= section_file_addr;
4404 std::pair<ValueToSymbolIndexMap::const_iterator,
4405 ValueToSymbolIndexMap::const_iterator>
4407 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4408 if (range.first != range.second) {
4409 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4410 pos != range.second; ++pos) {
4411 if (sym[sym_idx].GetMangled().
GetName(Mangled::ePreferMangled) ==
4413 Mangled::ePreferMangled)) {
4414 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4418 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4419 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4420 if (resolver_addresses.find(nlist.n_value) !=
4421 resolver_addresses.end())
4423 sym[sym_idx].
Clear();
4428 if (resolver_addresses.find(nlist.n_value) !=
4429 resolver_addresses.end())
4439 std::pair<ValueToSymbolIndexMap::const_iterator,
4440 ValueToSymbolIndexMap::const_iterator>
4442 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4443 if (range.first != range.second) {
4444 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4445 pos != range.second; ++pos) {
4446 if (sym[sym_idx].GetMangled().
GetName(Mangled::ePreferMangled) ==
4448 Mangled::ePreferMangled)) {
4449 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4453 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4454 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4455 sym[sym_idx].
Clear();
4461 const char *gsym_name = sym[sym_idx]
4463 .GetName(Mangled::ePreferMangled)
4466 ConstNameToSymbolIndexMap::const_iterator pos =
4467 N_GSYM_name_to_sym_idx.find(gsym_name);
4468 if (pos != N_GSYM_name_to_sym_idx.end()) {
4469 const uint32_t GSYM_sym_idx = pos->second;
4470 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4476 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4480 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4481 sym[sym_idx].
Clear();
4489 sym[sym_idx].
SetID(nlist_idx);
4495 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4497 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4498 if (nlist.n_desc & N_WEAK_REF)
4501 if (symbol_byte_size > 0)
4504 if (demangled_is_synthesized)
4513 std::vector<struct nlist_64> nlists;
4514 nlists.reserve(symtab_load_command.nsyms);
4515 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4517 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4518 nlists.push_back(*nlist);
4528 for (
auto &nlist : nlists) {
4529 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4535 for (
auto &nlist : nlists) {
4540 for (
const auto &pos : reexport_shlib_needs_fixup) {
4541 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4542 if (undef_pos != undefined_name_to_desc.end()) {
4543 const uint8_t dylib_ordinal =
4544 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4545 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4547 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4553 int trie_symbol_table_augment_count = 0;
4554 for (
auto &e : external_sym_trie_entries) {
4555 if (symbols_added.find(e.entry.address) == symbols_added.end())
4556 trie_symbol_table_augment_count++;
4559 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4560 num_syms = sym_idx + trie_symbol_table_augment_count;
4561 sym = symtab.
Resize(num_syms);
4563 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4566 for (
auto &e : external_sym_trie_entries) {
4567 if (symbols_added.contains(e.entry.address))
4573 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4574 SectionSP symbol_section(symbol_addr.
GetSection());
4575 const char *symbol_name = e.entry.name.GetCString();
4576 bool demangled_is_synthesized =
false;
4578 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4579 data_section_sp, data_dirty_section_sp,
4580 data_const_section_sp, symbol_section);
4583 if (symbol_section) {
4584 sym[sym_idx].
SetID(synthetic_sym_id++);
4586 if (demangled_is_synthesized)
4599 if (function_starts_count > 0) {
4600 uint32_t num_synthetic_function_symbols = 0;
4601 for (i = 0; i < function_starts_count; ++i) {
4602 if (symbols_added.find(function_starts.GetEntryRef(i).addr) ==
4603 symbols_added.end())
4604 ++num_synthetic_function_symbols;
4607 if (num_synthetic_function_symbols > 0) {
4608 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4609 num_syms = sym_idx + num_synthetic_function_symbols;
4610 sym = symtab.
Resize(num_syms);
4612 for (i = 0; i < function_starts_count; ++i) {
4614 function_starts.GetEntryAtIndex(i);
4615 if (symbols_added.find(func_start_entry->addr) == symbols_added.end()) {
4616 addr_t symbol_file_addr = func_start_entry->addr;
4618 if (func_start_entry->data)
4621 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4622 SectionSP symbol_section(symbol_addr.
GetSection());
4624 if (symbol_section) {
4625 const addr_t section_file_addr = symbol_section->GetFileAddress();
4627 function_starts.FindNextEntry(func_start_entry);
4628 const addr_t section_end_file_addr =
4629 section_file_addr + symbol_section->GetByteSize();
4630 if (next_func_start_entry) {
4631 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4634 symbol_byte_size = std::min<lldb::addr_t>(
4635 next_symbol_file_addr - symbol_file_addr,
4636 section_end_file_addr - symbol_file_addr);
4638 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4640 sym[sym_idx].
SetID(synthetic_sym_id++);
4650 sym[sym_idx].
SetFlags(symbol_flags);
4651 if (symbol_byte_size)
4663 if (sym_idx < num_syms) {
4665 sym = symtab.
Resize(num_syms);
4670 if (indirect_symbol_index_data.GetByteSize()) {
4671 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4672 m_nlist_idx_to_sym_idx.end();
4679 if (symbol_stub_byte_size == 0)
4685 if (num_symbol_stubs == 0)
4688 const uint32_t symbol_stub_index_offset =
4690 for (
uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4692 symbol_stub_index_offset + stub_idx;
4695 (stub_idx * symbol_stub_byte_size);
4697 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4698 symbol_stub_offset, 4)) {
4700 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4701 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4704 NListIndexToSymbolIndexMap::const_iterator index_pos =
4705 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4706 Symbol *stub_symbol =
nullptr;
4707 if (index_pos != end_index_pos) {
4718 Address so_addr(symbol_stub_addr, section_list);
4725 if (resolver_addresses.find(symbol_stub_addr) ==
4726 resolver_addresses.end())
4735 Mangled stub_symbol_mangled_name(stub_symbol->
GetMangled());
4736 if (sym_idx >= num_syms) {
4737 sym = symtab.
Resize(++num_syms);
4738 stub_symbol =
nullptr;
4740 sym[sym_idx].
SetID(synthetic_sym_id++);
4741 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4742 if (resolver_addresses.find(symbol_stub_addr) ==
4743 resolver_addresses.end())
4755 log->
Warning(
"symbol stub referencing symbol table symbol "
4756 "%u that isn't in our minimal symbol table, "
4767 if (!reexport_trie_entries.empty()) {
4768 for (
const auto &e : reexport_trie_entries) {
4769 if (e.entry.import_name) {
4772 if (indirect_symbol_names.find(e.entry.name) ==
4773 indirect_symbol_names.end()) {
4775 if (sym_idx >= num_syms)
4776 sym = symtab.
Resize(++num_syms);
4777 sym[sym_idx].
SetID(synthetic_sym_id++);
4778 sym[sym_idx].
GetMangled() = Mangled(e.entry.name);
4782 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4784 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
4796 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4797 s->
Printf(
"%p: ",
static_cast<void *
>(
this));
4804 *s <<
", file = '" <<
m_file;
4808 base_spec, all_specs);
4809 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
4834 llvm::MachO::uuid_command load_cmd;
4837 for (i = 0; i < header.ncmds; ++i) {
4839 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
4842 if (load_cmd.cmd == LC_UUID) {
4843 const uint8_t *uuid_bytes = data.
PeekData(offset, 16);
4849 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4850 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4851 0xbb, 0x14, 0xf0, 0x0d};
4853 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4856 return UUID(uuid_bytes, 16);
4860 offset = cmd_offset + load_cmd.cmdsize;
4867 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4868 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4869 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4870 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4871 case llvm::MachO::LC_VERSION_MIN_TVOS:
4872 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4873 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4874 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4876 llvm_unreachable(
"unexpected LC_VERSION load command");
4882 llvm::StringRef os_type;
4883 llvm::StringRef environment;
4886 case llvm::MachO::PLATFORM_MACOS:
4887 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4889 case llvm::MachO::PLATFORM_IOS:
4890 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4892 case llvm::MachO::PLATFORM_TVOS:
4893 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4895 case llvm::MachO::PLATFORM_WATCHOS:
4896 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4906 case llvm::MachO::PLATFORM_MACCATALYST:
4907 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4908 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
4910 case llvm::MachO::PLATFORM_IOSSIMULATOR:
4911 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4913 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4915 case llvm::MachO::PLATFORM_TVOSSIMULATOR:
4916 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4918 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4920 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
4921 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4923 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4926 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
4927 LLDB_LOGF(log,
"unsupported platform in LC_BUILD_VERSION");
4934 uint32_t major_version, minor_version, patch_version;
4936 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),
4937 patch_version(version & 0xffu) {}
4948 if (!base_arch.IsValid())
4951 bool found_any =
false;
4952 auto add_triple = [&](
const llvm::Triple &triple) {
4953 auto spec = base_spec;
4955 if (spec.GetArchitecture().IsValid()) {
4963 llvm::Triple base_triple = base_arch.GetTriple();
4964 base_triple.setOS(llvm::Triple::UnknownOS);
4965 base_triple.setOSName(llvm::StringRef());
4967 if (header.filetype == MH_PRELOAD) {
4968 if (header.cputype == CPU_TYPE_ARM) {
4974 base_triple.setVendor(llvm::Triple::Apple);
4979 base_triple.setVendor(llvm::Triple::UnknownVendor);
4980 base_triple.setVendorName(llvm::StringRef());
4982 return add_triple(base_triple);
4985 llvm::MachO::load_command load_cmd;
4990 for (
uint32_t i = 0; i < header.ncmds; ++i) {
4992 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
4995 llvm::MachO::version_min_command version_min;
4996 switch (load_cmd.cmd) {
4997 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4998 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4999 case llvm::MachO::LC_VERSION_MIN_TVOS:
5000 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
5001 if (load_cmd.cmdsize !=
sizeof(version_min))
5006 MinOS min_os(version_min.version);
5007 llvm::SmallString<32> os_name;
5008 llvm::raw_svector_ostream os(os_name);
5009 os <<
GetOSName(load_cmd.cmd) << min_os.major_version <<
'.'
5010 << min_os.minor_version <<
'.' << min_os.patch_version;
5012 auto triple = base_triple;
5013 triple.setOSName(os.str());
5016 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
5017 (base_triple.getArch() == llvm::Triple::x86_64 ||
5018 base_triple.getArch() == llvm::Triple::x86)) {
5025 triple.setEnvironment(llvm::Triple::Simulator);
5034 offset = cmd_offset + load_cmd.cmdsize;
5040 for (
uint32_t i = 0; i < header.ncmds; ++i) {
5042 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
5046 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
5047 llvm::MachO::build_version_command build_version;
5048 if (load_cmd.cmdsize <
sizeof(build_version)) {
5052 if (data.
ExtractBytes(cmd_offset,
sizeof(build_version),
5055 MinOS min_os(build_version.minos);
5056 OSEnv os_env(build_version.platform);
5057 llvm::SmallString<16> os_name;
5058 llvm::raw_svector_ostream os(os_name);
5059 os << os_env.os_type << min_os.major_version <<
'.'
5060 << min_os.minor_version <<
'.' << min_os.patch_version;
5061 auto triple = base_triple;
5062 triple.setOSName(os.str());
5064 if (!os_env.environment.empty())
5065 triple.setEnvironmentName(os_env.environment);
5069 offset = cmd_offset + load_cmd.cmdsize;
5073 add_triple(base_triple);
5078 ModuleSP module_sp,
const llvm::MachO::mach_header &header,
5083 base_spec, all_specs);
5088 const ArchSpec &module_arch = module_sp->GetArchitecture();
5089 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
5106 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5117 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5118 llvm::MachO::load_command load_cmd;
5120 std::vector<std::string> rpath_paths;
5121 std::vector<std::string> rpath_relative_paths;
5122 std::vector<std::string> at_exec_relative_paths;
5124 for (i = 0; i <
m_header.ncmds; ++i) {
5125 const uint32_t cmd_offset = offset;
5129 switch (load_cmd.cmd) {
5132 case LC_LOAD_WEAK_DYLIB:
5133 case LC_REEXPORT_DYLIB:
5134 case LC_LOAD_DYLINKER:
5136 case LC_LOAD_UPWARD_DYLIB: {
5140 if (load_cmd.cmd == LC_RPATH)
5141 rpath_paths.push_back(path);
5143 if (path[0] ==
'@') {
5144 if (strncmp(path,
"@rpath", strlen(
"@rpath")) == 0)
5145 rpath_relative_paths.push_back(path + strlen(
"@rpath"));
5146 else if (strncmp(path,
"@executable_path",
5147 strlen(
"@executable_path")) == 0)
5148 at_exec_relative_paths.push_back(path +
5149 strlen(
"@executable_path"));
5152 if (files.AppendIfUnique(file_spec))
5162 offset = cmd_offset + load_cmd.cmdsize;
5166 FileSystem::Instance().Resolve(this_file_spec);
5168 if (!rpath_paths.empty()) {
5172 for (
auto &rpath : rpath_paths) {
5173 if (llvm::StringRef(rpath).startswith(loader_path)) {
5174 rpath.erase(0, loader_path.size());
5176 }
else if (llvm::StringRef(rpath).startswith(executable_path)) {
5177 rpath.erase(0, executable_path.size());
5182 for (
const auto &rpath_relative_path : rpath_relative_paths) {
5183 for (
const auto &rpath : rpath_paths) {
5185 path += rpath_relative_path;
5189 FileSystem::Instance().Resolve(file_spec);
5190 if (FileSystem::Instance().Exists(file_spec) &&
5191 files.AppendIfUnique(file_spec)) {
5205 for (
const auto &at_exec_relative_path : at_exec_relative_paths) {
5208 if (FileSystem::Instance().Exists(file_spec) &&
5209 files.AppendIfUnique(file_spec))
5253 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5254 llvm::MachO::load_command load_cmd;
5260 for (i = 0; i <
m_header.ncmds; ++i) {
5265 switch (load_cmd.cmd) {
5268 while (offset < cmd_offset + load_cmd.cmdsize) {
5277 case llvm::MachO::CPU_TYPE_ARM:
5298 case llvm::MachO::CPU_TYPE_I386:
5308 case llvm::MachO::CPU_TYPE_X86_64:
5325 offset += count * 4;
5331 SectionSP text_segment_sp =
5333 if (text_segment_sp) {
5335 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5346 offset = cmd_offset + load_cmd.cmdsize;
5353 Symtab::eDebugAny, Symtab::eVisibilityAny);
5376 module_sp->FindSymbolsWithNameAndType(
ConstString(
"start"),
5393 SectionSP text_segment_sp(
5395 if (text_segment_sp) {
5406 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5411 llvm::MachO::thread_command thread_cmd;
5413 const uint32_t cmd_offset = offset;
5417 if (thread_cmd.cmd == LC_THREAD) {
5422 offset = cmd_offset + thread_cmd.cmdsize;
5433 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5439 const uint32_t cmd_offset = offset;
5440 llvm::MachO::load_command lc = {};
5443 if (lc.cmd == LC_NOTE) {
5444 char data_owner[17];
5446 data_owner[16] =
'\0';
5453 if (strcmp(
"kern ver str", data_owner) == 0) {
5459 char *buf = (
char *)malloc(strsize);
5462 buf[strsize - 1] =
'\0';
5472 offset = cmd_offset + lc.cmdsize;
5479 const uint32_t cmd_offset = offset;
5480 llvm::MachO::ident_command ident_command;
5481 if (
m_data.
GetU32(&offset, &ident_command, 2) ==
nullptr)
5483 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
5484 char *buf = (
char *)malloc(ident_command.cmdsize);
5485 if (buf !=
nullptr &&
m_data.
CopyData(offset, ident_command.cmdsize,
5486 buf) == ident_command.cmdsize) {
5487 buf[ident_command.cmdsize - 1] =
'\0';
5493 offset = cmd_offset + ident_command.cmdsize;
5503 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5506 const uint32_t cmd_offset = offset;
5507 llvm::MachO::load_command lc = {};
5510 if (lc.cmd == LC_NOTE) {
5511 char data_owner[17];
5513 data_owner[16] =
'\0';
5519 if (strcmp(
"addrable bits", data_owner) == 0) {
5525 if (num_addr_bits != 0) {
5526 mask = ~((1ULL << num_addr_bits) - 1);
5533 offset = cmd_offset + lc.cmdsize;
5540 bool &value_is_offset,
5544 value_is_offset =
false;
5550 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5553 const uint32_t cmd_offset = offset;
5554 llvm::MachO::load_command lc = {};
5557 if (lc.cmd == LC_NOTE) {
5558 char data_owner[17];
5559 memset(data_owner, 0,
sizeof(data_owner));
5597 if (strcmp(
"main bin spec", data_owner) == 0 && size >= 32) {
5600 if (
m_data.
GetU32(&offset, &version, 1) !=
nullptr && version <= 2) {
5603 memset(raw_uuid, 0,
sizeof(
uuid_t));
5615 value_is_offset =
true;
5622 switch (binspec_type) {
5638 if (version > 1 && !
m_data.
GetU32(&offset, &platform, 1))
5645 offset = cmd_offset + lc.cmdsize;
5651 lldb::RegisterContextSP
5654 lldb::RegisterContextSP reg_ctx_sp;
5658 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5664 if (thread_context_file_range) {
5673 std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);
5676 case llvm::MachO::CPU_TYPE_ARM:
5678 std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);
5681 case llvm::MachO::CPU_TYPE_I386:
5683 std::make_shared<RegisterContextDarwin_i386_Mach>(thread, data);
5686 case llvm::MachO::CPU_TYPE_X86_64:
5688 std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);