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"
57#include <TargetConditionals.h>
60#include <mach/mach_init.h>
61#include <mach/vm_map.h>
82#ifdef CPU_TYPE_ARM64_32
83#undef CPU_TYPE_ARM64_32
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
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
140using namespace llvm::MachO;
145 const
char *alt_name,
size_t reg_byte_size,
147 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
148 if (reg_info ==
nullptr)
149 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
152 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
153 if (reg_info->byte_size >= reg_byte_size)
154 data.Write(reg_value.
GetBytes(), reg_byte_size);
156 data.Write(reg_value.
GetBytes(), reg_info->byte_size);
157 for (
size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n; ++i)
164 for (
size_t i = 0; i < reg_byte_size; ++i)
188 int flavor = data.
GetU32(&offset);
196 for (i = 0; i < count; ++i)
393 int flavor = data.
GetU32(&offset);
401 for (i = 0; i < count; ++i)
509 int flavor = data.
GetU32(&offset);
517 if (count == gpr_buf_count) {
518 for (
uint32_t i = 0; i < (count - 1); ++i) {
526 offset = next_thread_state;
530 uint8_t *fpu_reg_buf = (uint8_t *)&
fpu.
floats;
531 const int fpu_reg_buf_size =
sizeof(
fpu.
floats);
533 fpu_reg_buf) == fpu_reg_buf_size) {
534 offset += fpu_reg_buf_size;
541 offset = next_thread_state;
552 offset = next_thread_state;
643 int flavor = data.
GetU32(&offset);
650 if (count >= (33 * 2) + 1) {
660 offset = next_thread_state;
663 uint8_t *fpu_reg_buf = (uint8_t *)&
fpu.
v[0];
664 const int fpu_reg_buf_size =
sizeof(
fpu);
665 if (fpu_reg_buf_size == count *
sizeof(
uint32_t) &&
667 fpu_reg_buf) == fpu_reg_buf_size) {
673 offset = next_thread_state;
682 offset = next_thread_state;
775 return sizeof(
struct llvm::MachO::mach_header);
779 return sizeof(
struct llvm::MachO::mach_header_64);
788#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
803 DataBufferSP data_sp,
819 if (data_sp->GetByteSize() < length) {
825 auto objfile_up = std::make_unique<ObjectFileMachO>(
826 module_sp, data_sp, data_offset, file, file_offset, length);
827 if (!objfile_up || !objfile_up->ParseHeader())
830 return objfile_up.release();
834 const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
835 const ProcessSP &process_sp,
lldb::addr_t header_addr) {
837 std::unique_ptr<ObjectFile> objfile_up(
839 if (objfile_up.get() && objfile_up->ParseHeader())
840 return objfile_up.release();
849 const size_t initial_count = specs.
GetSize();
854 llvm::MachO::mach_header header;
856 size_t header_and_load_cmds =
858 if (header_and_load_cmds >= data_sp->GetByteSize()) {
859 data_sp =
MapFileData(file, header_and_load_cmds, file_offset);
872 return specs.
GetSize() - initial_count;
877 return g_segment_name_TEXT;
882 return g_segment_name_DATA;
887 return g_segment_name;
892 return g_segment_name;
897 return g_segment_name_OBJC;
901 static ConstString g_section_name_LINKEDIT(
"__LINKEDIT");
902 return g_section_name_LINKEDIT;
907 return g_section_name;
911 static ConstString g_section_name_eh_frame(
"__eh_frame");
912 return g_section_name_eh_frame;
919 data.
SetData(data_sp, data_offset, data_length);
930 if (filetype == llvm::MachO::MH_FILESET)
937 DataBufferSP data_sp,
942 :
ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
943 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
944 m_thread_context_offsets_valid(false), m_reexported_dylibs(),
945 m_allow_assembly_emulation_unwind_plans(true) {
951 lldb::WritableDataBufferSP header_data_sp,
952 const lldb::ProcessSP &process_sp,
954 :
ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
955 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
956 m_thread_context_offsets_valid(false), m_reexported_dylibs(),
957 m_allow_assembly_emulation_unwind_plans(true) {
964 llvm::MachO::mach_header &header) {
967 header.magic = data.
GetU32(data_offset_ptr);
968 bool can_parse =
false;
969 bool is_64_bit =
false;
970 switch (header.magic) {
1006 data.
GetU32(data_offset_ptr, &header.cputype, 6);
1008 *data_offset_ptr += 4;
1011 memset(&header, 0,
sizeof(header));
1021 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1022 bool can_parse =
false;
1066 base_spec, all_specs);
1068 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
1073 const ArchSpec &module_arch = module_sp->GetArchitecture();
1078 const size_t header_and_lc_size =
1081 DataBufferSP data_sp;
1088 if (data_sp->GetByteSize() != header_and_lc_size)
1100 memset(&
m_header, 0,
sizeof(
struct llvm::MachO::mach_header));
1110 return m_header.filetype == MH_EXECUTE;
1114 return m_header.filetype == MH_DYLINKER;
1118 return m_header.flags & MH_DYLIB_IN_CACHE;
1122 return m_header.filetype == MH_KEXT_BUNDLE;
1132 return AddressClass::eUnknown;
1140 switch (section_type) {
1142 return AddressClass::eUnknown;
1145 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1149 return AddressClass::eCodeAlternateISA;
1151 return AddressClass::eCode;
1154 return AddressClass::eUnknown;
1168 return AddressClass::eData;
1205 return AddressClass::eDebug;
1211 return AddressClass::eRuntime;
1219 return AddressClass::eUnknown;
1225 switch (symbol_type) {
1227 return AddressClass::eUnknown;
1229 return AddressClass::eUnknown;
1234 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1238 return AddressClass::eCodeAlternateISA;
1240 return AddressClass::eCode;
1243 return AddressClass::eData;
1245 return AddressClass::eRuntime;
1247 return AddressClass::eRuntime;
1249 return AddressClass::eDebug;
1251 return AddressClass::eDebug;
1253 return AddressClass::eDebug;
1255 return AddressClass::eDebug;
1257 return AddressClass::eDebug;
1259 return AddressClass::eData;
1261 return AddressClass::eData;
1263 return AddressClass::eData;
1265 return AddressClass::eDebug;
1267 return AddressClass::eDebug;
1269 return AddressClass::eDebug;
1271 return AddressClass::eDebug;
1273 return AddressClass::eDebug;
1275 return AddressClass::eUnknown;
1277 return AddressClass::eDebug;
1279 return AddressClass::eDebug;
1281 return AddressClass::eUnknown;
1283 return AddressClass::eRuntime;
1285 return AddressClass::eRuntime;
1287 return AddressClass::eRuntime;
1289 return AddressClass::eRuntime;
1292 return AddressClass::eUnknown;
1303 llvm::MachO::load_command lc = {};
1306 if (lc.cmd == LC_DYSYMTAB) {
1317 offset = load_cmd_offset + lc.cmdsize;
1330 llvm::MachO::encryption_info_command encryption_cmd;
1333 if (
m_data.
GetU32(&offset, &encryption_cmd, 2) ==
nullptr)
1338 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
1339 encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
1340 if (
m_data.
GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
1341 if (encryption_cmd.cryptid != 0) {
1349 offset = load_cmd_offset + encryption_cmd.cmdsize;
1356 llvm::MachO::segment_command_64 &seg_cmd,
uint32_t cmd_idx) {
1357 if (
m_length == 0 || seg_cmd.filesize == 0)
1366 sizeof(seg_cmd.segname)) == 0)
1369 sizeof(seg_cmd.segname)) == 0)
1382 const char *lc_segment_name =
1383 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1385 "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "
1386 "the end of the file ({3:x16}), ignoring this section",
1387 cmd_idx, lc_segment_name, seg_cmd.fileoff,
m_length);
1389 seg_cmd.fileoff = 0;
1390 seg_cmd.filesize = 0;
1393 if (seg_cmd.fileoff + seg_cmd.filesize >
m_length) {
1400 const char *lc_segment_name =
1401 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1403 "load command {0} {1} has a fileoff + filesize ({2:x16}) that "
1404 "extends beyond the end of the file ({4:x16}), the segment will be "
1405 "truncated to match",
1406 cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize,
m_length);
1409 seg_cmd.filesize =
m_length - seg_cmd.fileoff;
1416 if (seg_cmd.initprot & VM_PROT_READ)
1417 result |= ePermissionsReadable;
1418 if (seg_cmd.initprot & VM_PROT_WRITE)
1419 result |= ePermissionsWritable;
1420 if (seg_cmd.initprot & VM_PROT_EXECUTE)
1421 result |= ePermissionsExecutable;
1428 if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1431 uint32_t mach_sect_type = flags & SECTION_TYPE;
1432 static ConstString g_sect_name_objc_data(
"__objc_data");
1433 static ConstString g_sect_name_objc_msgrefs(
"__objc_msgrefs");
1434 static ConstString g_sect_name_objc_selrefs(
"__objc_selrefs");
1435 static ConstString g_sect_name_objc_classrefs(
"__objc_classrefs");
1436 static ConstString g_sect_name_objc_superrefs(
"__objc_superrefs");
1437 static ConstString g_sect_name_objc_const(
"__objc_const");
1438 static ConstString g_sect_name_objc_classlist(
"__objc_classlist");
1439 static ConstString g_sect_name_cfstring(
"__cfstring");
1441 static ConstString g_sect_name_dwarf_debug_abbrev(
"__debug_abbrev");
1442 static ConstString g_sect_name_dwarf_debug_aranges(
"__debug_aranges");
1443 static ConstString g_sect_name_dwarf_debug_frame(
"__debug_frame");
1444 static ConstString g_sect_name_dwarf_debug_info(
"__debug_info");
1445 static ConstString g_sect_name_dwarf_debug_line(
"__debug_line");
1446 static ConstString g_sect_name_dwarf_debug_loc(
"__debug_loc");
1447 static ConstString g_sect_name_dwarf_debug_loclists(
"__debug_loclists");
1448 static ConstString g_sect_name_dwarf_debug_macinfo(
"__debug_macinfo");
1449 static ConstString g_sect_name_dwarf_debug_names(
"__debug_names");
1450 static ConstString g_sect_name_dwarf_debug_pubnames(
"__debug_pubnames");
1451 static ConstString g_sect_name_dwarf_debug_pubtypes(
"__debug_pubtypes");
1452 static ConstString g_sect_name_dwarf_debug_ranges(
"__debug_ranges");
1453 static ConstString g_sect_name_dwarf_debug_str(
"__debug_str");
1454 static ConstString g_sect_name_dwarf_debug_types(
"__debug_types");
1455 static ConstString g_sect_name_dwarf_apple_names(
"__apple_names");
1456 static ConstString g_sect_name_dwarf_apple_types(
"__apple_types");
1457 static ConstString g_sect_name_dwarf_apple_namespaces(
"__apple_namespac");
1458 static ConstString g_sect_name_dwarf_apple_objc(
"__apple_objc");
1459 static ConstString g_sect_name_eh_frame(
"__eh_frame");
1460 static ConstString g_sect_name_compact_unwind(
"__unwind_info");
1463 static ConstString g_sect_name_go_symtab(
"__gosymtab");
1465 if (section_name == g_sect_name_dwarf_debug_abbrev)
1467 if (section_name == g_sect_name_dwarf_debug_aranges)
1469 if (section_name == g_sect_name_dwarf_debug_frame)
1471 if (section_name == g_sect_name_dwarf_debug_info)
1473 if (section_name == g_sect_name_dwarf_debug_line)
1475 if (section_name == g_sect_name_dwarf_debug_loc)
1477 if (section_name == g_sect_name_dwarf_debug_loclists)
1479 if (section_name == g_sect_name_dwarf_debug_macinfo)
1481 if (section_name == g_sect_name_dwarf_debug_names)
1483 if (section_name == g_sect_name_dwarf_debug_pubnames)
1485 if (section_name == g_sect_name_dwarf_debug_pubtypes)
1487 if (section_name == g_sect_name_dwarf_debug_ranges)
1489 if (section_name == g_sect_name_dwarf_debug_str)
1491 if (section_name == g_sect_name_dwarf_debug_types)
1493 if (section_name == g_sect_name_dwarf_apple_names)
1495 if (section_name == g_sect_name_dwarf_apple_types)
1497 if (section_name == g_sect_name_dwarf_apple_namespaces)
1499 if (section_name == g_sect_name_dwarf_apple_objc)
1501 if (section_name == g_sect_name_objc_selrefs)
1503 if (section_name == g_sect_name_objc_msgrefs)
1505 if (section_name == g_sect_name_eh_frame)
1507 if (section_name == g_sect_name_compact_unwind)
1509 if (section_name == g_sect_name_cfstring)
1511 if (section_name == g_sect_name_go_symtab)
1513 if (section_name == g_sect_name_objc_data ||
1514 section_name == g_sect_name_objc_classrefs ||
1515 section_name == g_sect_name_objc_superrefs ||
1516 section_name == g_sect_name_objc_const ||
1517 section_name == g_sect_name_objc_classlist) {
1521 switch (mach_sect_type) {
1524 if (section_name == g_sect_name_text)
1526 if (section_name == g_sect_name_data)
1531 case S_CSTRING_LITERALS:
1533 case S_4BYTE_LITERALS:
1535 case S_8BYTE_LITERALS:
1537 case S_LITERAL_POINTERS:
1539 case S_NON_LAZY_SYMBOL_POINTERS:
1541 case S_LAZY_SYMBOL_POINTERS:
1543 case S_SYMBOL_STUBS:
1546 case S_MOD_INIT_FUNC_POINTERS:
1549 case S_MOD_TERM_FUNC_POINTERS:
1559 case S_16BYTE_LITERALS:
1563 case S_LAZY_DYLIB_SYMBOL_POINTERS:
1583 const llvm::MachO::load_command &load_cmd_,
lldb::offset_t offset,
1585 llvm::MachO::segment_command_64 load_cmd;
1586 memcpy(&load_cmd, &load_cmd_,
sizeof(load_cmd_));
1588 if (!
m_data.
GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
1593 const bool is_dsym = (
m_header.filetype == MH_DSYM);
1594 bool add_section =
true;
1595 bool add_to_unified =
true;
1597 load_cmd.segname, strnlen(load_cmd.segname,
sizeof(load_cmd.segname)));
1599 SectionSP unified_section_sp(
1601 if (is_dsym && unified_section_sp) {
1605 add_to_unified =
false;
1609 add_section =
false;
1622 const bool segment_is_encrypted =
1623 (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
1627 SectionSP segment_sp;
1628 if (add_section && (const_segname || is_core)) {
1629 segment_sp = std::make_shared<Section>(
1649 segment_sp->SetIsEncrypted(segment_is_encrypted);
1651 segment_sp->SetPermissions(segment_permissions);
1654 }
else if (unified_section_sp) {
1664 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
1668 "Installing dSYM's %s segment file address over ObjectFile's "
1669 "so symbol table/debug info resolves correctly for %s",
1671 module_sp->GetFileSpec().GetFilename().AsCString());
1676 module_sp->GetObjectFile()->GetSymtab();
1682 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
1691 llvm::MachO::section_64 sect64;
1692 ::memset(§64, 0,
sizeof(sect64));
1700 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
1701 for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
1702 ++segment_sect_idx) {
1703 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.sectname,
1704 sizeof(sect64.sectname)) ==
nullptr)
1706 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.segname,
1707 sizeof(sect64.segname)) ==
nullptr)
1712 if (
m_data.
GetU32(&offset, §64.offset, num_u32s) ==
nullptr)
1725 sect64.sectname, strnlen(sect64.sectname,
sizeof(sect64.sectname)));
1726 if (!const_segname) {
1734 sizeof(sect64.segname));
1736 if (segment_sp.get()) {
1737 Section *segment = segment_sp.get();
1740 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1744 curr_seg_min_addr + curr_seg_byte_size;
1745 if (sect64_min_addr >= curr_seg_min_addr) {
1747 sect64_max_addr - curr_seg_min_addr;
1749 if (new_seg_byte_size > curr_seg_byte_size)
1755 sect64_min_addr - curr_seg_min_addr;
1756 segment->
Slide(slide_amount,
false);
1758 segment->
SetByteSize(curr_seg_max_addr - sect64_min_addr);
1762 if (sect64.offset) {
1768 const lldb::addr_t section_min_file_offset = sect64.offset;
1770 section_min_file_offset + sect64.size;
1772 std::min(section_min_file_offset, segment_min_file_offset);
1774 std::max(section_max_file_offset, segment_max_file_offset) -
1781 segment_sp = std::make_shared<Section>(
1798 sect64.offset ? sect64.size : 0,
1803 segment_sp->SetIsFake(
true);
1804 segment_sp->SetPermissions(segment_permissions);
1808 segment_sp->SetIsEncrypted(segment_is_encrypted);
1811 assert(segment_sp.get());
1815 SectionSP section_sp(
new Section(
1816 segment_sp, module_sp,
this, ++context.
NextSectionIdx, section_name,
1817 sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
1818 sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
1822 bool section_is_encrypted =
false;
1823 if (!segment_is_encrypted && load_cmd.filesize != 0)
1825 sect64.offset) !=
nullptr;
1827 section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
1828 section_sp->SetPermissions(segment_permissions);
1829 segment_sp->GetChildren().AddSection(section_sp);
1831 if (segment_sp->IsFake()) {
1833 const_segname.
Clear();
1837 if (segment_sp && is_dsym) {
1840 for (sect_uid = first_segment_sectID; sect_uid <= context.
NextSectionIdx;
1842 SectionSP curr_section_sp(
1843 segment_sp->GetChildren().FindSectionByID(sect_uid));
1844 SectionSP next_section_sp;
1847 segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
1849 if (curr_section_sp.get()) {
1850 if (curr_section_sp->GetByteSize() == 0) {
1851 if (next_section_sp.get() !=
nullptr)
1852 curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
1853 curr_section_sp->GetFileAddress());
1855 curr_section_sp->SetByteSize(load_cmd.vmsize);
1864 const llvm::MachO::load_command &load_cmd,
lldb::offset_t offset) {
1884 llvm::MachO::load_command load_cmd;
1890 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
1892 else if (load_cmd.cmd == LC_DYSYMTAB)
1895 offset = load_cmd_offset + load_cmd.cmdsize;
1899 module_sp->SectionFileAddressesChanged();
1921 section_sp->GetFileAddress());
1923 section_sp->GetByteSize());
1925 std::string filename =
"<unknown>";
1927 if (first_section_sp)
1928 filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
1931 llvm::formatv(
"unable to find section {0} for a symbol in "
1932 "{1}, corrupt file?",
1962#define TRIE_SYMBOL_IS_THUMB (1ULL << 63)
1965 printf(
"0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
1966 static_cast<unsigned long long>(
address),
1967 static_cast<unsigned long long>(
flags),
1990 printf(
"[%3u] 0x%16.16llx: ", idx,
1991 static_cast<unsigned long long>(
nodeOffset));
2001 const bool is_arm,
addr_t text_seg_base_addr,
2002 std::vector<llvm::StringRef> &nameSlices,
2003 std::set<lldb::addr_t> &resolver_addresses,
2004 std::vector<TrieEntryWithOffset> &reexports,
2005 std::vector<TrieEntryWithOffset> &ext_symbols) {
2011 const uint64_t terminalSize = data.
GetULEB128(&offset);
2013 if (terminalSize != 0) {
2016 const char *import_name =
nullptr;
2017 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
2020 import_name = data.
GetCStr(&offset);
2025 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
2029 resolver_addr += text_seg_base_addr;
2032 resolver_addresses.insert(resolver_addr);
2036 bool add_this_entry =
false;
2038 import_name && import_name[0]) {
2040 add_this_entry =
true;
2042 (import_name ==
nullptr || import_name[0] ==
'\0')) {
2045 add_this_entry =
true;
2047 if (add_this_entry) {
2049 if (!nameSlices.empty()) {
2050 for (
auto name_slice : nameSlices)
2051 name.append(name_slice.data(), name_slice.size());
2053 if (name.size() > 1) {
2062 reexports.push_back(e);
2068 ext_symbols.push_back(e);
2073 const uint8_t childrenCount = data.
GetU8(&children_offset);
2074 for (uint8_t i = 0; i < childrenCount; ++i) {
2075 const char *cstr = data.
GetCStr(&children_offset);
2077 nameSlices.push_back(llvm::StringRef(cstr));
2081 if (childNodeOffset) {
2083 nameSlices, resolver_addresses, reexports,
2088 nameSlices.pop_back();
2094 bool &demangled_is_synthesized,
2095 const SectionSP &text_section_sp,
2096 const SectionSP &data_section_sp,
2097 const SectionSP &data_dirty_section_sp,
2098 const SectionSP &data_const_section_sp,
2099 const SectionSP &symbol_section) {
2102 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2103 if (symbol_section->IsDescendant(text_section_sp.get())) {
2104 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
2105 S_ATTR_SELF_MODIFYING_CODE |
2106 S_ATTR_SOME_INSTRUCTIONS))
2110 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
2111 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
2112 symbol_section->IsDescendant(data_const_section_sp.get())) {
2113 if (symbol_sect_name &&
2114 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
2118 llvm::StringRef symbol_name_ref(symbol_name);
2119 if (symbol_name_ref.startswith(
"OBJC_")) {
2120 static const llvm::StringRef g_objc_v2_prefix_class(
"OBJC_CLASS_$_");
2121 static const llvm::StringRef g_objc_v2_prefix_metaclass(
2122 "OBJC_METACLASS_$_");
2123 static const llvm::StringRef g_objc_v2_prefix_ivar(
"OBJC_IVAR_$_");
2124 if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
2125 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2127 demangled_is_synthesized =
true;
2128 }
else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) {
2129 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2131 demangled_is_synthesized =
true;
2132 }
else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) {
2133 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2135 demangled_is_synthesized =
true;
2139 }
else if (symbol_sect_name &&
2140 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
2146 }
else if (symbol_sect_name &&
2147 ::strstr(symbol_sect_name,
"__IMPORT") == symbol_sect_name) {
2153static std::optional<struct nlist_64>
2155 size_t nlist_byte_size) {
2156 struct nlist_64 nlist;
2177 Progress progress(llvm::formatv(
"Parsing symbol table for {0}", file_name));
2179 llvm::MachO::symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
2180 llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
2181 llvm::MachO::linkedit_data_command exports_trie_load_command = {0, 0, 0, 0};
2182 llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2183 llvm::MachO::dysymtab_command dysymtab =
m_dysymtab;
2192 llvm::DenseSet<addr_t> symbols_added;
2196 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2200 symbols_added.insert(file_addr);
2202 FunctionStarts function_starts;
2207 llvm::StringRef g_objc_v2_prefix_class(
"_OBJC_CLASS_$_");
2208 llvm::StringRef g_objc_v2_prefix_metaclass(
"_OBJC_METACLASS_$_");
2209 llvm::StringRef g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
2212 for (i = 0; i <
m_header.ncmds; ++i) {
2215 llvm::MachO::load_command lc;
2221 symtab_load_command.cmd = lc.cmd;
2222 symtab_load_command.cmdsize = lc.cmdsize;
2224 if (
m_data.
GetU32(&offset, &symtab_load_command.symoff, 4) ==
2230 case LC_DYLD_INFO_ONLY:
2231 if (
m_data.
GetU32(&offset, &dyld_info.rebase_off, 10)) {
2232 dyld_info.cmd = lc.cmd;
2233 dyld_info.cmdsize = lc.cmdsize;
2235 memset(&dyld_info, 0,
sizeof(dyld_info));
2240 case LC_LOAD_WEAK_DYLIB:
2241 case LC_REEXPORT_DYLIB:
2243 case LC_LOAD_UPWARD_DYLIB: {
2253 if (lc.cmd == LC_REEXPORT_DYLIB) {
2257 dylib_files.
Append(file_spec);
2261 case LC_DYLD_EXPORTS_TRIE:
2262 exports_trie_load_command.cmd = lc.cmd;
2263 exports_trie_load_command.cmdsize = lc.cmdsize;
2264 if (
m_data.
GetU32(&offset, &exports_trie_load_command.dataoff, 2) ==
2266 memset(&exports_trie_load_command, 0,
2267 sizeof(exports_trie_load_command));
2269 case LC_FUNCTION_STARTS:
2270 function_starts_load_command.cmd = lc.cmd;
2271 function_starts_load_command.cmdsize = lc.cmdsize;
2272 if (
m_data.
GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
2274 memset(&function_starts_load_command, 0,
2275 sizeof(function_starts_load_command));
2282 image_uuid =
UUID(uuid_bytes, 16);
2289 offset = cmd_offset + lc.cmdsize;
2292 if (!symtab_load_command.cmd)
2296 if (section_list ==
nullptr)
2301 bool bit_width_32 = addr_byte_size == 4;
2302 const size_t nlist_byte_size =
2303 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2305 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2306 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2307 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2308 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2310 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2312 const
addr_t nlist_data_byte_size =
2313 symtab_load_command.nsyms * nlist_byte_size;
2314 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2317 ProcessSP process_sp(m_process_wp.lock());
2318 Process *process = process_sp.get();
2322 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2323 SectionSP linkedit_section_sp(
2324 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2326 if (process && m_header.filetype != llvm::MachO::MH_OBJECT &&
2327 !is_local_shared_cache_image) {
2328 Target &target = process->GetTarget();
2334 if (linkedit_section_sp) {
2335 addr_t linkedit_load_addr =
2336 linkedit_section_sp->GetLoadBaseAddress(&target);
2342 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
2343 m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2346 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2347 const addr_t symoff_addr = linkedit_load_addr +
2348 symtab_load_command.symoff -
2349 linkedit_file_offset;
2350 strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
2351 linkedit_file_offset;
2359 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2360 DataBufferSP nlist_data_sp(
2361 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2363 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2364 if (dysymtab.nindirectsyms != 0) {
2365 const addr_t indirect_syms_addr = linkedit_load_addr +
2366 dysymtab.indirectsymoff -
2367 linkedit_file_offset;
2368 DataBufferSP indirect_syms_data_sp(ReadMemory(
2369 process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
2370 if (indirect_syms_data_sp)
2371 indirect_symbol_index_data.SetData(
2372 indirect_syms_data_sp, 0,
2373 indirect_syms_data_sp->GetByteSize());
2383 if (!is_shared_cache_image) {
2384 DataBufferSP strtab_data_sp(
2385 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2386 if (strtab_data_sp) {
2387 strtab_data.SetData(strtab_data_sp, 0,
2388 strtab_data_sp->GetByteSize());
2393 if (function_starts_load_command.cmd) {
2394 const addr_t func_start_addr =
2395 linkedit_load_addr + function_starts_load_command.dataoff -
2396 linkedit_file_offset;
2397 DataBufferSP func_start_data_sp(
2398 ReadMemory(process_sp, func_start_addr,
2399 function_starts_load_command.datasize));
2400 if (func_start_data_sp)
2401 function_starts_data.SetData(func_start_data_sp, 0,
2402 func_start_data_sp->GetByteSize());
2408 if (is_local_shared_cache_image) {
2416 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2419 symtab_load_command.symoff += linkedit_slide;
2420 symtab_load_command.stroff += linkedit_slide;
2421 dyld_info.export_off += linkedit_slide;
2422 dysymtab.indirectsymoff += linkedit_slide;
2423 function_starts_load_command.dataoff += linkedit_slide;
2424 exports_trie_load_command.dataoff += linkedit_slide;
2427 nlist_data.SetData(
m_data, symtab_load_command.symoff,
2428 nlist_data_byte_size);
2429 strtab_data.SetData(
m_data, symtab_load_command.stroff,
2430 strtab_data_byte_size);
2435 && (exports_trie_load_command.datasize > 0)));
2436 if (dyld_info.export_size > 0) {
2437 dyld_trie_data.SetData(
m_data, dyld_info.export_off,
2438 dyld_info.export_size);
2439 }
else if (exports_trie_load_command.datasize > 0) {
2440 dyld_trie_data.SetData(
m_data, exports_trie_load_command.dataoff,
2441 exports_trie_load_command.datasize);
2444 if (dysymtab.nindirectsyms != 0) {
2445 indirect_symbol_index_data.SetData(
m_data, dysymtab.indirectsymoff,
2446 dysymtab.nindirectsyms * 4);
2448 if (function_starts_load_command.cmd) {
2449 function_starts_data.SetData(
m_data, function_starts_load_command.dataoff,
2450 function_starts_load_command.datasize);
2454 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2462 SectionSP text_section_sp(
2464 SectionSP data_section_sp(
2466 SectionSP data_dirty_section_sp(
2468 SectionSP data_const_section_sp(
2470 SectionSP objc_section_sp(
2472 SectionSP eh_frame_section_sp;
2473 if (text_section_sp.get())
2474 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2475 g_section_name_eh_frame);
2477 eh_frame_section_sp =
2480 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2497 if (text_section_sp && function_starts_data.GetByteSize()) {
2498 FunctionStarts::Entry function_start_entry;
2499 function_start_entry.data =
false;
2501 function_start_entry.addr = text_section_sp->GetFileAddress();
2503 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2506 function_start_entry.addr += delta;
2508 if (function_start_entry.addr & 1) {
2510 function_start_entry.data =
true;
2511 }
else if (always_thumb) {
2512 function_start_entry.data =
true;
2515 function_starts.Append(function_start_entry);
2523 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2529 addr_t text_base_addr = text_section_sp->GetFileAddress();
2530 size_t count = functions.
GetSize();
2531 for (
size_t i = 0; i < count; ++i) {
2535 FunctionStarts::Entry function_start_entry;
2536 function_start_entry.addr = func->
base - text_base_addr;
2538 if (function_start_entry.addr & 1) {
2540 function_start_entry.data =
true;
2541 }
else if (always_thumb) {
2542 function_start_entry.data =
true;
2545 function_starts.Append(function_start_entry);
2551 const size_t function_starts_count = function_starts.GetSize();
2564 Log *unwind_or_symbol_log(
GetLog(LLDBLog::Symbols | LLDBLog::Unwind));
2566 if (unwind_or_symbol_log)
2567 module_sp->LogMessage(
2568 unwind_or_symbol_log,
2569 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2572 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2573 ? eh_frame_section_sp->GetID()
2579 std::vector<uint32_t> N_FUN_indexes;
2580 std::vector<uint32_t> N_NSYM_indexes;
2581 std::vector<uint32_t> N_INCL_indexes;
2582 std::vector<uint32_t> N_BRAC_indexes;
2583 std::vector<uint32_t> N_COMM_indexes;
2584 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2585 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2586 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2587 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2588 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2589 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2592 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2594 Symbol *symbol_ptr =
nullptr;
2598 size_t num_syms = 0;
2599 std::string memory_symbol_name;
2600 uint32_t unmapped_local_symbols_found = 0;
2602 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2603 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2604 std::set<lldb::addr_t> resolver_addresses;
2606 if (dyld_trie_data.GetByteSize() > 0) {
2607 SectionSP text_segment_sp =
2610 if (text_segment_sp)
2611 text_segment_file_addr = text_segment_sp->GetFileAddress();
2612 std::vector<llvm::StringRef> nameSlices;
2614 nameSlices, resolver_addresses, reexport_trie_entries,
2615 external_sym_trie_entries);
2618 typedef std::set<ConstString> IndirectSymbols;
2619 IndirectSymbols indirect_symbol_names;
2642 UUID process_shared_cache_uuid;
2643 addr_t process_shared_cache_base_addr;
2647 process_shared_cache_uuid);
2650 __block
bool found_image =
false;
2651 __block
void *nlist_buffer =
nullptr;
2652 __block
unsigned nlist_count = 0;
2653 __block
char *string_table =
nullptr;
2654 __block vm_offset_t vm_nlist_memory = 0;
2655 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2656 __block vm_offset_t vm_string_memory = 0;
2657 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2659 auto _ = llvm::make_scope_exit(^{
2660 if (vm_nlist_memory)
2661 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2662 if (vm_string_memory)
2663 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2666 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2667 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2668 UndefinedNameToDescMap undefined_name_to_desc;
2669 SymbolIndexToName reexport_shlib_needs_fixup;
2671 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2673 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2677 if (process_shared_cache_uuid.
IsValid() &&
2678 process_shared_cache_uuid != UUID::fromData(&cache_uuid, 16))
2681 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2686 dyld_image_copy_uuid(image, &dsc_image_uuid);
2687 if (image_uuid != UUID::fromData(dsc_image_uuid, 16))
2694 dyld_image_local_nlist_content_4Symbolication(
2695 image, ^(
const void *nlistStart, uint64_t nlistCount,
2696 const char *stringTable) {
2697 if (!nlistStart || !nlistCount)
2705 nlist_byte_size * nlistCount, &vm_nlist_memory,
2706 &vm_nlist_bytes_read);
2709 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2714 vm_address_t string_address = (vm_address_t)stringTable;
2715 vm_size_t region_size;
2716 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2717 vm_region_basic_info_data_t info;
2718 memory_object_name_t object;
2720 ®ion_size, VM_REGION_BASIC_INFO_64,
2721 (vm_region_info_t)&info, &info_count, &
object);
2727 ((vm_address_t)stringTable - string_address),
2728 &vm_string_memory, &vm_string_bytes_read);
2732 nlist_buffer = (
void *)vm_nlist_memory;
2733 string_table = (
char *)vm_string_memory;
2734 nlist_count = nlistCount;
2740 nlist_count * nlist_byte_size,
2741 byte_order, addr_byte_size);
2742 unmapped_local_symbols_found = nlist_count;
2747 symtab_load_command.nsyms +
m_dysymtab.nindirectsyms +
2748 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2754 nlist_index < nlist_count;
2758 std::optional<struct nlist_64> nlist_maybe =
2759 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2763 struct nlist_64 nlist = *nlist_maybe;
2766 const char *symbol_name = string_table + nlist.n_strx;
2768 if (symbol_name == NULL) {
2773 "DSC unmapped local symbol[{0}] has invalid "
2774 "string table offset {1:x} in {2}, ignoring symbol",
2775 nlist_index, nlist.n_strx,
2776 module_sp->GetFileSpec().GetPath());
2779 if (symbol_name[0] ==
'\0')
2782 const char *symbol_name_non_abi_mangled = NULL;
2784 SectionSP symbol_section;
2786 bool add_nlist =
true;
2787 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2788 bool demangled_is_synthesized =
false;
2789 bool is_gsym =
false;
2790 bool set_value =
true;
2792 assert(sym_idx < num_syms);
2797 switch (nlist.n_type) {
2816 if (symbol_name && symbol_name[0] ==
'_' &&
2817 symbol_name[1] ==
'O') {
2818 llvm::StringRef symbol_name_ref(symbol_name);
2819 if (symbol_name_ref.startswith(
2820 g_objc_v2_prefix_class)) {
2821 symbol_name_non_abi_mangled = symbol_name + 1;
2823 symbol_name + g_objc_v2_prefix_class.size();
2825 demangled_is_synthesized =
true;
2827 }
else if (symbol_name_ref.startswith(
2828 g_objc_v2_prefix_metaclass)) {
2829 symbol_name_non_abi_mangled = symbol_name + 1;
2831 symbol_name + g_objc_v2_prefix_metaclass.size();
2833 demangled_is_synthesized =
true;
2834 }
else if (symbol_name_ref.startswith(
2835 g_objc_v2_prefix_ivar)) {
2836 symbol_name_non_abi_mangled = symbol_name + 1;
2838 symbol_name + g_objc_v2_prefix_ivar.size();
2840 demangled_is_synthesized =
true;
2843 if (nlist.n_value != 0)
2845 nlist.n_sect, nlist.n_value);
2860 nlist.n_sect, nlist.n_value);
2862 N_FUN_addr_to_sym_idx.insert(
2863 std::make_pair(nlist.n_value, sym_idx));
2867 N_FUN_indexes.push_back(sym_idx);
2871 if (!N_FUN_indexes.empty()) {
2878 N_FUN_indexes.pop_back();
2890 N_STSYM_addr_to_sym_idx.insert(
2891 std::make_pair(nlist.n_value, sym_idx));
2892 symbol_section = section_info.
GetSection(nlist.n_sect,
2894 if (symbol_name && symbol_name[0]) {
2902 symbol_section = section_info.
GetSection(nlist.n_sect,
2936 symbol_section = section_info.
GetSection(nlist.n_sect,
2949 if (symbol_name == NULL) {
2960 N_NSYM_indexes.clear();
2961 N_INCL_indexes.clear();
2962 N_BRAC_indexes.clear();
2963 N_COMM_indexes.clear();
2964 N_FUN_indexes.clear();
2970 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
2971 if (N_SO_has_full_path) {
2972 if ((N_SO_index == sym_idx - 1) &&
2973 ((sym_idx - 1) < num_syms)) {
2979 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2985 N_SO_index = sym_idx;
2987 }
else if ((N_SO_index == sym_idx - 1) &&
2988 ((sym_idx - 1) < num_syms)) {
2993 const char *so_path = sym[sym_idx - 1]
2997 if (so_path && so_path[0]) {
2998 std::string full_so_path(so_path);
2999 const size_t double_slash_pos =
3000 full_so_path.find(
"//");
3001 if (double_slash_pos != std::string::npos) {
3012 &full_so_path[double_slash_pos + 1],
3013 FileSpec::Style::native);
3016 full_so_path.erase(0, double_slash_pos + 1);
3020 if (*full_so_path.rbegin() !=
'/')
3021 full_so_path +=
'/';
3022 full_so_path += symbol_name;
3026 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3030 N_SO_index = sym_idx;
3051 N_INCL_indexes.push_back(sym_idx);
3061 if (!N_INCL_indexes.empty()) {
3066 N_INCL_indexes.pop_back();
3101 symbol_section = section_info.
GetSection(nlist.n_sect,
3112 symbol_section = section_info.
GetSection(nlist.n_sect,
3114 N_BRAC_indexes.push_back(sym_idx);
3124 symbol_section = section_info.
GetSection(nlist.n_sect,
3126 if (!N_BRAC_indexes.empty()) {
3131 N_BRAC_indexes.pop_back();
3148 N_COMM_indexes.push_back(sym_idx);
3153 symbol_section = section_info.
GetSection(nlist.n_sect,
3164 if (!N_COMM_indexes.empty()) {
3169 N_COMM_indexes.pop_back();
3184 uint8_t n_type = N_TYPE & nlist.n_type;
3185 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3189 const char *reexport_name_cstr =
3190 strtab_data.PeekCStr(nlist.n_value);
3191 if (reexport_name_cstr && reexport_name_cstr[0]) {
3194 reexport_name_cstr +
3195 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3198 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3200 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3206 if (symbol_name && symbol_name[0]) {
3208 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3209 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3221 symbol_section = section_info.
GetSection(nlist.n_sect,
3224 if (symbol_section == NULL) {
3230 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3234 symbol_section->Get() & SECTION_TYPE;
3236 switch (section_type) {
3237 case S_CSTRING_LITERALS:
3240 case S_4BYTE_LITERALS:
3243 case S_8BYTE_LITERALS:
3246 case S_LITERAL_POINTERS:
3249 case S_NON_LAZY_SYMBOL_POINTERS:
3253 case S_LAZY_SYMBOL_POINTERS:
3256 case S_SYMBOL_STUBS:
3260 case S_MOD_INIT_FUNC_POINTERS:
3264 case S_MOD_TERM_FUNC_POINTERS:
3272 case S_16BYTE_LITERALS:
3278 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3282 switch (symbol_section->GetType()) {
3309 const char *symbol_sect_name =
3310 symbol_section->GetName().AsCString();
3311 if (symbol_section->IsDescendant(
3312 text_section_sp.get())) {
3313 if (symbol_section->IsClear(
3314 S_ATTR_PURE_INSTRUCTIONS |
3315 S_ATTR_SELF_MODIFYING_CODE |
3316 S_ATTR_SOME_INSTRUCTIONS))
3320 }
else if (symbol_section->IsDescendant(
3321 data_section_sp.get()) ||
3322 symbol_section->IsDescendant(
3323 data_dirty_section_sp.get()) ||
3324 symbol_section->IsDescendant(
3325 data_const_section_sp.get())) {
3326 if (symbol_sect_name &&
3327 ::strstr(symbol_sect_name,
"__objc") ==
3332 llvm::StringRef symbol_name_ref(symbol_name);
3333 if (symbol_name_ref.startswith(
"_OBJC_")) {
3335 g_objc_v2_prefix_class(
3338 g_objc_v2_prefix_metaclass(
3339 "_OBJC_METACLASS_$_");
3341 g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
3342 if (symbol_name_ref.startswith(
3343 g_objc_v2_prefix_class)) {
3344 symbol_name_non_abi_mangled =
3348 g_objc_v2_prefix_class.size();
3350 demangled_is_synthesized =
true;
3352 symbol_name_ref.startswith(
3353 g_objc_v2_prefix_metaclass)) {
3354 symbol_name_non_abi_mangled =
3358 g_objc_v2_prefix_metaclass.size();
3360 demangled_is_synthesized =
true;
3361 }
else if (symbol_name_ref.startswith(
3362 g_objc_v2_prefix_ivar)) {
3363 symbol_name_non_abi_mangled =
3367 g_objc_v2_prefix_ivar.size();
3369 demangled_is_synthesized =
true;
3373 }
else if (symbol_sect_name &&
3374 ::strstr(symbol_sect_name,
3375 "__gcc_except_tab") ==
3381 }
else if (symbol_sect_name &&
3382 ::strstr(symbol_sect_name,
"__IMPORT") ==
3385 }
else if (symbol_section->IsDescendant(
3386 objc_section_sp.get())) {
3388 if (symbol_name && symbol_name[0] ==
'.') {
3389 llvm::StringRef symbol_name_ref(symbol_name);
3391 g_objc_v1_prefix_class(
".objc_class_name_");
3392 if (symbol_name_ref.startswith(
3393 g_objc_v1_prefix_class)) {
3394 symbol_name_non_abi_mangled = symbol_name;
3395 symbol_name = symbol_name +
3396 g_objc_v1_prefix_class.size();
3398 demangled_is_synthesized =
true;
3409 uint64_t symbol_value = nlist.n_value;
3410 if (symbol_name_non_abi_mangled) {
3416 if (symbol_name && symbol_name[0] ==
'_') {
3422 sym[sym_idx].
GetMangled().SetValue(const_symbol_name);
3423 if (is_gsym && is_debug) {
3424 const char *gsym_name =
3427 .GetName(Mangled::ePreferMangled)
3430 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3434 if (symbol_section) {
3435 const addr_t section_file_addr =
3436 symbol_section->GetFileAddress();
3437 if (symbol_byte_size == 0 &&
3438 function_starts_count > 0) {
3439 addr_t symbol_lookup_file_addr = nlist.n_value;
3444 FunctionStarts::Entry *func_start_entry =
3445 function_starts.FindEntry(symbol_lookup_file_addr,
3447 if (is_arm && func_start_entry) {
3451 if (func_start_entry->addr !=
3452 symbol_lookup_file_addr &&
3453 func_start_entry->addr !=
3454 (symbol_lookup_file_addr + 1)) {
3456 func_start_entry = NULL;
3459 if (func_start_entry) {
3460 func_start_entry->data =
true;
3462 addr_t symbol_file_addr = func_start_entry->addr;
3465 if (symbol_file_addr & 1)
3470 const FunctionStarts::Entry *next_func_start_entry =
3471 function_starts.FindNextEntry(func_start_entry);
3472 const addr_t section_end_file_addr =
3474 symbol_section->GetByteSize();
3475 if (next_func_start_entry) {
3476 addr_t next_symbol_file_addr =
3477 next_func_start_entry->addr;
3483 symbol_byte_size = std::min<lldb::addr_t>(
3484 next_symbol_file_addr - symbol_file_addr,
3485 section_end_file_addr - symbol_file_addr);
3488 section_end_file_addr - symbol_file_addr;
3492 symbol_value -= section_file_addr;
3495 if (is_debug ==
false) {
3503 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3504 if (range.first != range.second) {
3505 bool found_it =
false;
3506 for (
auto pos = range.first; pos != range.second;
3508 if (sym[sym_idx].GetMangled().
GetName(
3509 Mangled::ePreferMangled) ==
3511 Mangled::ePreferMangled)) {
3512 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3518 sym[sym_idx].IsExternal());
3519 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3521 if (resolver_addresses.find(nlist.n_value) !=
3522 resolver_addresses.end())
3524 sym[sym_idx].
Clear();
3532 if (resolver_addresses.find(nlist.n_value) !=
3533 resolver_addresses.end())
3545 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3547 if (range.first != range.second) {
3548 bool found_it =
false;
3549 for (
auto pos = range.first; pos != range.second;
3551 if (sym[sym_idx].GetMangled().
GetName(
3552 Mangled::ePreferMangled) ==
3554 Mangled::ePreferMangled)) {
3555 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3561 sym[sym_idx].IsExternal());
3562 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3564 sym[sym_idx].
Clear();
3572 const char *gsym_name =
3575 .GetName(Mangled::ePreferMangled)
3580 ConstNameToSymbolIndexMap::const_iterator pos =
3581 N_GSYM_name_to_sym_idx.find(gsym_name);
3582 if (pos != N_GSYM_name_to_sym_idx.end()) {
3583 const uint32_t GSYM_sym_idx = pos->second;
3584 m_nlist_idx_to_sym_idx[nlist_idx] =
3593 add_symbol_addr(sym[GSYM_sym_idx]
3600 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3602 sym[sym_idx].
Clear();
3610 sym[sym_idx].
SetID(nlist_idx);
3616 sym[sym_idx].GetAddress().GetFileAddress());
3618 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3620 if (symbol_byte_size > 0)
3623 if (demangled_is_synthesized)
3627 sym[sym_idx].
Clear();
3634 for (
const auto &pos : reexport_shlib_needs_fixup) {
3635 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3636 if (undef_pos != undefined_name_to_desc.end()) {
3637 const uint8_t dylib_ordinal =
3638 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3639 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3649 if (nlist_data.GetByteSize() > 0) {
3653 if (sym ==
nullptr) {
3659 if (unmapped_local_symbols_found) {
3661 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3667 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3668 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3669 UndefinedNameToDescMap undefined_name_to_desc;
3670 SymbolIndexToName reexport_shlib_needs_fixup;
3678 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist,
uint32_t nlist_idx,
3680 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3681 if (is_debug != debug_only)
3684 const char *symbol_name_non_abi_mangled =
nullptr;
3685 const char *symbol_name =
nullptr;
3687 if (have_strtab_data) {
3688 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3690 if (symbol_name ==
nullptr) {
3694 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3696 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3699 if (symbol_name[0] ==
'\0')
3700 symbol_name =
nullptr;
3702 const addr_t str_addr = strtab_addr + nlist.n_strx;
3704 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3706 symbol_name = memory_symbol_name.c_str();
3710 SectionSP symbol_section;
3712 bool add_nlist =
true;
3713 bool is_gsym =
false;
3714 bool demangled_is_synthesized =
false;
3715 bool set_value =
true;
3717 assert(sym_idx < num_syms);
3721 switch (nlist.n_type) {
3738 if (symbol_name && symbol_name[0] ==
'_' && symbol_name[1] ==
'O') {
3739 llvm::StringRef symbol_name_ref(symbol_name);
3740 if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
3741 symbol_name_non_abi_mangled = symbol_name + 1;
3742 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3744 demangled_is_synthesized =
true;
3746 }
else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) {
3747 symbol_name_non_abi_mangled = symbol_name + 1;
3748 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3750 demangled_is_synthesized =
true;
3751 }
else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) {
3752 symbol_name_non_abi_mangled = symbol_name + 1;
3753 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3755 demangled_is_synthesized =
true;
3758 if (nlist.n_value != 0)
3760 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3775 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3777 N_FUN_addr_to_sym_idx.insert(
3778 std::make_pair(nlist.n_value, sym_idx));
3782 N_FUN_indexes.push_back(sym_idx);
3786 if (!N_FUN_indexes.empty()) {
3791 N_FUN_indexes.pop_back();
3802 N_STSYM_addr_to_sym_idx.insert(
3803 std::make_pair(nlist.n_value, sym_idx));
3804 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3805 if (symbol_name && symbol_name[0]) {
3813 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3844 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3856 if (symbol_name ==
nullptr) {
3867 N_NSYM_indexes.clear();
3868 N_INCL_indexes.clear();
3869 N_BRAC_indexes.clear();
3870 N_COMM_indexes.clear();
3871 N_FUN_indexes.clear();
3877 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3878 if (N_SO_has_full_path) {
3879 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3884 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3889 N_SO_index = sym_idx;
3891 }
else if ((N_SO_index == sym_idx - 1) &&
3892 ((sym_idx - 1) < num_syms)) {
3896 const char *so_path =
3897 sym[sym_idx - 1].
GetMangled().GetDemangledName().AsCString();
3898 if (so_path && so_path[0]) {
3899 std::string full_so_path(so_path);
3900 const size_t double_slash_pos = full_so_path.find(
"//");
3901 if (double_slash_pos != std::string::npos) {
3909 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3910 FileSpec::Style::native);
3913 full_so_path.erase(0, double_slash_pos + 1);
3917 if (*full_so_path.rbegin() !=
'/')
3918 full_so_path +=
'/';
3919 full_so_path += symbol_name;
3923 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3927 N_SO_index = sym_idx;
3947 N_INCL_indexes.push_back(sym_idx);
3956 if (!N_INCL_indexes.empty()) {
3960 N_INCL_indexes.pop_back();
3995 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4004 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4005 N_BRAC_indexes.push_back(sym_idx);
4014 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4015 if (!N_BRAC_indexes.empty()) {
4019 N_BRAC_indexes.pop_back();
4035 N_COMM_indexes.push_back(sym_idx);
4040 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4049 if (!N_COMM_indexes.empty()) {
4053 N_COMM_indexes.pop_back();
4067 uint8_t n_type = N_TYPE & nlist.n_type;
4068 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
4072 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4073 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
4076 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
4079 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4080 indirect_symbol_names.insert(
4081 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
4087 if (symbol_name && symbol_name[0]) {
4089 ((symbol_name[0] ==
'_') ? 1 : 0));
4090 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4103 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4105 if (!symbol_section) {
4111 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4114 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4116 switch (section_type) {
4117 case S_CSTRING_LITERALS:
4120 case S_4BYTE_LITERALS:
4123 case S_8BYTE_LITERALS:
4126 case S_LITERAL_POINTERS:
4129 case S_NON_LAZY_SYMBOL_POINTERS:
4132 case S_LAZY_SYMBOL_POINTERS:
4135 case S_SYMBOL_STUBS:
4139 case S_MOD_INIT_FUNC_POINTERS:
4142 case S_MOD_TERM_FUNC_POINTERS:
4149 case S_16BYTE_LITERALS:
4155 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4159 switch (symbol_section->GetType()) {
4181 const char *symbol_sect_name =
4182 symbol_section->GetName().AsCString();
4183 if (symbol_section->IsDescendant(text_section_sp.get())) {
4184 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4185 S_ATTR_SELF_MODIFYING_CODE |
4186 S_ATTR_SOME_INSTRUCTIONS))
4190 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4191 symbol_section->IsDescendant(
4192 data_dirty_section_sp.get()) ||
4193 symbol_section->IsDescendant(
4194 data_const_section_sp.get())) {
4195 if (symbol_sect_name &&
4196 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4200 llvm::StringRef symbol_name_ref(symbol_name);
4201 if (symbol_name_ref.startswith(
"_OBJC_")) {
4202 llvm::StringRef g_objc_v2_prefix_class(
4204 llvm::StringRef g_objc_v2_prefix_metaclass(
4205 "_OBJC_METACLASS_$_");
4206 llvm::StringRef g_objc_v2_prefix_ivar(
4208 if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
4209 symbol_name_non_abi_mangled = symbol_name + 1;
4211 symbol_name + g_objc_v2_prefix_class.size();
4213 demangled_is_synthesized =
true;
4214 }
else if (symbol_name_ref.startswith(
4215 g_objc_v2_prefix_metaclass)) {
4216 symbol_name_non_abi_mangled = symbol_name + 1;
4218 symbol_name + g_objc_v2_prefix_metaclass.size();
4220 demangled_is_synthesized =
true;
4221 }
else if (symbol_name_ref.startswith(
4222 g_objc_v2_prefix_ivar)) {
4223 symbol_name_non_abi_mangled = symbol_name + 1;
4225 symbol_name + g_objc_v2_prefix_ivar.size();
4227 demangled_is_synthesized =
true;
4231 }
else if (symbol_sect_name &&
4232 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4238 }
else if (symbol_sect_name &&
4239 ::strstr(symbol_sect_name,
"__IMPORT") ==
4242 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4244 if (symbol_name && symbol_name[0] ==
'.') {
4245 llvm::StringRef symbol_name_ref(symbol_name);
4246 llvm::StringRef g_objc_v1_prefix_class(
4247 ".objc_class_name_");
4248 if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) {
4249 symbol_name_non_abi_mangled = symbol_name;
4250 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4252 demangled_is_synthesized =
true;
4263 sym[sym_idx].
Clear();
4267 uint64_t symbol_value = nlist.n_value;
4269 if (symbol_name_non_abi_mangled) {
4275 if (symbol_name && symbol_name[0] ==
'_') {
4281 sym[sym_idx].
GetMangled().SetValue(const_symbol_name);
4286 const char *gsym_name = sym[sym_idx]
4288 .GetName(Mangled::ePreferMangled)
4291 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4294 if (symbol_section) {
4295 const addr_t section_file_addr = symbol_section->GetFileAddress();
4296 if (symbol_byte_size == 0 && function_starts_count > 0) {
4297 addr_t symbol_lookup_file_addr = nlist.n_value;
4301 FunctionStarts::Entry *func_start_entry =
4302 function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
4303 if (is_arm && func_start_entry) {
4306 if (func_start_entry->addr != symbol_lookup_file_addr &&
4307 func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
4309 func_start_entry =
nullptr;
4312 if (func_start_entry) {
4313 func_start_entry->data =
true;
4315 addr_t symbol_file_addr = func_start_entry->addr;
4319 const FunctionStarts::Entry *next_func_start_entry =
4320 function_starts.FindNextEntry(func_start_entry);
4321 const addr_t section_end_file_addr =
4322 section_file_addr + symbol_section->GetByteSize();
4323 if (next_func_start_entry) {
4324 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4329 symbol_byte_size = std::min<lldb::addr_t>(
4330 next_symbol_file_addr - symbol_file_addr,
4331 section_end_file_addr - symbol_file_addr);
4333 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4337 symbol_value -= section_file_addr;
4346 std::pair<ValueToSymbolIndexMap::const_iterator,
4347 ValueToSymbolIndexMap::const_iterator>
4349 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4350 if (range.first != range.second) {
4351 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4352 pos != range.second; ++pos) {
4353 if (sym[sym_idx].GetMangled().
GetName(Mangled::ePreferMangled) ==
4355 Mangled::ePreferMangled)) {
4356 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4360 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4361 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4362 if (resolver_addresses.find(nlist.n_value) !=
4363 resolver_addresses.end())
4365 sym[sym_idx].
Clear();
4370 if (resolver_addresses.find(nlist.n_value) !=
4371 resolver_addresses.end())
4381 std::pair<ValueToSymbolIndexMap::const_iterator,
4382 ValueToSymbolIndexMap::const_iterator>
4384 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4385 if (range.first != range.second) {
4386 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4387 pos != range.second; ++pos) {
4388 if (sym[sym_idx].GetMangled().
GetName(Mangled::ePreferMangled) ==
4390 Mangled::ePreferMangled)) {
4391 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4395 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4396 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4397 sym[sym_idx].
Clear();
4403 const char *gsym_name = sym[sym_idx]
4405 .GetName(Mangled::ePreferMangled)
4408 ConstNameToSymbolIndexMap::const_iterator pos =
4409 N_GSYM_name_to_sym_idx.find(gsym_name);
4410 if (pos != N_GSYM_name_to_sym_idx.end()) {
4411 const uint32_t GSYM_sym_idx = pos->second;
4412 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4418 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4422 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4423 sym[sym_idx].
Clear();
4431 sym[sym_idx].
SetID(nlist_idx);
4437 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4439 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4440 if (nlist.n_desc & N_WEAK_REF)
4443 if (symbol_byte_size > 0)
4446 if (demangled_is_synthesized)
4455 std::vector<struct nlist_64> nlists;
4456 nlists.reserve(symtab_load_command.nsyms);
4457 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4459 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4460 nlists.push_back(*nlist);
4470 for (
auto &nlist : nlists) {
4471 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4477 for (
auto &nlist : nlists) {
4482 for (
const auto &pos : reexport_shlib_needs_fixup) {
4483 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4484 if (undef_pos != undefined_name_to_desc.end()) {
4485 const uint8_t dylib_ordinal =
4486 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4487 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4495 int trie_symbol_table_augment_count = 0;
4496 for (
auto &e : external_sym_trie_entries) {
4497 if (!symbols_added.contains(e.entry.address))
4498 trie_symbol_table_augment_count++;
4501 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4502 num_syms = sym_idx + trie_symbol_table_augment_count;
4503 sym = symtab.
Resize(num_syms);
4505 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4508 for (
auto &e : external_sym_trie_entries) {
4509 if (symbols_added.contains(e.entry.address))
4515 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4516 SectionSP symbol_section(symbol_addr.
GetSection());
4517 const char *symbol_name = e.entry.name.GetCString();
4518 bool demangled_is_synthesized =
false;
4520 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4521 data_section_sp, data_dirty_section_sp,
4522 data_const_section_sp, symbol_section);
4525 if (symbol_section) {
4526 sym[sym_idx].
SetID(synthetic_sym_id++);
4528 if (demangled_is_synthesized)
4541 if (function_starts_count > 0) {
4542 uint32_t num_synthetic_function_symbols = 0;
4543 for (i = 0; i < function_starts_count; ++i) {
4544 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4545 ++num_synthetic_function_symbols;
4548 if (num_synthetic_function_symbols > 0) {
4549 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4550 num_syms = sym_idx + num_synthetic_function_symbols;
4551 sym = symtab.
Resize(num_syms);
4553 for (i = 0; i < function_starts_count; ++i) {
4554 const FunctionStarts::Entry *func_start_entry =
4555 function_starts.GetEntryAtIndex(i);
4556 if (!symbols_added.contains(func_start_entry->addr)) {
4557 addr_t symbol_file_addr = func_start_entry->addr;
4559 if (func_start_entry->data)
4562 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4563 SectionSP symbol_section(symbol_addr.
GetSection());
4565 if (symbol_section) {
4566 const addr_t section_file_addr = symbol_section->GetFileAddress();
4567 const FunctionStarts::Entry *next_func_start_entry =
4568 function_starts.FindNextEntry(func_start_entry);
4569 const addr_t section_end_file_addr =
4570 section_file_addr + symbol_section->GetByteSize();
4571 if (next_func_start_entry) {
4572 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4575 symbol_byte_size = std::min<lldb::addr_t>(
4576 next_symbol_file_addr - symbol_file_addr,
4577 section_end_file_addr - symbol_file_addr);
4579 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4581 sym[sym_idx].
SetID(synthetic_sym_id++);
4591 sym[sym_idx].
SetFlags(symbol_flags);
4592 if (symbol_byte_size)
4604 if (sym_idx < num_syms) {
4606 sym = symtab.
Resize(num_syms);
4611 if (indirect_symbol_index_data.GetByteSize()) {
4612 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4613 m_nlist_idx_to_sym_idx.end();
4620 if (symbol_stub_byte_size == 0)
4626 if (num_symbol_stubs == 0)
4629 const uint32_t symbol_stub_index_offset =
4631 for (
uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4633 symbol_stub_index_offset + stub_idx;
4636 (stub_idx * symbol_stub_byte_size);
4638 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4639 symbol_stub_offset, 4)) {
4641 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4642 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4645 NListIndexToSymbolIndexMap::const_iterator index_pos =
4646 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4647 Symbol *stub_symbol =
nullptr;
4648 if (index_pos != end_index_pos) {
4659 Address so_addr(symbol_stub_addr, section_list);
4666 if (resolver_addresses.find(symbol_stub_addr) ==
4667 resolver_addresses.end())
4676 Mangled stub_symbol_mangled_name(stub_symbol->
GetMangled());
4677 if (sym_idx >= num_syms) {
4678 sym = symtab.
Resize(++num_syms);
4679 stub_symbol =
nullptr;
4681 sym[sym_idx].
SetID(synthetic_sym_id++);
4682 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4683 if (resolver_addresses.find(symbol_stub_addr) ==
4684 resolver_addresses.end())
4696 log->
Warning(
"symbol stub referencing symbol table symbol "
4697 "%u that isn't in our minimal symbol table, "
4708 if (!reexport_trie_entries.empty()) {
4709 for (
const auto &e : reexport_trie_entries) {
4710 if (e.entry.import_name) {
4713 if (indirect_symbol_names.find(e.entry.name) ==
4714 indirect_symbol_names.end()) {
4716 if (sym_idx >= num_syms)
4717 sym = symtab.
Resize(++num_syms);
4718 sym[sym_idx].
SetID(synthetic_sym_id++);
4719 sym[sym_idx].
GetMangled() = Mangled(e.entry.name);
4723 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
4737 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4738 s->
Printf(
"%p: ",
static_cast<void *
>(
this));
4745 *s <<
", file = '" <<
m_file;
4749 base_spec, all_specs);
4750 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
4775 llvm::MachO::uuid_command load_cmd;
4778 for (i = 0; i < header.ncmds; ++i) {
4780 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
4783 if (load_cmd.cmd == LC_UUID) {
4784 const uint8_t *uuid_bytes = data.
PeekData(offset, 16);
4790 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4791 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4792 0xbb, 0x14, 0xf0, 0x0d};
4794 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4797 return UUID(uuid_bytes, 16);
4801 offset = cmd_offset + load_cmd.cmdsize;
4808 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4809 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4810 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4811 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4812 case llvm::MachO::LC_VERSION_MIN_TVOS:
4813 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4814 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4815 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4817 llvm_unreachable(
"unexpected LC_VERSION load command");
4823 llvm::StringRef os_type;
4824 llvm::StringRef environment;
4827 case llvm::MachO::PLATFORM_MACOS:
4828 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4830 case llvm::MachO::PLATFORM_IOS:
4831 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4833 case llvm::MachO::PLATFORM_TVOS:
4834 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4836 case llvm::MachO::PLATFORM_WATCHOS:
4837 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4847 case llvm::MachO::PLATFORM_MACCATALYST:
4848 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4849 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
4851 case llvm::MachO::PLATFORM_IOSSIMULATOR:
4852 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4854 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4856 case llvm::MachO::PLATFORM_TVOSSIMULATOR:
4857 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4859 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4861 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
4862 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4864 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4867 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
4868 LLDB_LOGF(log,
"unsupported platform in LC_BUILD_VERSION");
4875 uint32_t major_version, minor_version, patch_version;
4877 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),
4878 patch_version(version & 0xffu) {}
4889 if (!base_arch.IsValid())
4892 bool found_any =
false;
4893 auto add_triple = [&](
const llvm::Triple &triple) {
4894 auto spec = base_spec;
4896 if (spec.GetArchitecture().IsValid()) {
4904 llvm::Triple base_triple = base_arch.GetTriple();
4905 base_triple.setOS(llvm::Triple::UnknownOS);
4906 base_triple.setOSName(llvm::StringRef());
4908 if (header.filetype == MH_PRELOAD) {
4909 if (header.cputype == CPU_TYPE_ARM) {
4915 base_triple.setVendor(llvm::Triple::Apple);
4920 base_triple.setVendor(llvm::Triple::UnknownVendor);
4921 base_triple.setVendorName(llvm::StringRef());
4923 return add_triple(base_triple);
4926 llvm::MachO::load_command load_cmd;
4931 for (
uint32_t i = 0; i < header.ncmds; ++i) {
4933 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
4936 llvm::MachO::version_min_command version_min;
4937 switch (load_cmd.cmd) {
4938 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4939 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4940 case llvm::MachO::LC_VERSION_MIN_TVOS:
4941 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
4942 if (load_cmd.cmdsize !=
sizeof(version_min))
4947 MinOS min_os(version_min.version);
4948 llvm::SmallString<32> os_name;
4949 llvm::raw_svector_ostream os(os_name);
4950 os <<
GetOSName(load_cmd.cmd) << min_os.major_version <<
'.'
4951 << min_os.minor_version <<
'.' << min_os.patch_version;
4953 auto triple = base_triple;
4954 triple.setOSName(os.str());
4957 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
4958 (base_triple.getArch() == llvm::Triple::x86_64 ||
4959 base_triple.getArch() == llvm::Triple::x86)) {
4966 triple.setEnvironment(llvm::Triple::Simulator);
4975 offset = cmd_offset + load_cmd.cmdsize;
4981 for (
uint32_t i = 0; i < header.ncmds; ++i) {
4983 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
4987 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
4988 llvm::MachO::build_version_command build_version;
4989 if (load_cmd.cmdsize <
sizeof(build_version)) {
4993 if (data.
ExtractBytes(cmd_offset,
sizeof(build_version),
4996 MinOS min_os(build_version.minos);
4997 OSEnv os_env(build_version.platform);
4998 llvm::SmallString<16> os_name;
4999 llvm::raw_svector_ostream os(os_name);
5000 os << os_env.os_type << min_os.major_version <<
'.'
5001 << min_os.minor_version <<
'.' << min_os.patch_version;
5002 auto triple = base_triple;
5003 triple.setOSName(os.str());
5005 if (!os_env.environment.empty())
5006 triple.setEnvironmentName(os_env.environment);
5010 offset = cmd_offset + load_cmd.cmdsize;
5014 add_triple(base_triple);
5019 ModuleSP module_sp,
const llvm::MachO::mach_header &header,
5024 base_spec, all_specs);
5029 const ArchSpec &module_arch = module_sp->GetArchitecture();
5030 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
5047 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5058 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5059 llvm::MachO::load_command load_cmd;
5061 std::vector<std::string> rpath_paths;
5062 std::vector<std::string> rpath_relative_paths;
5063 std::vector<std::string> at_exec_relative_paths;
5065 for (i = 0; i <
m_header.ncmds; ++i) {
5066 const uint32_t cmd_offset = offset;
5070 switch (load_cmd.cmd) {
5073 case LC_LOAD_WEAK_DYLIB:
5074 case LC_REEXPORT_DYLIB:
5075 case LC_LOAD_DYLINKER:
5077 case LC_LOAD_UPWARD_DYLIB: {
5081 if (load_cmd.cmd == LC_RPATH)
5082 rpath_paths.push_back(path);
5084 if (path[0] ==
'@') {
5085 if (strncmp(path,
"@rpath", strlen(
"@rpath")) == 0)
5086 rpath_relative_paths.push_back(path + strlen(
"@rpath"));
5087 else if (strncmp(path,
"@executable_path",
5088 strlen(
"@executable_path")) == 0)
5089 at_exec_relative_paths.push_back(path +
5090 strlen(
"@executable_path"));
5103 offset = cmd_offset + load_cmd.cmdsize;
5109 if (!rpath_paths.empty()) {
5111 std::string loader_path(
"@loader_path");
5112 std::string executable_path(
"@executable_path");
5113 for (
auto &rpath : rpath_paths) {
5114 if (llvm::StringRef(rpath).startswith(loader_path)) {
5115 rpath.erase(0, loader_path.size());
5117 }
else if (llvm::StringRef(rpath).startswith(executable_path)) {
5118 rpath.erase(0, executable_path.size());
5123 for (
const auto &rpath_relative_path : rpath_relative_paths) {
5124 for (
const auto &rpath : rpath_paths) {
5125 std::string path = rpath;
5126 path += rpath_relative_path;
5146 for (
const auto &at_exec_relative_path : at_exec_relative_paths) {
5194 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5195 llvm::MachO::load_command load_cmd;
5201 for (i = 0; i <
m_header.ncmds; ++i) {
5206 switch (load_cmd.cmd) {
5209 while (offset < cmd_offset + load_cmd.cmdsize) {
5218 case llvm::MachO::CPU_TYPE_ARM:
5229 case llvm::MachO::CPU_TYPE_ARM64:
5230 case llvm::MachO::CPU_TYPE_ARM64_32:
5239 case llvm::MachO::CPU_TYPE_I386:
5249 case llvm::MachO::CPU_TYPE_X86_64:
5266 offset += count * 4;
5271 SectionSP text_segment_sp =
5273 if (text_segment_sp) {
5275 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5286 offset = cmd_offset + load_cmd.cmdsize;
5292 ConstString(
"_dyld_start"), SymbolType::eSymbolTypeCode,
5300 if (start_address !=
LL