9#include "llvm/ADT/ScopeExit.h"
10#include "llvm/ADT/StringRef.h"
48#include "llvm/ADT/DenseSet.h"
49#include "llvm/Support/FormatVariadic.h"
50#include "llvm/Support/MemoryBuffer.h"
55#include <TargetConditionals.h>
58#include <mach/mach_init.h>
59#include <mach/vm_map.h>
80#ifdef CPU_TYPE_ARM64_32
81#undef CPU_TYPE_ARM64_32
95#ifdef LC_VERSION_MIN_MACOSX
96#undef LC_VERSION_MIN_MACOSX
98#ifdef LC_VERSION_MIN_IPHONEOS
99#undef LC_VERSION_MIN_IPHONEOS
101#ifdef LC_VERSION_MIN_TVOS
102#undef LC_VERSION_MIN_TVOS
104#ifdef LC_VERSION_MIN_WATCHOS
105#undef LC_VERSION_MIN_WATCHOS
107#ifdef LC_BUILD_VERSION
108#undef LC_BUILD_VERSION
113#ifdef PLATFORM_MACCATALYST
114#undef PLATFORM_MACCATALYST
119#ifdef PLATFORM_IOSSIMULATOR
120#undef PLATFORM_IOSSIMULATOR
125#ifdef PLATFORM_TVOSSIMULATOR
126#undef PLATFORM_TVOSSIMULATOR
128#ifdef PLATFORM_WATCHOS
129#undef PLATFORM_WATCHOS
131#ifdef PLATFORM_WATCHOSSIMULATOR
132#undef PLATFORM_WATCHOSSIMULATOR
135#define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
138using namespace llvm::MachO;
143 const
char *alt_name,
size_t reg_byte_size,
145 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
146 if (reg_info ==
nullptr)
147 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
150 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
151 if (reg_info->
byte_size >= reg_byte_size)
152 data.Write(reg_value.
GetBytes(), reg_byte_size);
155 for (
size_t i = 0, n = reg_byte_size - reg_info->
byte_size; i < n; ++i)
162 for (
size_t i = 0; i < reg_byte_size; ++i)
186 int flavor = data.
GetU32(&offset);
191 uint32_t count = data.
GetU32(&offset);
194 for (i = 0; i < count; ++i)
391 int flavor = data.
GetU32(&offset);
396 uint32_t count = data.
GetU32(&offset);
399 for (i = 0; i < count; ++i)
507 int flavor = data.
GetU32(&offset);
508 uint32_t count = data.
GetU32(&offset);
514 uint32_t gpr_buf_count = (
sizeof(
gpr.
r) /
sizeof(
gpr.
r[0])) + 1;
515 if (count == gpr_buf_count) {
516 for (uint32_t i = 0; i < (count - 1); ++i) {
524 offset = next_thread_state;
528 uint8_t *fpu_reg_buf = (uint8_t *)&
fpu.
floats;
529 const int fpu_reg_buf_size =
sizeof(
fpu.
floats);
531 fpu_reg_buf) == fpu_reg_buf_size) {
532 offset += fpu_reg_buf_size;
539 offset = next_thread_state;
550 offset = next_thread_state;
641 int flavor = data.
GetU32(&offset);
642 uint32_t count = data.
GetU32(&offset);
648 if (count >= (33 * 2) + 1) {
649 for (uint32_t i = 0; i < 29; ++i)
658 offset = next_thread_state;
661 uint8_t *fpu_reg_buf = (uint8_t *)&
fpu.
v[0];
662 const int fpu_reg_buf_size =
sizeof(
fpu);
663 if (fpu_reg_buf_size == count *
sizeof(uint32_t) &&
665 fpu_reg_buf) == fpu_reg_buf_size) {
671 offset = next_thread_state;
680 offset = next_thread_state;
773 return sizeof(
struct llvm::MachO::mach_header);
777 return sizeof(
struct llvm::MachO::mach_header_64);
786#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
817 if (data_sp->GetByteSize() < length) {
823 auto objfile_up = std::make_unique<ObjectFileMachO>(
824 module_sp, data_sp, data_offset, file, file_offset, length);
825 if (!objfile_up || !objfile_up->ParseHeader())
828 return objfile_up.release();
835 std::unique_ptr<ObjectFile> objfile_up(
837 if (objfile_up.get() && objfile_up->ParseHeader())
838 return objfile_up.release();
847 const size_t initial_count = specs.
GetSize();
852 llvm::MachO::mach_header header;
854 size_t header_and_load_cmds =
856 if (header_and_load_cmds >= data_sp->GetByteSize()) {
857 data_sp =
MapFileData(file, header_and_load_cmds, file_offset);
870 return specs.
GetSize() - initial_count;
875 return g_segment_name_TEXT;
880 return g_segment_name_DATA;
885 return g_segment_name;
890 return g_segment_name;
895 return g_segment_name_OBJC;
899 static ConstString g_section_name_LINKEDIT(
"__LINKEDIT");
900 return g_section_name_LINKEDIT;
905 return g_section_name;
910 return g_section_name;
914 static ConstString g_section_name_eh_frame(
"__eh_frame");
915 return g_section_name_eh_frame;
922 data.
SetData(data_sp, data_offset, data_length);
924 uint32_t magic = data.
GetU32(&offset);
928 uint32_t filetype = data.
GetU32(&offset);
933 if (filetype == llvm::MachO::MH_FILESET)
945 :
ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
946 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
947 m_thread_context_offsets_valid(false), m_reexported_dylibs(),
948 m_allow_assembly_emulation_unwind_plans(true) {
957 :
ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
958 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
959 m_thread_context_offsets_valid(false), m_reexported_dylibs(),
960 m_allow_assembly_emulation_unwind_plans(true) {
967 llvm::MachO::mach_header &header) {
970 header.magic = data.
GetU32(data_offset_ptr);
971 bool can_parse =
false;
972 bool is_64_bit =
false;
973 switch (header.magic) {
1009 data.
GetU32(data_offset_ptr, &header.cputype, 6);
1011 *data_offset_ptr += 4;
1014 memset(&header, 0,
sizeof(header));
1024 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1025 bool can_parse =
false;
1069 base_spec, all_specs);
1071 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
1076 const ArchSpec &module_arch = module_sp->GetArchitecture();
1081 const size_t header_and_lc_size =
1091 if (data_sp->GetByteSize() != header_and_lc_size)
1103 memset(&
m_header, 0,
sizeof(
struct llvm::MachO::mach_header));
1113 return m_header.filetype == MH_EXECUTE;
1117 return m_header.filetype == MH_DYLINKER;
1121 return m_header.flags & MH_DYLIB_IN_CACHE;
1125 return m_header.filetype == MH_KEXT_BUNDLE;
1135 return AddressClass::eUnknown;
1143 switch (section_type) {
1145 return AddressClass::eUnknown;
1148 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1152 return AddressClass::eCodeAlternateISA;
1154 return AddressClass::eCode;
1157 return AddressClass::eUnknown;
1171 return AddressClass::eData;
1210 return AddressClass::eDebug;
1216 return AddressClass::eRuntime;
1224 return AddressClass::eUnknown;
1230 switch (symbol_type) {
1232 return AddressClass::eUnknown;
1234 return AddressClass::eUnknown;
1239 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1243 return AddressClass::eCodeAlternateISA;
1245 return AddressClass::eCode;
1248 return AddressClass::eData;
1250 return AddressClass::eRuntime;
1252 return AddressClass::eRuntime;
1254 return AddressClass::eDebug;
1256 return AddressClass::eDebug;
1258 return AddressClass::eDebug;
1260 return AddressClass::eDebug;
1262 return AddressClass::eDebug;
1264 return AddressClass::eData;
1266 return AddressClass::eData;
1268 return AddressClass::eData;
1270 return AddressClass::eDebug;
1272 return AddressClass::eDebug;
1274 return AddressClass::eDebug;
1276 return AddressClass::eDebug;
1278 return AddressClass::eDebug;
1280 return AddressClass::eUnknown;
1282 return AddressClass::eDebug;
1284 return AddressClass::eDebug;
1286 return AddressClass::eUnknown;
1288 return AddressClass::eRuntime;
1290 return AddressClass::eRuntime;
1292 return AddressClass::eRuntime;
1294 return AddressClass::eRuntime;
1297 return AddressClass::eUnknown;
1305 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1308 llvm::MachO::load_command lc = {};
1311 if (lc.cmd == LC_DYSYMTAB) {
1315 (
sizeof(
m_dysymtab) /
sizeof(uint32_t)) - 2) ==
1322 offset = load_cmd_offset + lc.cmdsize;
1335 llvm::MachO::encryption_info_command encryption_cmd;
1336 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1338 if (
m_data.
GetU32(&offset, &encryption_cmd, 2) ==
nullptr)
1343 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
1344 encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
1345 if (
m_data.
GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
1346 if (encryption_cmd.cryptid != 0) {
1354 offset = load_cmd_offset + encryption_cmd.cmdsize;
1361 llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx) {
1362 if (
m_length == 0 || seg_cmd.filesize == 0)
1371 sizeof(seg_cmd.segname)) == 0)
1374 sizeof(seg_cmd.segname)) == 0)
1387 const char *lc_segment_name =
1388 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1390 "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "
1391 "the end of the file ({3:x16}), ignoring this section",
1392 cmd_idx, lc_segment_name, seg_cmd.fileoff,
m_length);
1394 seg_cmd.fileoff = 0;
1395 seg_cmd.filesize = 0;
1398 if (seg_cmd.fileoff + seg_cmd.filesize >
m_length) {
1405 const char *lc_segment_name =
1406 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1408 "load command {0} {1} has a fileoff + filesize ({2:x16}) that "
1409 "extends beyond the end of the file ({4:x16}), the segment will be "
1410 "truncated to match",
1411 cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize,
m_length);
1414 seg_cmd.filesize =
m_length - seg_cmd.fileoff;
1420 uint32_t result = 0;
1421 if (seg_cmd.initprot & VM_PROT_READ)
1422 result |= ePermissionsReadable;
1423 if (seg_cmd.initprot & VM_PROT_WRITE)
1424 result |= ePermissionsWritable;
1425 if (seg_cmd.initprot & VM_PROT_EXECUTE)
1426 result |= ePermissionsExecutable;
1433 if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1436 uint32_t mach_sect_type = flags & SECTION_TYPE;
1437 static ConstString g_sect_name_objc_data(
"__objc_data");
1438 static ConstString g_sect_name_objc_msgrefs(
"__objc_msgrefs");
1439 static ConstString g_sect_name_objc_selrefs(
"__objc_selrefs");
1440 static ConstString g_sect_name_objc_classrefs(
"__objc_classrefs");
1441 static ConstString g_sect_name_objc_superrefs(
"__objc_superrefs");
1442 static ConstString g_sect_name_objc_const(
"__objc_const");
1443 static ConstString g_sect_name_objc_classlist(
"__objc_classlist");
1444 static ConstString g_sect_name_cfstring(
"__cfstring");
1446 static ConstString g_sect_name_dwarf_debug_abbrev(
"__debug_abbrev");
1447 static ConstString g_sect_name_dwarf_debug_abbrev_dwo(
"__debug_abbrev.dwo");
1448 static ConstString g_sect_name_dwarf_debug_addr(
"__debug_addr");
1449 static ConstString g_sect_name_dwarf_debug_aranges(
"__debug_aranges");
1450 static ConstString g_sect_name_dwarf_debug_cu_index(
"__debug_cu_index");
1451 static ConstString g_sect_name_dwarf_debug_frame(
"__debug_frame");
1452 static ConstString g_sect_name_dwarf_debug_info(
"__debug_info");
1453 static ConstString g_sect_name_dwarf_debug_info_dwo(
"__debug_info.dwo");
1454 static ConstString g_sect_name_dwarf_debug_line(
"__debug_line");
1455 static ConstString g_sect_name_dwarf_debug_line_dwo(
"__debug_line.dwo");
1456 static ConstString g_sect_name_dwarf_debug_line_str(
"__debug_line_str");
1457 static ConstString g_sect_name_dwarf_debug_loc(
"__debug_loc");
1458 static ConstString g_sect_name_dwarf_debug_loclists(
"__debug_loclists");
1459 static ConstString g_sect_name_dwarf_debug_loclists_dwo(
"__debug_loclists.dwo");
1460 static ConstString g_sect_name_dwarf_debug_macinfo(
"__debug_macinfo");
1461 static ConstString g_sect_name_dwarf_debug_macro(
"__debug_macro");
1462 static ConstString g_sect_name_dwarf_debug_macro_dwo(
"__debug_macro.dwo");
1463 static ConstString g_sect_name_dwarf_debug_names(
"__debug_names");
1464 static ConstString g_sect_name_dwarf_debug_pubnames(
"__debug_pubnames");
1465 static ConstString g_sect_name_dwarf_debug_pubtypes(
"__debug_pubtypes");
1466 static ConstString g_sect_name_dwarf_debug_ranges(
"__debug_ranges");
1467 static ConstString g_sect_name_dwarf_debug_rnglists(
"__debug_rnglists");
1468 static ConstString g_sect_name_dwarf_debug_str(
"__debug_str");
1469 static ConstString g_sect_name_dwarf_debug_str_dwo(
"__debug_str.dwo");
1470 static ConstString g_sect_name_dwarf_debug_str_offs(
"__debug_str_offs");
1471 static ConstString g_sect_name_dwarf_debug_str_offs_dwo(
"__debug_str_offs.dwo");
1472 static ConstString g_sect_name_dwarf_debug_tu_index(
"__debug_tu_index");
1473 static ConstString g_sect_name_dwarf_debug_types(
"__debug_types");
1474 static ConstString g_sect_name_dwarf_apple_names(
"__apple_names");
1475 static ConstString g_sect_name_dwarf_apple_types(
"__apple_types");
1476 static ConstString g_sect_name_dwarf_apple_namespaces(
"__apple_namespac");
1477 static ConstString g_sect_name_dwarf_apple_objc(
"__apple_objc");
1478 static ConstString g_sect_name_eh_frame(
"__eh_frame");
1479 static ConstString g_sect_name_compact_unwind(
"__unwind_info");
1482 static ConstString g_sect_name_go_symtab(
"__gosymtab");
1484 static ConstString g_sect_name_swift_ast(
"__swift_ast");
1486 if (section_name == g_sect_name_dwarf_debug_abbrev)
1488 if (section_name == g_sect_name_dwarf_debug_abbrev_dwo)
1490 if (section_name == g_sect_name_dwarf_debug_addr)
1492 if (section_name == g_sect_name_dwarf_debug_aranges)
1494 if (section_name == g_sect_name_dwarf_debug_cu_index)
1496 if (section_name == g_sect_name_dwarf_debug_frame)
1498 if (section_name == g_sect_name_dwarf_debug_info)
1500 if (section_name == g_sect_name_dwarf_debug_info_dwo)
1502 if (section_name == g_sect_name_dwarf_debug_line)
1504 if (section_name == g_sect_name_dwarf_debug_line_dwo)
1506 if (section_name == g_sect_name_dwarf_debug_line_str)
1508 if (section_name == g_sect_name_dwarf_debug_loc)
1510 if (section_name == g_sect_name_dwarf_debug_loclists)
1512 if (section_name == g_sect_name_dwarf_debug_loclists_dwo)
1514 if (section_name == g_sect_name_dwarf_debug_macinfo)
1516 if (section_name == g_sect_name_dwarf_debug_macro)
1518 if (section_name == g_sect_name_dwarf_debug_macro_dwo)
1520 if (section_name == g_sect_name_dwarf_debug_names)
1522 if (section_name == g_sect_name_dwarf_debug_pubnames)
1524 if (section_name == g_sect_name_dwarf_debug_pubtypes)
1526 if (section_name == g_sect_name_dwarf_debug_ranges)
1528 if (section_name == g_sect_name_dwarf_debug_rnglists)
1530 if (section_name == g_sect_name_dwarf_debug_str)
1532 if (section_name == g_sect_name_dwarf_debug_str_dwo)
1534 if (section_name == g_sect_name_dwarf_debug_str_offs)
1536 if (section_name == g_sect_name_dwarf_debug_str_offs_dwo)
1538 if (section_name == g_sect_name_dwarf_debug_tu_index)
1540 if (section_name == g_sect_name_dwarf_debug_types)
1542 if (section_name == g_sect_name_dwarf_apple_names)
1544 if (section_name == g_sect_name_dwarf_apple_types)
1546 if (section_name == g_sect_name_dwarf_apple_namespaces)
1548 if (section_name == g_sect_name_dwarf_apple_objc)
1550 if (section_name == g_sect_name_objc_selrefs)
1552 if (section_name == g_sect_name_objc_msgrefs)
1554 if (section_name == g_sect_name_eh_frame)
1556 if (section_name == g_sect_name_compact_unwind)
1558 if (section_name == g_sect_name_cfstring)
1560 if (section_name == g_sect_name_go_symtab)
1562 if (section_name == g_sect_name_ctf)
1564 if (section_name == g_sect_name_swift_ast)
1566 if (section_name == g_sect_name_objc_data ||
1567 section_name == g_sect_name_objc_classrefs ||
1568 section_name == g_sect_name_objc_superrefs ||
1569 section_name == g_sect_name_objc_const ||
1570 section_name == g_sect_name_objc_classlist) {
1574 switch (mach_sect_type) {
1577 if (section_name == g_sect_name_text)
1579 if (section_name == g_sect_name_data)
1584 case S_CSTRING_LITERALS:
1586 case S_4BYTE_LITERALS:
1588 case S_8BYTE_LITERALS:
1590 case S_LITERAL_POINTERS:
1592 case S_NON_LAZY_SYMBOL_POINTERS:
1594 case S_LAZY_SYMBOL_POINTERS:
1596 case S_SYMBOL_STUBS:
1599 case S_MOD_INIT_FUNC_POINTERS:
1602 case S_MOD_TERM_FUNC_POINTERS:
1612 case S_16BYTE_LITERALS:
1616 case S_LAZY_DYLIB_SYMBOL_POINTERS:
1636 const llvm::MachO::load_command &load_cmd_,
lldb::offset_t offset,
1638 llvm::MachO::segment_command_64 load_cmd;
1639 memcpy(&load_cmd, &load_cmd_,
sizeof(load_cmd_));
1641 if (!
m_data.
GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
1646 const bool is_dsym = (
m_header.filetype == MH_DSYM);
1647 bool add_section =
true;
1648 bool add_to_unified =
true;
1650 load_cmd.segname, strnlen(load_cmd.segname,
sizeof(load_cmd.segname)));
1654 if (is_dsym && unified_section_sp) {
1658 add_to_unified =
false;
1662 add_section =
false;
1675 const bool segment_is_encrypted =
1676 (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
1681 if (add_section && (const_segname || is_core)) {
1682 segment_sp = std::make_shared<Section>(
1702 segment_sp->SetIsEncrypted(segment_is_encrypted);
1704 segment_sp->SetPermissions(segment_permissions);
1707 }
else if (unified_section_sp) {
1717 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
1721 "Installing dSYM's %s segment file address over ObjectFile's "
1722 "so symbol table/debug info resolves correctly for %s",
1724 module_sp->GetFileSpec().GetFilename().AsCString());
1729 module_sp->GetObjectFile()->GetSymtab();
1735 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
1744 llvm::MachO::section_64 sect64;
1745 ::memset(§64, 0,
sizeof(sect64));
1750 uint32_t segment_sect_idx;
1753 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
1754 for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
1755 ++segment_sect_idx) {
1756 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.sectname,
1757 sizeof(sect64.sectname)) ==
nullptr)
1759 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.segname,
1760 sizeof(sect64.segname)) ==
nullptr)
1765 if (
m_data.
GetU32(&offset, §64.offset, num_u32s) ==
nullptr)
1778 sect64.sectname, strnlen(sect64.sectname,
sizeof(sect64.sectname)));
1779 if (!const_segname) {
1787 sizeof(sect64.segname));
1789 if (segment_sp.get()) {
1790 Section *segment = segment_sp.get();
1793 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1797 curr_seg_min_addr + curr_seg_byte_size;
1798 if (sect64_min_addr >= curr_seg_min_addr) {
1800 sect64_max_addr - curr_seg_min_addr;
1802 if (new_seg_byte_size > curr_seg_byte_size)
1808 sect64_min_addr - curr_seg_min_addr;
1809 segment->
Slide(slide_amount,
false);
1811 segment->
SetByteSize(curr_seg_max_addr - sect64_min_addr);
1815 if (sect64.offset) {
1821 const lldb::addr_t section_min_file_offset = sect64.offset;
1823 section_min_file_offset + sect64.size;
1825 std::min(section_min_file_offset, segment_min_file_offset);
1827 std::max(section_max_file_offset, segment_max_file_offset) -
1834 segment_sp = std::make_shared<Section>(
1851 sect64.offset ? sect64.size : 0,
1856 segment_sp->SetIsFake(
true);
1857 segment_sp->SetPermissions(segment_permissions);
1861 segment_sp->SetIsEncrypted(segment_is_encrypted);
1864 assert(segment_sp.get());
1869 segment_sp, module_sp,
this, ++context.
NextSectionIdx, section_name,
1870 sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
1871 sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
1875 bool section_is_encrypted =
false;
1876 if (!segment_is_encrypted && load_cmd.filesize != 0)
1878 sect64.offset) !=
nullptr;
1880 section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
1881 section_sp->SetPermissions(segment_permissions);
1882 segment_sp->GetChildren().AddSection(section_sp);
1884 if (segment_sp->IsFake()) {
1886 const_segname.
Clear();
1890 if (segment_sp && is_dsym) {
1893 for (sect_uid = first_segment_sectID; sect_uid <= context.
NextSectionIdx;
1896 segment_sp->GetChildren().FindSectionByID(sect_uid));
1900 segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
1902 if (curr_section_sp.get()) {
1903 if (curr_section_sp->GetByteSize() == 0) {
1904 if (next_section_sp.get() !=
nullptr)
1905 curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
1906 curr_section_sp->GetFileAddress());
1908 curr_section_sp->SetByteSize(load_cmd.vmsize);
1917 const llvm::MachO::load_command &load_cmd,
lldb::offset_t offset) {
1921 (
sizeof(
m_dysymtab) /
sizeof(uint32_t)) - 2);
1937 llvm::MachO::load_command load_cmd;
1938 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1943 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
1945 else if (load_cmd.cmd == LC_DYSYMTAB)
1948 offset = load_cmd_offset + load_cmd.cmdsize;
1952 module_sp->SectionFileAddressesChanged();
1974 section_sp->GetFileAddress());
1976 section_sp->GetByteSize());
1978 std::string filename =
"<unknown>";
1980 if (first_section_sp)
1981 filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
1984 llvm::formatv(
"unable to find section {0} for a symbol in "
1985 "{1}, corrupt file?",
2015#define TRIE_SYMBOL_IS_THUMB (1ULL << 63)
2018 printf(
"0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2019 static_cast<unsigned long long>(
address),
2020 static_cast<unsigned long long>(
flags),
2043 printf(
"[%3u] 0x%16.16llx: ", idx,
2044 static_cast<unsigned long long>(
nodeOffset));
2054 const bool is_arm,
addr_t text_seg_base_addr,
2055 std::vector<llvm::StringRef> &nameSlices,
2056 std::set<lldb::addr_t> &resolver_addresses,
2057 std::vector<TrieEntryWithOffset> &reexports,
2058 std::vector<TrieEntryWithOffset> &ext_symbols) {
2064 const uint64_t terminalSize = data.
GetULEB128(&offset);
2066 if (terminalSize != 0) {
2069 const char *import_name =
nullptr;
2070 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
2073 import_name = data.
GetCStr(&offset);
2078 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
2082 resolver_addr += text_seg_base_addr;
2085 resolver_addresses.insert(resolver_addr);
2089 bool add_this_entry =
false;
2091 import_name && import_name[0]) {
2093 add_this_entry =
true;
2095 (import_name ==
nullptr || import_name[0] ==
'\0')) {
2098 add_this_entry =
true;
2100 if (add_this_entry) {
2102 if (!nameSlices.empty()) {
2103 for (
auto name_slice : nameSlices)
2104 name.append(name_slice.data(), name_slice.size());
2106 if (name.size() > 1) {
2115 reexports.push_back(e);
2121 ext_symbols.push_back(e);
2126 const uint8_t childrenCount = data.
GetU8(&children_offset);
2127 for (uint8_t i = 0; i < childrenCount; ++i) {
2128 const char *cstr = data.
GetCStr(&children_offset);
2130 nameSlices.push_back(llvm::StringRef(cstr));
2134 if (childNodeOffset) {
2136 nameSlices, resolver_addresses, reexports,
2141 nameSlices.pop_back();
2147 bool &demangled_is_synthesized,
2155 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2156 if (symbol_section->IsDescendant(text_section_sp.get())) {
2157 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
2158 S_ATTR_SELF_MODIFYING_CODE |
2159 S_ATTR_SOME_INSTRUCTIONS))
2163 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
2164 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
2165 symbol_section->IsDescendant(data_const_section_sp.get())) {
2166 if (symbol_sect_name &&
2167 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
2171 llvm::StringRef symbol_name_ref(symbol_name);
2172 if (symbol_name_ref.starts_with(
"OBJC_")) {
2173 static const llvm::StringRef g_objc_v2_prefix_class(
"OBJC_CLASS_$_");
2174 static const llvm::StringRef g_objc_v2_prefix_metaclass(
2175 "OBJC_METACLASS_$_");
2176 static const llvm::StringRef g_objc_v2_prefix_ivar(
"OBJC_IVAR_$_");
2177 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
2178 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2180 demangled_is_synthesized =
true;
2181 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
2182 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2184 demangled_is_synthesized =
true;
2185 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
2186 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2188 demangled_is_synthesized =
true;
2192 }
else if (symbol_sect_name &&
2193 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
2199 }
else if (symbol_sect_name &&
2200 ::strstr(symbol_sect_name,
"__IMPORT") == symbol_sect_name) {
2206static std::optional<struct nlist_64>
2208 size_t nlist_byte_size) {
2209 struct nlist_64 nlist;
2232 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2233 Progress progress(
"Parsing symbol table", file_name);
2235 llvm::MachO::symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
2236 llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
2237 llvm::MachO::linkedit_data_command exports_trie_load_command = {0, 0, 0, 0};
2238 llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2239 llvm::MachO::dysymtab_command dysymtab =
m_dysymtab;
2248 llvm::DenseSet<addr_t> symbols_added;
2252 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2256 symbols_added.insert(file_addr);
2258 FunctionStarts function_starts;
2262 llvm::StringRef g_objc_v2_prefix_class(
"_OBJC_CLASS_$_");
2263 llvm::StringRef g_objc_v2_prefix_metaclass(
"_OBJC_METACLASS_$_");
2264 llvm::StringRef g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
2267 for (i = 0; i <
m_header.ncmds; ++i) {
2270 llvm::MachO::load_command lc;
2276 symtab_load_command.cmd = lc.cmd;
2277 symtab_load_command.cmdsize = lc.cmdsize;
2279 if (
m_data.
GetU32(&offset, &symtab_load_command.symoff, 4) ==
2285 case LC_DYLD_INFO_ONLY:
2286 if (
m_data.
GetU32(&offset, &dyld_info.rebase_off, 10)) {
2287 dyld_info.cmd = lc.cmd;
2288 dyld_info.cmdsize = lc.cmdsize;
2290 memset(&dyld_info, 0,
sizeof(dyld_info));
2295 case LC_LOAD_WEAK_DYLIB:
2296 case LC_REEXPORT_DYLIB:
2298 case LC_LOAD_UPWARD_DYLIB: {
2299 uint32_t name_offset = cmd_offset +
m_data.
GetU32(&offset);
2308 if (lc.cmd == LC_REEXPORT_DYLIB) {
2312 dylib_files.
Append(file_spec);
2316 case LC_DYLD_EXPORTS_TRIE:
2317 exports_trie_load_command.cmd = lc.cmd;
2318 exports_trie_load_command.cmdsize = lc.cmdsize;
2319 if (
m_data.
GetU32(&offset, &exports_trie_load_command.dataoff, 2) ==
2321 memset(&exports_trie_load_command, 0,
2322 sizeof(exports_trie_load_command));
2324 case LC_FUNCTION_STARTS:
2325 function_starts_load_command.cmd = lc.cmd;
2326 function_starts_load_command.cmdsize = lc.cmdsize;
2327 if (
m_data.
GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
2329 memset(&function_starts_load_command, 0,
2330 sizeof(function_starts_load_command));
2337 image_uuid =
UUID(uuid_bytes, 16);
2344 offset = cmd_offset + lc.cmdsize;
2347 if (!symtab_load_command.cmd)
2351 if (section_list ==
nullptr)
2356 bool bit_width_32 = addr_byte_size == 4;
2357 const size_t nlist_byte_size =
2358 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2360 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2361 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2362 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2363 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2365 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2367 const
addr_t nlist_data_byte_size =
2368 symtab_load_command.nsyms * nlist_byte_size;
2369 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2372 ProcessSP process_sp(m_process_wp.lock());
2373 Process *process = process_sp.get();
2377 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2379 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2381 if (process && m_header.filetype != llvm::MachO::MH_OBJECT &&
2382 !is_local_shared_cache_image) {
2383 Target &target = process->GetTarget();
2389 if (linkedit_section_sp) {
2390 addr_t linkedit_load_addr =
2391 linkedit_section_sp->GetLoadBaseAddress(&target);
2397 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
2398 m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2401 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2402 const addr_t symoff_addr = linkedit_load_addr +
2403 symtab_load_command.symoff -
2404 linkedit_file_offset;
2405 strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
2406 linkedit_file_offset;
2414 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2416 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2418 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2419 if (dysymtab.nindirectsyms != 0) {
2420 const addr_t indirect_syms_addr = linkedit_load_addr +
2421 dysymtab.indirectsymoff -
2422 linkedit_file_offset;
2424 process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
2425 if (indirect_syms_data_sp)
2426 indirect_symbol_index_data.SetData(
2427 indirect_syms_data_sp, 0,
2428 indirect_syms_data_sp->GetByteSize());
2438 if (!is_shared_cache_image) {
2440 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2441 if (strtab_data_sp) {
2442 strtab_data.SetData(strtab_data_sp, 0,
2443 strtab_data_sp->GetByteSize());
2448 if (function_starts_load_command.cmd) {
2449 const addr_t func_start_addr =
2450 linkedit_load_addr + function_starts_load_command.dataoff -
2451 linkedit_file_offset;
2453 ReadMemory(process_sp, func_start_addr,
2454 function_starts_load_command.datasize));
2455 if (func_start_data_sp)
2456 function_starts_data.SetData(func_start_data_sp, 0,
2457 func_start_data_sp->GetByteSize());
2463 if (is_local_shared_cache_image) {
2471 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2474 symtab_load_command.symoff += linkedit_slide;
2475 symtab_load_command.stroff += linkedit_slide;
2476 dyld_info.export_off += linkedit_slide;
2477 dysymtab.indirectsymoff += linkedit_slide;
2478 function_starts_load_command.dataoff += linkedit_slide;
2479 exports_trie_load_command.dataoff += linkedit_slide;
2482 nlist_data.SetData(
m_data, symtab_load_command.symoff,
2483 nlist_data_byte_size);
2484 strtab_data.SetData(
m_data, symtab_load_command.stroff,
2485 strtab_data_byte_size);
2490 && (exports_trie_load_command.datasize > 0)));
2491 if (dyld_info.export_size > 0) {
2492 dyld_trie_data.SetData(
m_data, dyld_info.export_off,
2493 dyld_info.export_size);
2494 }
else if (exports_trie_load_command.datasize > 0) {
2495 dyld_trie_data.SetData(
m_data, exports_trie_load_command.dataoff,
2496 exports_trie_load_command.datasize);
2499 if (dysymtab.nindirectsyms != 0) {
2500 indirect_symbol_index_data.SetData(
m_data, dysymtab.indirectsymoff,
2501 dysymtab.nindirectsyms * 4);
2503 if (function_starts_load_command.cmd) {
2504 function_starts_data.SetData(
m_data, function_starts_load_command.dataoff,
2505 function_starts_load_command.datasize);
2509 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2528 if (text_section_sp.get())
2529 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2530 g_section_name_eh_frame);
2532 eh_frame_section_sp =
2535 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2552 if (text_section_sp && function_starts_data.GetByteSize()) {
2553 FunctionStarts::Entry function_start_entry;
2554 function_start_entry.data =
false;
2556 function_start_entry.addr = text_section_sp->GetFileAddress();
2558 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2561 function_start_entry.addr += delta;
2563 if (function_start_entry.addr & 1) {
2565 function_start_entry.data =
true;
2566 }
else if (always_thumb) {
2567 function_start_entry.data =
true;
2570 function_starts.Append(function_start_entry);
2578 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2584 addr_t text_base_addr = text_section_sp->GetFileAddress();
2585 size_t count = functions.
GetSize();
2586 for (
size_t i = 0; i < count; ++i) {
2590 FunctionStarts::Entry function_start_entry;
2591 function_start_entry.addr = func->
base - text_base_addr;
2593 if (function_start_entry.addr & 1) {
2595 function_start_entry.data =
true;
2596 }
else if (always_thumb) {
2597 function_start_entry.data =
true;
2600 function_starts.Append(function_start_entry);
2606 const size_t function_starts_count = function_starts.GetSize();
2619 Log *unwind_or_symbol_log(
GetLog(LLDBLog::Symbols | LLDBLog::Unwind));
2621 if (unwind_or_symbol_log)
2622 module_sp->LogMessage(
2623 unwind_or_symbol_log,
2624 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2627 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2628 ? eh_frame_section_sp->GetID()
2634 std::vector<uint32_t> N_FUN_indexes;
2635 std::vector<uint32_t> N_NSYM_indexes;
2636 std::vector<uint32_t> N_INCL_indexes;
2637 std::vector<uint32_t> N_BRAC_indexes;
2638 std::vector<uint32_t> N_COMM_indexes;
2639 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2640 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2641 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2642 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2643 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2644 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2647 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2648 uint32_t nlist_idx = 0;
2649 Symbol *symbol_ptr =
nullptr;
2651 uint32_t sym_idx = 0;
2653 size_t num_syms = 0;
2654 std::string memory_symbol_name;
2655 uint32_t unmapped_local_symbols_found = 0;
2657 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2658 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2659 std::set<lldb::addr_t> resolver_addresses;
2661 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2662 if (dyld_trie_data_size > 0) {
2663 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2667 if (text_segment_sp)
2668 text_segment_file_addr = text_segment_sp->GetFileAddress();
2669 std::vector<llvm::StringRef> nameSlices;
2671 nameSlices, resolver_addresses, reexport_trie_entries,
2672 external_sym_trie_entries);
2675 typedef std::set<ConstString> IndirectSymbols;
2676 IndirectSymbols indirect_symbol_names;
2699 UUID process_shared_cache_uuid;
2700 addr_t process_shared_cache_base_addr;
2704 process_shared_cache_uuid);
2707 __block
bool found_image =
false;
2708 __block
void *nlist_buffer =
nullptr;
2709 __block
unsigned nlist_count = 0;
2710 __block
char *string_table =
nullptr;
2711 __block vm_offset_t vm_nlist_memory = 0;
2712 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2713 __block vm_offset_t vm_string_memory = 0;
2714 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2716 auto _ = llvm::make_scope_exit(^{
2717 if (vm_nlist_memory)
2718 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2719 if (vm_string_memory)
2720 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2723 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2724 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2725 UndefinedNameToDescMap undefined_name_to_desc;
2726 SymbolIndexToName reexport_shlib_needs_fixup;
2728 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2730 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2734 if (process_shared_cache_uuid.
IsValid() &&
2735 process_shared_cache_uuid != UUID::fromData(&cache_uuid, 16))
2738 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2743 dyld_image_copy_uuid(image, &dsc_image_uuid);
2744 if (image_uuid != UUID::fromData(dsc_image_uuid, 16))
2751 dyld_image_local_nlist_content_4Symbolication(
2752 image, ^(
const void *nlistStart, uint64_t nlistCount,
2753 const char *stringTable) {
2754 if (!nlistStart || !nlistCount)
2762 nlist_byte_size * nlistCount, &vm_nlist_memory,
2763 &vm_nlist_bytes_read);
2766 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2771 vm_address_t string_address = (vm_address_t)stringTable;
2772 vm_size_t region_size;
2773 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2774 vm_region_basic_info_data_t info;
2775 memory_object_name_t object;
2777 ®ion_size, VM_REGION_BASIC_INFO_64,
2778 (vm_region_info_t)&info, &info_count, &
object);
2784 ((vm_address_t)stringTable - string_address),
2785 &vm_string_memory, &vm_string_bytes_read);
2789 nlist_buffer = (
void *)vm_nlist_memory;
2790 string_table = (
char *)vm_string_memory;
2791 nlist_count = nlistCount;
2797 nlist_count * nlist_byte_size,
2798 byte_order, addr_byte_size);
2799 unmapped_local_symbols_found = nlist_count;
2804 symtab_load_command.nsyms +
m_dysymtab.nindirectsyms +
2805 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2810 for (uint32_t nlist_index = 0;
2811 nlist_index < nlist_count;
2815 std::optional<struct nlist_64> nlist_maybe =
2816 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2820 struct nlist_64 nlist = *nlist_maybe;
2823 const char *symbol_name = string_table + nlist.n_strx;
2825 if (symbol_name == NULL) {
2830 "DSC unmapped local symbol[{0}] has invalid "
2831 "string table offset {1:x} in {2}, ignoring symbol",
2832 nlist_index, nlist.n_strx,
2833 module_sp->GetFileSpec().GetPath());
2836 if (symbol_name[0] ==
'\0')
2839 const char *symbol_name_non_abi_mangled = NULL;
2842 uint32_t symbol_byte_size = 0;
2843 bool add_nlist =
true;
2844 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2845 bool demangled_is_synthesized =
false;
2846 bool is_gsym =
false;
2847 bool set_value =
true;
2849 assert(sym_idx < num_syms);
2854 switch (nlist.n_type) {
2873 if (symbol_name && symbol_name[0] ==
'_' &&
2874 symbol_name[1] ==
'O') {
2875 llvm::StringRef symbol_name_ref(symbol_name);
2876 if (symbol_name_ref.starts_with(
2877 g_objc_v2_prefix_class)) {
2878 symbol_name_non_abi_mangled = symbol_name + 1;
2880 symbol_name + g_objc_v2_prefix_class.size();
2882 demangled_is_synthesized =
true;
2884 }
else if (symbol_name_ref.starts_with(
2885 g_objc_v2_prefix_metaclass)) {
2886 symbol_name_non_abi_mangled = symbol_name + 1;
2888 symbol_name + g_objc_v2_prefix_metaclass.size();
2890 demangled_is_synthesized =
true;
2891 }
else if (symbol_name_ref.starts_with(
2892 g_objc_v2_prefix_ivar)) {
2893 symbol_name_non_abi_mangled = symbol_name + 1;
2895 symbol_name + g_objc_v2_prefix_ivar.size();
2897 demangled_is_synthesized =
true;
2900 if (nlist.n_value != 0)
2902 nlist.n_sect, nlist.n_value);
2917 nlist.n_sect, nlist.n_value);
2919 N_FUN_addr_to_sym_idx.insert(
2920 std::make_pair(nlist.n_value, sym_idx));
2924 N_FUN_indexes.push_back(sym_idx);
2928 if (!N_FUN_indexes.empty()) {
2935 N_FUN_indexes.pop_back();
2947 N_STSYM_addr_to_sym_idx.insert(
2948 std::make_pair(nlist.n_value, sym_idx));
2949 symbol_section = section_info.
GetSection(nlist.n_sect,
2951 if (symbol_name && symbol_name[0]) {
2959 symbol_section = section_info.
GetSection(nlist.n_sect,
2993 symbol_section = section_info.
GetSection(nlist.n_sect,
3006 if (symbol_name == NULL) {
3017 N_NSYM_indexes.clear();
3018 N_INCL_indexes.clear();
3019 N_BRAC_indexes.clear();
3020 N_COMM_indexes.clear();
3021 N_FUN_indexes.clear();
3027 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3028 if (N_SO_has_full_path) {
3029 if ((N_SO_index == sym_idx - 1) &&
3030 ((sym_idx - 1) < num_syms)) {
3036 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3042 N_SO_index = sym_idx;
3044 }
else if ((N_SO_index == sym_idx - 1) &&
3045 ((sym_idx - 1) < num_syms)) {
3050 const char *so_path = sym[sym_idx - 1]
3054 if (so_path && so_path[0]) {
3055 std::string full_so_path(so_path);
3056 const size_t double_slash_pos =
3057 full_so_path.find(
"//");
3058 if (double_slash_pos != std::string::npos) {
3069 &full_so_path[double_slash_pos + 1],
3070 FileSpec::Style::native);
3073 full_so_path.erase(0, double_slash_pos + 1);
3077 if (*full_so_path.rbegin() !=
'/')
3078 full_so_path +=
'/';
3079 full_so_path += symbol_name;
3083 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3087 N_SO_index = sym_idx;
3108 N_INCL_indexes.push_back(sym_idx);
3118 if (!N_INCL_indexes.empty()) {
3123 N_INCL_indexes.pop_back();
3158 symbol_section = section_info.
GetSection(nlist.n_sect,
3169 symbol_section = section_info.
GetSection(nlist.n_sect,
3171 N_BRAC_indexes.push_back(sym_idx);
3181 symbol_section = section_info.
GetSection(nlist.n_sect,
3183 if (!N_BRAC_indexes.empty()) {
3188 N_BRAC_indexes.pop_back();
3205 N_COMM_indexes.push_back(sym_idx);
3210 symbol_section = section_info.
GetSection(nlist.n_sect,
3221 if (!N_COMM_indexes.empty()) {
3226 N_COMM_indexes.pop_back();
3241 uint8_t n_type = N_TYPE & nlist.n_type;
3242 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3246 const char *reexport_name_cstr =
3247 strtab_data.PeekCStr(nlist.n_value);
3248 if (reexport_name_cstr && reexport_name_cstr[0]) {
3251 reexport_name_cstr +
3252 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3255 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3257 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3263 if (symbol_name && symbol_name[0]) {
3265 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3266 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3278 symbol_section = section_info.
GetSection(nlist.n_sect,
3281 if (symbol_section == NULL) {
3287 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3290 uint32_t section_type =
3291 symbol_section->Get() & SECTION_TYPE;
3293 switch (section_type) {
3294 case S_CSTRING_LITERALS:
3297 case S_4BYTE_LITERALS:
3300 case S_8BYTE_LITERALS:
3303 case S_LITERAL_POINTERS:
3306 case S_NON_LAZY_SYMBOL_POINTERS:
3310 case S_LAZY_SYMBOL_POINTERS:
3313 case S_SYMBOL_STUBS:
3317 case S_MOD_INIT_FUNC_POINTERS:
3321 case S_MOD_TERM_FUNC_POINTERS:
3329 case S_16BYTE_LITERALS:
3335 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3339 switch (symbol_section->GetType()) {
3366 const char *symbol_sect_name =
3367 symbol_section->GetName().AsCString();
3368 if (symbol_section->IsDescendant(
3369 text_section_sp.get())) {
3370 if (symbol_section->IsClear(
3371 S_ATTR_PURE_INSTRUCTIONS |
3372 S_ATTR_SELF_MODIFYING_CODE |
3373 S_ATTR_SOME_INSTRUCTIONS))
3377 }
else if (symbol_section->IsDescendant(
3378 data_section_sp.get()) ||
3379 symbol_section->IsDescendant(
3380 data_dirty_section_sp.get()) ||
3381 symbol_section->IsDescendant(
3382 data_const_section_sp.get())) {
3383 if (symbol_sect_name &&
3384 ::strstr(symbol_sect_name,
"__objc") ==
3389 llvm::StringRef symbol_name_ref(symbol_name);
3390 if (symbol_name_ref.starts_with(
"_OBJC_")) {
3392 g_objc_v2_prefix_class(
3395 g_objc_v2_prefix_metaclass(
3396 "_OBJC_METACLASS_$_");
3398 g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
3399 if (symbol_name_ref.starts_with(
3400 g_objc_v2_prefix_class)) {
3401 symbol_name_non_abi_mangled =
3405 g_objc_v2_prefix_class.size();
3407 demangled_is_synthesized =
true;
3409 symbol_name_ref.starts_with(
3410 g_objc_v2_prefix_metaclass)) {
3411 symbol_name_non_abi_mangled =
3415 g_objc_v2_prefix_metaclass.size();
3417 demangled_is_synthesized =
true;
3418 }
else if (symbol_name_ref.starts_with(
3419 g_objc_v2_prefix_ivar)) {
3420 symbol_name_non_abi_mangled =
3424 g_objc_v2_prefix_ivar.size();
3426 demangled_is_synthesized =
true;
3430 }
else if (symbol_sect_name &&
3431 ::strstr(symbol_sect_name,
3432 "__gcc_except_tab") ==
3438 }
else if (symbol_sect_name &&
3439 ::strstr(symbol_sect_name,
"__IMPORT") ==
3442 }
else if (symbol_section->IsDescendant(
3443 objc_section_sp.get())) {
3445 if (symbol_name && symbol_name[0] ==
'.') {
3446 llvm::StringRef symbol_name_ref(symbol_name);
3448 g_objc_v1_prefix_class(
".objc_class_name_");
3449 if (symbol_name_ref.starts_with(
3450 g_objc_v1_prefix_class)) {
3451 symbol_name_non_abi_mangled = symbol_name;
3452 symbol_name = symbol_name +
3453 g_objc_v1_prefix_class.size();
3455 demangled_is_synthesized =
true;
3466 uint64_t symbol_value = nlist.n_value;
3467 if (symbol_name_non_abi_mangled) {
3473 if (symbol_name && symbol_name[0] ==
'_') {
3480 if (is_gsym && is_debug) {
3481 const char *gsym_name =
3487 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3491 if (symbol_section) {
3492 const addr_t section_file_addr =
3493 symbol_section->GetFileAddress();
3494 if (symbol_byte_size == 0 &&
3495 function_starts_count > 0) {
3496 addr_t symbol_lookup_file_addr = nlist.n_value;
3501 FunctionStarts::Entry *func_start_entry =
3502 function_starts.FindEntry(symbol_lookup_file_addr,
3504 if (is_arm && func_start_entry) {
3508 if (func_start_entry->addr !=
3509 symbol_lookup_file_addr &&
3510 func_start_entry->addr !=
3511 (symbol_lookup_file_addr + 1)) {
3513 func_start_entry = NULL;
3516 if (func_start_entry) {
3517 func_start_entry->data =
true;
3519 addr_t symbol_file_addr = func_start_entry->addr;
3520 uint32_t symbol_flags = 0;
3522 if (symbol_file_addr & 1)
3527 const FunctionStarts::Entry *next_func_start_entry =
3528 function_starts.FindNextEntry(func_start_entry);
3529 const addr_t section_end_file_addr =
3531 symbol_section->GetByteSize();
3532 if (next_func_start_entry) {
3533 addr_t next_symbol_file_addr =
3534 next_func_start_entry->addr;
3540 symbol_byte_size = std::min<lldb::addr_t>(
3541 next_symbol_file_addr - symbol_file_addr,
3542 section_end_file_addr - symbol_file_addr);
3545 section_end_file_addr - symbol_file_addr;
3549 symbol_value -= section_file_addr;
3552 if (is_debug ==
false) {
3560 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3561 if (range.first != range.second) {
3562 bool found_it =
false;
3563 for (
auto pos = range.first; pos != range.second;
3565 if (sym[sym_idx].GetMangled().
GetName(
3569 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3575 sym[sym_idx].IsExternal());
3576 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3578 if (resolver_addresses.find(nlist.n_value) !=
3579 resolver_addresses.end())
3581 sym[sym_idx].
Clear();
3589 if (resolver_addresses.find(nlist.n_value) !=
3590 resolver_addresses.end())
3602 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3604 if (range.first != range.second) {
3605 bool found_it =
false;
3606 for (
auto pos = range.first; pos != range.second;
3608 if (sym[sym_idx].GetMangled().
GetName(
3612 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3618 sym[sym_idx].IsExternal());
3619 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3621 sym[sym_idx].
Clear();
3629 const char *gsym_name =
3637 ConstNameToSymbolIndexMap::const_iterator pos =
3638 N_GSYM_name_to_sym_idx.find(gsym_name);
3639 if (pos != N_GSYM_name_to_sym_idx.end()) {
3640 const uint32_t GSYM_sym_idx = pos->second;
3641 m_nlist_idx_to_sym_idx[nlist_idx] =
3650 add_symbol_addr(sym[GSYM_sym_idx]
3657 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3659 sym[sym_idx].
Clear();
3667 sym[sym_idx].
SetID(nlist_idx);
3673 sym[sym_idx].GetAddress().GetFileAddress());
3675 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3677 if (symbol_byte_size > 0)
3680 if (demangled_is_synthesized)
3684 sym[sym_idx].
Clear();
3691 for (
const auto &pos : reexport_shlib_needs_fixup) {
3692 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3693 if (undef_pos != undefined_name_to_desc.end()) {
3694 const uint8_t dylib_ordinal =
3695 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3696 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3706 if (nlist_data.GetByteSize() > 0) {
3710 if (sym ==
nullptr) {
3716 if (unmapped_local_symbols_found) {
3718 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3724 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3725 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3726 UndefinedNameToDescMap undefined_name_to_desc;
3727 SymbolIndexToName reexport_shlib_needs_fixup;
3735 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3737 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3738 if (is_debug != debug_only)
3741 const char *symbol_name_non_abi_mangled =
nullptr;
3742 const char *symbol_name =
nullptr;
3744 if (have_strtab_data) {
3745 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3747 if (symbol_name ==
nullptr) {
3751 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3753 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3756 if (symbol_name[0] ==
'\0')
3757 symbol_name =
nullptr;
3759 const addr_t str_addr = strtab_addr + nlist.n_strx;
3761 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3763 symbol_name = memory_symbol_name.c_str();
3769 bool add_nlist =
true;
3770 bool is_gsym =
false;
3771 bool demangled_is_synthesized =
false;
3772 bool set_value =
true;
3774 assert(sym_idx < num_syms);
3778 switch (nlist.n_type) {
3795 if (symbol_name && symbol_name[0] ==
'_' && symbol_name[1] ==
'O') {
3796 llvm::StringRef symbol_name_ref(symbol_name);
3797 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
3798 symbol_name_non_abi_mangled = symbol_name + 1;
3799 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3801 demangled_is_synthesized =
true;
3803 }
else if (symbol_name_ref.starts_with(
3804 g_objc_v2_prefix_metaclass)) {
3805 symbol_name_non_abi_mangled = symbol_name + 1;
3806 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3808 demangled_is_synthesized =
true;
3809 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
3810 symbol_name_non_abi_mangled = symbol_name + 1;
3811 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3813 demangled_is_synthesized =
true;
3816 if (nlist.n_value != 0)
3818 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3833 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3835 N_FUN_addr_to_sym_idx.insert(
3836 std::make_pair(nlist.n_value, sym_idx));
3840 N_FUN_indexes.push_back(sym_idx);
3844 if (!N_FUN_indexes.empty()) {
3849 N_FUN_indexes.pop_back();
3860 N_STSYM_addr_to_sym_idx.insert(
3861 std::make_pair(nlist.n_value, sym_idx));
3862 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3863 if (symbol_name && symbol_name[0]) {
3871 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3902 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3914 if (symbol_name ==
nullptr) {
3925 N_NSYM_indexes.clear();
3926 N_INCL_indexes.clear();
3927 N_BRAC_indexes.clear();
3928 N_COMM_indexes.clear();
3929 N_FUN_indexes.clear();
3935 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3936 if (N_SO_has_full_path) {
3937 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3942 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3947 N_SO_index = sym_idx;
3949 }
else if ((N_SO_index == sym_idx - 1) &&
3950 ((sym_idx - 1) < num_syms)) {
3954 const char *so_path =
3956 if (so_path && so_path[0]) {
3957 std::string full_so_path(so_path);
3958 const size_t double_slash_pos = full_so_path.find(
"//");
3959 if (double_slash_pos != std::string::npos) {
3967 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3968 FileSpec::Style::native);
3971 full_so_path.erase(0, double_slash_pos + 1);
3975 if (*full_so_path.rbegin() !=
'/')
3976 full_so_path +=
'/';
3977 full_so_path += symbol_name;
3981 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3985 N_SO_index = sym_idx;
4005 N_INCL_indexes.push_back(sym_idx);
4014 if (!N_INCL_indexes.empty()) {
4018 N_INCL_indexes.pop_back();
4053 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4062 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4063 N_BRAC_indexes.push_back(sym_idx);
4072 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4073 if (!N_BRAC_indexes.empty()) {
4077 N_BRAC_indexes.pop_back();
4093 N_COMM_indexes.push_back(sym_idx);
4098 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4107 if (!N_COMM_indexes.empty()) {
4111 N_COMM_indexes.pop_back();
4125 uint8_t n_type = N_TYPE & nlist.n_type;
4126 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
4130 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4131 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
4134 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
4137 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4138 indirect_symbol_names.insert(
4139 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
4145 if (symbol_name && symbol_name[0]) {
4147 ((symbol_name[0] ==
'_') ? 1 : 0));
4148 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4161 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4163 if (!symbol_section) {
4169 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4172 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4174 switch (section_type) {
4175 case S_CSTRING_LITERALS:
4178 case S_4BYTE_LITERALS:
4181 case S_8BYTE_LITERALS:
4184 case S_LITERAL_POINTERS:
4187 case S_NON_LAZY_SYMBOL_POINTERS:
4190 case S_LAZY_SYMBOL_POINTERS:
4193 case S_SYMBOL_STUBS:
4197 case S_MOD_INIT_FUNC_POINTERS:
4200 case S_MOD_TERM_FUNC_POINTERS:
4207 case S_16BYTE_LITERALS:
4213 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4217 switch (symbol_section->GetType()) {
4239 const char *symbol_sect_name =
4240 symbol_section->GetName().AsCString();
4241 if (symbol_section->IsDescendant(text_section_sp.get())) {
4242 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4243 S_ATTR_SELF_MODIFYING_CODE |
4244 S_ATTR_SOME_INSTRUCTIONS))
4248 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4249 symbol_section->IsDescendant(
4250 data_dirty_section_sp.get()) ||
4251 symbol_section->IsDescendant(
4252 data_const_section_sp.get())) {
4253 if (symbol_sect_name &&
4254 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4258 llvm::StringRef symbol_name_ref(symbol_name);
4259 if (symbol_name_ref.starts_with(
"_OBJC_")) {
4260 llvm::StringRef g_objc_v2_prefix_class(
4262 llvm::StringRef g_objc_v2_prefix_metaclass(
4263 "_OBJC_METACLASS_$_");
4264 llvm::StringRef g_objc_v2_prefix_ivar(
4266 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
4267 symbol_name_non_abi_mangled = symbol_name + 1;
4269 symbol_name + g_objc_v2_prefix_class.size();
4271 demangled_is_synthesized =
true;
4272 }
else if (symbol_name_ref.starts_with(
4273 g_objc_v2_prefix_metaclass)) {
4274 symbol_name_non_abi_mangled = symbol_name + 1;
4276 symbol_name + g_objc_v2_prefix_metaclass.size();
4278 demangled_is_synthesized =
true;
4279 }
else if (symbol_name_ref.starts_with(
4280 g_objc_v2_prefix_ivar)) {
4281 symbol_name_non_abi_mangled = symbol_name + 1;
4283 symbol_name + g_objc_v2_prefix_ivar.size();
4285 demangled_is_synthesized =
true;
4289 }
else if (symbol_sect_name &&
4290 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4296 }
else if (symbol_sect_name &&
4297 ::strstr(symbol_sect_name,
"__IMPORT") ==
4300 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4302 if (symbol_name && symbol_name[0] ==
'.') {
4303 llvm::StringRef symbol_name_ref(symbol_name);
4304 llvm::StringRef g_objc_v1_prefix_class(
4305 ".objc_class_name_");
4306 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4307 symbol_name_non_abi_mangled = symbol_name;
4308 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4310 demangled_is_synthesized =
true;
4321 sym[sym_idx].
Clear();
4325 uint64_t symbol_value = nlist.n_value;
4327 if (symbol_name_non_abi_mangled) {
4333 if (symbol_name && symbol_name[0] ==
'_') {
4344 const char *gsym_name = sym[sym_idx]
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;
4359 FunctionStarts::Entry *func_start_entry =
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;
4377 const FunctionStarts::Entry *next_func_start_entry =
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) {
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) {
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]
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())
4553 int trie_symbol_table_augment_count = 0;
4554 for (
auto &e : external_sym_trie_entries) {
4555 if (!symbols_added.contains(e.entry.address))
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)) {
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.contains(function_starts.GetEntryRef(i).addr))
4603 ++num_synthetic_function_symbols;
4606 if (num_synthetic_function_symbols > 0) {
4607 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4608 num_syms = sym_idx + num_synthetic_function_symbols;
4609 sym = symtab.
Resize(num_syms);
4611 for (i = 0; i < function_starts_count; ++i) {
4612 const FunctionStarts::Entry *func_start_entry =
4613 function_starts.GetEntryAtIndex(i);
4614 if (!symbols_added.contains(func_start_entry->addr)) {
4615 addr_t symbol_file_addr = func_start_entry->addr;
4616 uint32_t symbol_flags = 0;
4617 if (func_start_entry->data)
4620 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4622 uint32_t symbol_byte_size = 0;
4623 if (symbol_section) {
4624 const addr_t section_file_addr = symbol_section->GetFileAddress();
4625 const FunctionStarts::Entry *next_func_start_entry =
4626 function_starts.FindNextEntry(func_start_entry);
4627 const addr_t section_end_file_addr =
4628 section_file_addr + symbol_section->GetByteSize();
4629 if (next_func_start_entry) {
4630 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4633 symbol_byte_size = std::min<lldb::addr_t>(
4634 next_symbol_file_addr - symbol_file_addr,
4635 section_end_file_addr - symbol_file_addr);
4637 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4639 sym[sym_idx].
SetID(synthetic_sym_id++);
4649 sym[sym_idx].
SetFlags(symbol_flags);
4650 if (symbol_byte_size)
4662 if (sym_idx < num_syms) {
4664 sym = symtab.
Resize(num_syms);
4669 if (indirect_symbol_index_data.GetByteSize()) {
4670 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4671 m_nlist_idx_to_sym_idx.end();
4678 if (symbol_stub_byte_size == 0)
4681 const uint32_t num_symbol_stubs =
4684 if (num_symbol_stubs == 0)
4687 const uint32_t symbol_stub_index_offset =
4689 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4690 const uint32_t symbol_stub_index =
4691 symbol_stub_index_offset + stub_idx;
4694 (stub_idx * symbol_stub_byte_size);
4696 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4697 symbol_stub_offset, 4)) {
4698 const uint32_t stub_sym_id =
4699 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4700 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4703 NListIndexToSymbolIndexMap::const_iterator index_pos =
4704 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4705 Symbol *stub_symbol =
nullptr;
4706 if (index_pos != end_index_pos) {
4717 Address so_addr(symbol_stub_addr, section_list);
4724 if (resolver_addresses.find(symbol_stub_addr) ==
4725 resolver_addresses.end())
4735 if (sym_idx >= num_syms) {
4736 sym = symtab.
Resize(++num_syms);
4737 stub_symbol =
nullptr;
4739 sym[sym_idx].
SetID(synthetic_sym_id++);
4740 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4741 if (resolver_addresses.find(symbol_stub_addr) ==
4742 resolver_addresses.end())
4754 log->
Warning(
"symbol stub referencing symbol table symbol "
4755 "%u that isn't in our minimal symbol table, "
4766 if (!reexport_trie_entries.empty()) {
4767 for (
const auto &e : reexport_trie_entries) {
4768 if (e.entry.import_name) {
4771 if (indirect_symbol_names.find(e.entry.name) ==
4772 indirect_symbol_names.end()) {
4774 if (sym_idx >= num_syms)
4775 sym = symtab.
Resize(++num_syms);
4776 sym[sym_idx].
SetID(synthetic_sym_id++);
4781 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
4795 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4796 s->
Printf(
"%p: ",
static_cast<void *
>(
this));
4803 *s <<
", file = '" <<
m_file;
4807 base_spec, all_specs);
4808 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
4833 llvm::MachO::uuid_command load_cmd;
4836 for (i = 0; i < header.ncmds; ++i) {
4838 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
4841 if (load_cmd.cmd == LC_UUID) {
4842 const uint8_t *uuid_bytes = data.
PeekData(offset, 16);
4848 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4849 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4850 0xbb, 0x14, 0xf0, 0x0d};
4852 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4855 return UUID(uuid_bytes, 16);
4859 offset = cmd_offset + load_cmd.cmdsize;
4866 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4867 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4868 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4869 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4870 case llvm::MachO::LC_VERSION_MIN_TVOS:
4871 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4872 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4873 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4875 llvm_unreachable(
"unexpected LC_VERSION load command");
4881 llvm::StringRef os_type;
4882 llvm::StringRef environment;
4883 OSEnv(uint32_t cmd) {
4885 case llvm::MachO::PLATFORM_MACOS:
4886 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4888 case llvm::MachO::PLATFORM_IOS:
4889 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4891 case llvm::MachO::PLATFORM_TVOS:
4892 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4894 case llvm::MachO::PLATFORM_WATCHOS:
4895 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4897 case llvm::MachO::PLATFORM_BRIDGEOS:
4898 os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
4900 case llvm::MachO::PLATFORM_DRIVERKIT:
4901 os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);
4903 case llvm::MachO::PLATFORM_MACCATALYST:
4904 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4905 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
4907 case llvm::MachO::PLATFORM_IOSSIMULATOR:
4908 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4910 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4912 case llvm::MachO::PLATFORM_TVOSSIMULATOR:
4913 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4915 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4917 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
4918 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4920 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4922 case llvm::MachO::PLATFORM_XROS:
4923 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4925 case llvm::MachO::PLATFORM_XROS_SIMULATOR:
4926 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4928 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4931 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
4932 LLDB_LOGF(log,
"unsupported platform in LC_BUILD_VERSION");
4939 uint32_t major_version, minor_version, patch_version;
4940 MinOS(uint32_t version)
4941 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),
4942 patch_version(version & 0xffu) {}
4953 if (!base_arch.IsValid())
4956 bool found_any =
false;
4957 auto add_triple = [&](
const llvm::Triple &triple) {
4958 auto spec = base_spec;
4960 if (spec.GetArchitecture().IsValid()) {
4968 llvm::Triple base_triple = base_arch.GetTriple();
4969 base_triple.setOS(llvm::Triple::UnknownOS);
4970 base_triple.setOSName(llvm::StringRef());
4972 if (header.filetype == MH_PRELOAD) {
4973 if (header.cputype == CPU_TYPE_ARM) {
4979 base_triple.setVendor(llvm::Triple::Apple);
4984 base_triple.setVendor(llvm::Triple::UnknownVendor);
4985 base_triple.setVendorName(llvm::StringRef());
4987 return add_triple(base_triple);
4990 llvm::MachO::load_command load_cmd;
4995 for (uint32_t i = 0; i < header.ncmds; ++i) {
4997 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
5000 llvm::MachO::version_min_command version_min;
5001 switch (load_cmd.cmd) {
5002 case llvm::MachO::LC_VERSION_MIN_MACOSX:
5003 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
5004 case llvm::MachO::LC_VERSION_MIN_TVOS:
5005 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
5006 if (load_cmd.cmdsize !=
sizeof(version_min))
5011 MinOS min_os(version_min.version);
5012 llvm::SmallString<32> os_name;
5013 llvm::raw_svector_ostream os(os_name);
5014 os <<
GetOSName(load_cmd.cmd) << min_os.major_version <<
'.'
5015 << min_os.minor_version <<
'.' << min_os.patch_version;
5017 auto triple = base_triple;
5018 triple.setOSName(os.str());
5021 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
5022 (base_triple.getArch() == llvm::Triple::x86_64 ||
5023 base_triple.getArch() == llvm::Triple::x86)) {
5030 triple.setEnvironment(llvm::Triple::Simulator);
5039 offset = cmd_offset + load_cmd.cmdsize;
5045 for (uint32_t i = 0; i < header.ncmds; ++i) {
5047 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
5051 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
5052 llvm::MachO::build_version_command build_version;
5053 if (load_cmd.cmdsize <
sizeof(build_version)) {
5057 if (data.
ExtractBytes(cmd_offset,
sizeof(build_version),
5060 MinOS min_os(build_version.minos);
5061 OSEnv os_env(build_version.platform);
5062 llvm::SmallString<16> os_name;
5063 llvm::raw_svector_ostream os(os_name);
5064 os << os_env.os_type << min_os.major_version <<
'.'
5065 << min_os.minor_version <<
'.' << min_os.patch_version;
5066 auto triple = base_triple;
5067 triple.setOSName(os.str());
5069 if (!os_env.environment.empty())
5070 triple.setEnvironmentName(os_env.environment);
5074 offset = cmd_offset + load_cmd.cmdsize;
5078 add_triple(base_triple);
5083 ModuleSP module_sp,
const llvm::MachO::mach_header &header,
5088 base_spec, all_specs);
5093 const ArchSpec &module_arch = module_sp->GetArchitecture();
5094 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
5111 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5122 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5123 llvm::MachO::load_command load_cmd;
5125 std::vector<std::string> rpath_paths;
5126 std::vector<std::string> rpath_relative_paths;
5127 std::vector<std::string> at_exec_relative_paths;
5129 for (i = 0; i <
m_header.ncmds; ++i) {
5130 const uint32_t cmd_offset = offset;
5134 switch (load_cmd.cmd) {
5137 case LC_LOAD_WEAK_DYLIB:
5138 case LC_REEXPORT_DYLIB:
5139 case LC_LOAD_DYLINKER:
5141 case LC_LOAD_UPWARD_DYLIB: {
5142 uint32_t name_offset = cmd_offset +
m_data.
GetU32(&offset);
5145 if (load_cmd.cmd == LC_RPATH)
5146 rpath_paths.push_back(path);
5148 if (path[0] ==
'@') {
5149 if (strncmp(path,
"@rpath", strlen(
"@rpath")) == 0)
5150 rpath_relative_paths.push_back(path + strlen(
"@rpath"));
5151 else if (strncmp(path,
"@executable_path",
5152 strlen(
"@executable_path")) == 0)
5153 at_exec_relative_paths.push_back(path +
5154 strlen(
"@executable_path"));
5167 offset = cmd_offset + load_cmd.cmdsize;
5173 if (!rpath_paths.empty()) {
5175 std::string loader_path(
"@loader_path");
5176 std::string executable_path(
"@executable_path");
5177 for (
auto &rpath : rpath_paths) {
5178 if (llvm::StringRef(rpath).starts_with(loader_path)) {
5179 rpath.erase(0, loader_path.size());
5181 }
else if (llvm::StringRef(rpath).starts_with(executable_path)) {
5182 rpath.erase(0, executable_path.size());
5187 for (
const auto &rpath_relative_path : rpath_relative_paths) {
5188 for (
const auto &rpath : rpath_paths) {
5189 std::string path = rpath;
5190 path += rpath_relative_path;
5210 for (
const auto &at_exec_relative_path : at_exec_relative_paths) {
5258 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5259 llvm::MachO::load_command load_cmd;
5265 for (i = 0; i <
m_header.ncmds; ++i) {
5270 switch (load_cmd.cmd) {
5273 while (offset < cmd_offset + load_cmd.cmdsize) {
5282 case llvm::MachO::CPU_TYPE_ARM:
5293 case llvm::MachO::CPU_TYPE_ARM64:
5294 case llvm::MachO::CPU_TYPE_ARM64_32:
5303 case llvm::MachO::CPU_TYPE_I386:
5313 case llvm::MachO::CPU_TYPE_X86_64:
5330 offset += count * 4;
5337 if (text_segment_sp) {
5339 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5350 offset = cmd_offset + load_cmd.cmdsize;
5356 ConstString(
"_dyld_start"), SymbolType::eSymbolTypeCode,
5380 module_sp->FindSymbolsWithNameAndType(
ConstString(
"start"),
5399 if (text_segment_sp) {
5410 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5415 llvm::MachO::thread_command thread_cmd;
5416 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5417 const uint32_t cmd_offset = offset;
5421 if (thread_cmd.cmd == LC_THREAD) {
5426 offset = cmd_offset + thread_cmd.cmdsize;
5433std::vector<std::tuple<offset_t, offset_t>>
5435 std::vector<std::tuple<offset_t, offset_t>> results;
5438 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5441 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5442 const uint32_t cmd_offset = offset;
5443 llvm::MachO::load_command lc = {};
5446 if (lc.cmd == LC_NOTE) {
5447 char data_owner[17];
5449 data_owner[16] =
'\0';
5452 if (name == data_owner) {
5455 results.push_back({payload_offset, payload_size});
5458 offset = cmd_offset + lc.cmdsize;
5466 GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));
5469 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5472 for (
auto lc_note : lc_notes) {
5473 offset_t payload_offset = std::get<0>(lc_note);
5474 offset_t payload_size = std::get<1>(lc_note);
5476 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr) {
5478 uint32_t strsize = payload_size -
sizeof(uint32_t);
5479 std::string result(strsize,
'\0');
5481 LLDB_LOGF(log,
"LC_NOTE 'kern ver str' found with text '%s'",
5491 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5492 const uint32_t cmd_offset = offset;
5493 llvm::MachO::ident_command ident_command;
5494 if (
m_data.
GetU32(&offset, &ident_command, 2) ==
nullptr)
5496 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
5497 std::string result(ident_command.cmdsize,
'\0');
5498 if (
m_data.
CopyData(offset, ident_command.cmdsize, result.data()) ==
5499 ident_command.cmdsize) {
5500 LLDB_LOGF(log,
"LC_IDENT found with text '%s'", result.c_str());
5504 offset = cmd_offset + ident_command.cmdsize;
5516 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5518 for (
auto lc_note : lc_notes) {
5519 offset_t payload_offset = std::get<0>(lc_note);
5521 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr) {
5526 "LC_NOTE 'addrable bits' v3 found, value %d "
5534 if (lo_addr_bits == hi_addr_bits)
5538 LLDB_LOGF(log,
"LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
5539 lo_addr_bits, hi_addr_bits);
5544 return addressable_bits;
5548 bool &value_is_offset,
5552 GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));
5554 value_is_offset =
false;
5556 uint32_t log2_pagesize = 0;
5557 uint32_t platform = 0;
5560 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5563 for (
auto lc_note : lc_notes) {
5564 offset_t payload_offset = std::get<0>(lc_note);
5599 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr &&
5601 uint32_t binspec_type = 0;
5603 memset(raw_uuid, 0,
sizeof(
uuid_t));
5610 if (version > 1 && !
m_data.
GetU64(&payload_offset, &slide, 1))
5614 value_is_offset =
true;
5621 const char *typestr =
"unrecognized type";
5622 switch (binspec_type) {
5629 typestr =
"xnu kernel";
5633 typestr =
"userland dyld";
5637 typestr =
"standalone";
5641 "LC_NOTE 'main bin spec' found, version %d type %d "
5642 "(%s), value 0x%" PRIx64
" value-is-slide==%s uuid %s",
5643 version, type, typestr, value,
5644 value_is_offset ?
"true" :
"false",
5646 if (!
m_data.
GetU32(&payload_offset, &log2_pagesize, 1))
5648 if (version > 1 && !
m_data.
GetU32(&payload_offset, &platform, 1))
5662 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5664 Log *log(
GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));
5666 for (
auto lc_note : lc_notes) {
5667 offset_t payload_offset = std::get<0>(lc_note);
5668 offset_t strsize = std::get<1>(lc_note);
5669 std::string buf(strsize,
'\0');
5670 if (
m_data.
CopyData(payload_offset, strsize, buf.data()) != strsize) {
5672 "Unable to read %" PRIu64
5673 " bytes of 'process metadata' LC_NOTE JSON contents",
5677 while (buf.back() ==
'\0')
5678 buf.resize(buf.size() - 1);
5682 LLDB_LOGF(log,
"Unable to read 'process metadata' LC_NOTE, did not "
5683 "get a dictionary.");
5689 "'process metadata' LC_NOTE does not have a 'threads' key");
5693 LLDB_LOGF(log,
"Unable to read 'process metadata' LC_NOTE, number of "
5694 "threads does not match number of LC_THREADS.");
5697 const size_t num_threads = threads->
GetSize();
5698 for (
size_t i = 0; i < num_threads; i++) {
5699 std::optional<StructuredData::Dictionary *> maybe_thread =
5701 if (!maybe_thread) {
5703 "Unable to read 'process metadata' LC_NOTE, threads "
5704 "array does not have a dictionary at index %zu.",
5713 tids.push_back(tid);
5718 logmsg.
Printf(
"LC_NOTE 'process metadata' found: ");
5719 dict->
Dump(logmsg,
false);
5735 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5741 if (thread_context_file_range) {
5747 case llvm::MachO::CPU_TYPE_ARM64:
5748 case llvm::MachO::CPU_TYPE_ARM64_32:
5750 std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);
5753 case llvm::MachO::CPU_TYPE_ARM:
5755 std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);
5758 case llvm::MachO::CPU_TYPE_I386:
5760 std::make_shared<RegisterContextDarwin_i386_Mach>(thread, data);
5763 case llvm::MachO::CPU_TYPE_X86_64:
5765 std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
5808 case MH_KEXT_BUNDLE:
5836 if (
m_header.flags & MH_DYLDLINK) {
5864 case MH_KEXT_BUNDLE:
5875 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5876 llvm::MachO::dylib_command load_cmd;
5878 uint32_t version_cmd = 0;
5879 uint64_t version = 0;
5881 for (i = 0; i <
m_header.ncmds; ++i) {
5886 if (load_cmd.cmd == LC_ID_DYLIB) {
5887 if (version_cmd == 0) {
5888 version_cmd = load_cmd.cmd;
5889 if (
m_data.
GetU32(&offset, &load_cmd.dylib, 4) ==
nullptr)
5891 version = load_cmd.dylib.current_version;
5896 offset = cmd_offset + load_cmd.cmdsize;
5899 if (version_cmd == LC_ID_DYLIB) {
5900 unsigned major = (version & 0xFFFF0000ull) >> 16;
5901 unsigned minor = (version & 0x0000FF00ull) >> 8;
5902 unsigned subminor = (version & 0x000000FFull);
5903 return llvm::VersionTuple(major, minor, subminor);
5906 return llvm::VersionTuple();
5913 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5930 private_shared_cache);
5932 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
5935 "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64,
5958#if defined(__APPLE__)
5959 uint8_t *(*dyld_get_all_image_infos)(void);
5960 dyld_get_all_image_infos =
5961 (uint8_t * (*)()) dlsym(RTLD_DEFAULT,
"_dyld_get_all_image_infos");
5962 if (dyld_get_all_image_infos) {
5963 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5964 if (dyld_all_image_infos_address) {
5965 uint32_t *version = (uint32_t *)
5966 dyld_all_image_infos_address;
5967 if (*version >= 13) {
5968 uuid_t *sharedCacheUUID_address = 0;
5969 int wordsize =
sizeof(uint8_t *);
5970 if (wordsize == 8) {
5971 sharedCacheUUID_address =
5972 (
uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5977 *)((uint8_t *)dyld_all_image_infos_address +
5980 sharedCacheUUID_address =
5981 (
uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5983 if (*version >= 15) {
5987 *)((uint8_t *)dyld_all_image_infos_address +
5991 uuid =
UUID(sharedCacheUUID_address,
sizeof(
uuid_t));
5997 unsigned int task, uint64_t timestamp,
5998 unsigned int *kernelError);
5999 void (*dyld_process_info_get_cache)(
void *info,
void *cacheInfo);
6002 dyld_process_info_create = (
void *(*)(
unsigned int , uint64_t,
6004 dlsym(RTLD_DEFAULT,
"_dyld_process_info_create");
6005 dyld_process_info_get_cache = (void (*)(
void *,
void *))dlsym(
6006 RTLD_DEFAULT,
"_dyld_process_info_get_cache");
6007 dyld_process_info_release =
6008 (void (*)(
void *))dlsym(RTLD_DEFAULT,
"_dyld_process_info_release");
6010 if (dyld_process_info_create && dyld_process_info_get_cache) {
6011 unsigned int kern_ret;
6017 dyld_process_info_get_cache(process_info, &sc_info);
6022 dyld_process_info_release(process_info);
6026 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
6029 "lldb's in-memory shared cache has a UUID of %s base address of "
6038 for (
size_t i = 0; i < ncmds; i++) {
6040 llvm::MachO::load_command lc = {};
6041 if (data.
GetU32(&offset, &lc.cmd, 2) ==
nullptr)
6044 uint32_t version = 0;
6045 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
6046 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
6047 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
6048 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
6056 version = data.
GetU32(&offset);
6057 }
else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
6067 offset +=
sizeof(uint32_t);
6068 version = data.
GetU32(&offset);
6072 const uint32_t xxxx = version >> 16;
6073 const uint32_t yy = (version >> 8) & 0xffu;
6074 const uint32_t zz = version & 0xffu;
6076 return llvm::VersionTuple(xxxx, yy, zz);
6078 offset = load_cmd_offset + lc.cmdsize;
6080 return llvm::VersionTuple();
6098 return m_header.filetype == llvm::MachO::MH_DYLINKER;
6104 return m_header.filetype == llvm::MachO::MH_DSYM;
6130 return text_segment_sp.get();
6132 const size_t num_sections = section_list->
GetSize();
6133 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6145 const bool is_dsym = (
m_header.filetype == MH_DSYM);
6165 const bool is_memory_image = (bool)
m_process_wp.lock();
6177 if (module_sp && header_section && section &&
6181 return section->
GetFileAddress() - file_addr + header_load_address;
6187 bool value_is_offset) {
6196 size_t num_loaded_sections = 0;
6197 const size_t num_sections = section_list->
GetSize();
6201 const bool warn_multiple =
true;
6203 if (value_is_offset) {
6205 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6211 section_sp, section_sp->GetFileAddress() + value,
6213 ++num_loaded_sections;
6220 if (mach_header_section) {
6221 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6226 value, mach_header_section, section_sp.get());
6229 section_sp, section_load_addr, warn_multiple))
6230 ++num_loaded_sections;
6235 return num_loaded_sections > 0;
6318 Target &target = process_sp->GetTarget();
6324 if (core_style == SaveCoreStyle::eSaveCoreStackOnly)
6327 std::set<std::string> executing_uuids;
6328 ThreadList &thread_list(process_sp->GetThreadList());
6329 for (uint32_t i = 0; i < thread_list.
GetSize(); i++) {
6331 uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
6332 for (uint32_t j = 0; j < stack_frame_count; j++) {
6333 StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
6334 Address pc = stack_frame_sp->GetFrameCodeAddress();
6337 UUID uuid = module_sp->GetUUID();
6345 size_t modules_count = modules.
GetSize();
6363 std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;
6364 for (
size_t i = 0; i < modules_count; i++) {
6368 size_t sections_count = sections->
GetSize();
6369 std::vector<segment_vmaddr> segment_vmaddrs;
6370 for (
size_t j = 0; j < sections_count; j++) {
6372 if (!section->GetParent().get()) {
6373 addr_t vmaddr = section->GetLoadBaseAddress(&target);
6386 seg_vmaddr.
vmaddr = vmaddr;
6388 segment_vmaddrs.push_back(seg_vmaddr);
6391 modules_segment_vmaddrs.push_back(segment_vmaddrs);
6394 offset_t size_of_vmaddr_structs = 0;
6395 for (
size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6396 size_of_vmaddr_structs +=
6400 offset_t size_of_filepath_cstrings = 0;
6401 for (
size_t i = 0; i < modules_count; i++) {
6403 size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;
6412 start_of_entries +
sizeof(
image_entry) * modules_count;
6413 offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;
6415 offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;
6421 offset_t current_string_offset = start_of_filenames;
6422 offset_t current_segaddrs_offset = start_of_seg_vmaddrs;
6423 std::vector<struct image_entry> image_entries;
6424 for (
size_t i = 0; i < modules_count; i++) {
6428 memcpy(&ent.
uuid, module_sp->GetUUID().GetBytes().data(),
sizeof(ent.
uuid));
6429 if (modules_segment_vmaddrs[i].size() > 0) {
6434 ObjectFile *objfile = module_sp->GetObjectFile();
6448 if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=
6449 executing_uuids.end())
6450 all_image_infos_payload.
PutHex32(1);
6452 all_image_infos_payload.
PutHex32(0);
6455 current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;
6460 for (
size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6461 if (modules_segment_vmaddrs[i].size() == 0)
6464 all_image_infos_payload.
PutRawBytes(segvm.segname,
sizeof(segvm.segname));
6465 all_image_infos_payload.
PutHex64(segvm.vmaddr);
6466 all_image_infos_payload.
PutHex64(segvm.unused);
6470 for (
size_t i = 0; i < modules_count; i++) {
6472 std::string filepath = module_sp->GetFileSpec().GetPath();
6473 all_image_infos_payload.
PutRawBytes(filepath.data(), filepath.size() + 1);
6476 return final_file_offset;
6494 if (core_style == SaveCoreStyle::eSaveCoreUnspecified)
6495 core_style = SaveCoreStyle::eSaveCoreDirtyOnly;
6497 Target &target = process_sp->GetTarget();
6499 const llvm::Triple &target_triple = target_arch.
GetTriple();
6500 if (target_triple.getVendor() == llvm::Triple::Apple &&
6501 (target_triple.getOS() == llvm::Triple::MacOSX ||
6502 target_triple.getOS() == llvm::Triple::IOS ||
6503 target_triple.getOS() == llvm::Triple::WatchOS ||
6504 target_triple.getOS() == llvm::Triple::TvOS ||
6505 target_triple.getOS() == llvm::Triple::XROS)) {
6508 bool make_core =
false;
6510 case llvm::Triple::aarch64:
6511 case llvm::Triple::aarch64_32:
6512 case llvm::Triple::arm:
6513 case llvm::Triple::thumb:
6514 case llvm::Triple::x86:
6515 case llvm::Triple::x86_64:
6519 error.SetErrorStringWithFormat(
"unsupported core architecture: %s",
6520 target_triple.str().c_str());
6526 error = process_sp->CalculateCoreFileSaveRanges(core_style, core_ranges);
6527 if (
error.Success()) {
6530 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6531 for (
const auto &core_range : core_ranges) {
6532 uint32_t cmd_type = LC_SEGMENT_64;
6533 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6534 if (addr_byte_size == 4) {
6535 cmd_type = LC_SEGMENT;
6536 segment_size =
sizeof(llvm::MachO::segment_command);
6540 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6542 uint32_t vm_prot = 0;
6543 if (core_range.lldb_permissions & ePermissionsReadable)
6544 vm_prot |= VM_PROT_READ;
6545 if (core_range.lldb_permissions & ePermissionsWritable)
6546 vm_prot |= VM_PROT_WRITE;
6547 if (core_range.lldb_permissions & ePermissionsExecutable)
6548 vm_prot |= VM_PROT_EXECUTE;
6549 const addr_t vm_addr = core_range.range.start();
6550 const addr_t vm_size = core_range.range.size();
6551 llvm::MachO::segment_command_64 segment = {
6563 segment_load_commands.push_back(segment);
6568 llvm::MachO::mach_header_64 mach_header;
6569 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6572 mach_header.filetype = MH_CORE;
6573 mach_header.ncmds = segment_load_commands.size();
6574 mach_header.flags = 0;
6575 mach_header.reserved = 0;
6576 ThreadList &thread_list = process_sp->GetThreadList();
6577 const uint32_t num_threads = thread_list.
GetSize();
6583 std::vector<StreamString> LC_THREAD_datas(num_threads);
6584 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6586 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6587 LC_THREAD_data.SetByteOrder(byte_order);
6589 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6592 switch (mach_header.cputype) {
6593 case llvm::MachO::CPU_TYPE_ARM64:
6594 case llvm::MachO::CPU_TYPE_ARM64_32:
6596 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6599 case llvm::MachO::CPU_TYPE_ARM:
6601 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6604 case llvm::MachO::CPU_TYPE_I386:
6606 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6609 case llvm::MachO::CPU_TYPE_X86_64:
6611 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6618 if (addr_byte_size == 8) {
6619 mach_header.sizeofcmds = segment_load_commands.size() *
6620 sizeof(llvm::MachO::segment_command_64);
6622 mach_header.sizeofcmds = segment_load_commands.size() *
6623 sizeof(llvm::MachO::segment_command);
6627 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6628 ++mach_header.ncmds;
6629 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6634 uint64_t address_mask = process_sp->GetCodeAddressMask();
6637 mach_header.ncmds++;
6638 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6642 mach_header.ncmds++;
6643 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6646 mach_header.ncmds++;
6647 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6650 buffer.
PutHex32(mach_header.magic);
6651 buffer.
PutHex32(mach_header.cputype);
6652 buffer.
PutHex32(mach_header.cpusubtype);
6653 buffer.
PutHex32(mach_header.filetype);
6654 buffer.
PutHex32(mach_header.ncmds);
6655 buffer.
PutHex32(mach_header.sizeofcmds);
6656 buffer.
PutHex32(mach_header.flags);
6657 if (addr_byte_size == 8) {
6658 buffer.
PutHex32(mach_header.reserved);
6663 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6665 file_offset = llvm::alignTo(file_offset, 16);
6666 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6670 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6672 addrable_bits_lcnote_up->name =
"addrable bits";
6673 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6674 int bits = std::bitset<64>(~address_mask).count();
6675 addrable_bits_lcnote_up->payload.PutHex32(4);
6676 addrable_bits_lcnote_up->payload.PutHex32(
6678 addrable_bits_lcnote_up->payload.PutHex32(
6680 addrable_bits_lcnote_up->payload.PutHex32(0);
6682 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6684 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6688 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6690 thread_extrainfo_lcnote_up->name =
"process metadata";
6691 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6694 std::make_shared<StructuredData::Dictionary>());
6696 std::make_shared<StructuredData::Array>());
6697 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6700 std::make_shared<StructuredData::Dictionary>());
6701 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6702 threads->AddItem(thread);
6704 dict->AddItem(
"threads", threads);
6706 dict->Dump(strm,
false);
6710 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6711 file_offset = llvm::alignTo(file_offset, 16);
6712 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6715 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6717 all_image_infos_lcnote_up->name =
"all image infos";
6718 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6720 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6722 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6725 for (
auto &lcnote : lc_notes) {
6728 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6730 memset(namebuf, 0,
sizeof(namebuf));
6736 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6738 buffer.
PutHex64(lcnote->payload_file_offset);
6739 buffer.
PutHex64(lcnote->payload.GetSize());
6743 file_offset = llvm::alignTo(file_offset, 4096);
6745 for (
auto &segment : segment_load_commands) {
6746 segment.fileoff = file_offset;
6747 file_offset += segment.filesize;
6751 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6752 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6754 buffer.
PutHex32(8 + LC_THREAD_data_size);
6755 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6759 for (
const auto &segment : segment_load_commands) {
6762 buffer.
PutRawBytes(segment.segname,
sizeof(segment.segname));
6763 if (addr_byte_size == 8) {
6769 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmaddr));
6770 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmsize));
6771 buffer.
PutHex32(
static_cast<uint32_t
>(segment.fileoff));
6772 buffer.
PutHex32(
static_cast<uint32_t
>(segment.filesize));
6780 std::string core_file_path(outfile.
GetPath());
6785 error = core_file.takeError();
6788 uint8_t bytes[0x1000];
6790 size_t bytes_written = buffer.
GetString().size();
6792 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6793 if (
error.Success()) {
6795 for (
auto &lcnote : lc_notes) {
6796 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6798 error.SetErrorStringWithFormat(
"Unable to seek to corefile pos "
6799 "to write '%s' LC_NOTE payload",
6800 lcnote->name.c_str());
6803 bytes_written = lcnote->payload.GetSize();
6804 error = core_file.get()->Write(lcnote->payload.GetData(),
6806 if (!
error.Success())
6811 for (
const auto &segment : segment_load_commands) {
6812 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6813 error.SetErrorStringWithFormat(
6814 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6815 segment.fileoff, core_file_path.c_str());
6821 " bytes of data for memory region at 0x%" PRIx64
"\n",
6822 segment.vmsize, segment.vmaddr);
6823 addr_t bytes_left = segment.vmsize;
6824 addr_t addr = segment.vmaddr;
6826 while (bytes_left > 0 &&
error.Success()) {
6827 const size_t bytes_to_read =
6828 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6833 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6836 if (bytes_read == bytes_to_read) {
6837 size_t bytes_written = bytes_read;
6838 error = core_file.get()->Write(bytes, bytes_written);
6839 bytes_left -= bytes_read;
6844 memset(bytes, 0, bytes_to_read);
6845 size_t bytes_written = bytes_to_read;
6846 error = core_file.get()->Write(bytes, bytes_written);
6847 bytes_left -= bytes_to_read;
6848 addr += bytes_to_read;
6865 Log *log(
GetLog(LLDBLog::Object | LLDBLog::Symbols | LLDBLog::Process |
6866 LLDBLog::DynamicLoader));
6869 for (
auto lc_note : lc_notes) {
6870 offset_t payload_offset = std::get<0>(lc_note);
6877 uint64_t entries_fileoff =
m_data.
GetU64(&payload_offset);
6882 LLDB_LOGF(log,
"LC_NOTE 'all image infos' found version %d with %d images",
6884 payload_offset = entries_fileoff;
6885 for (uint32_t i = 0; i < imgcount; i++) {
6891 uint64_t load_address =
m_data.
GetU64(&payload_offset);
6893 uint32_t segment_count =
m_data.
GetU32(&payload_offset);
6894 uint32_t currently_executing =
m_data.
GetU32(&payload_offset);
6900 image_entry.currently_executing = currently_executing;
6902 offset_t seg_vmaddrs_offset = seg_addrs_offset;
6903 for (uint32_t j = 0; j < segment_count; j++) {
6907 seg_vmaddrs_offset += 16;
6909 seg_vmaddrs_offset += 8;
6911 std::tuple<ConstString, addr_t> new_seg{
ConstString(segname), vmaddr};
6912 image_entry.segment_load_addresses.push_back(new_seg);
6914 LLDB_LOGF(log,
" image entry: %s %s 0x%" PRIx64
" %s",
6918 image_entry.currently_executing ?
"currently executing"
6919 :
"not currently executing");
6925 for (
auto lc_note : lc_notes) {
6926 offset_t payload_offset = std::get<0>(lc_note);
6932 uint64_t load_address =
m_data.
GetU64(&payload_offset);
6944 "LC_NOTE 'load binary' found, filename %s uuid %s load "
6945 "address 0x%" PRIx64
" slide 0x%" PRIx64,
6949 :
"00000000-0000-0000-0000-000000000000",
6950 load_address, slide);
6959 Log *log =
GetLog(LLDBLog::Object | LLDBLog::DynamicLoader);
6962 bool found_platform_binary =
false;
6965 ModuleSP module_sp, local_filesystem_module_sp;
6977 "ObjectFileMachO::%s binary at 0x%" PRIx64
6978 " is a platform binary, has been handled by a Platform plugin.",
6996 const bool notify =
false;
6999 const bool allow_memory_image_last_resort =
7002 &process, image.
filename, image.
uuid, value, value_is_offset,
7004 allow_memory_image_last_resort);
7010 added_modules.
Append(module_sp,
false );
7016 log->
Printf(
"ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7017 "UUID %s with section load addresses",
7018 module_sp->GetFileSpec().GetPath().c_str(),
7022 SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList();
7028 sect_sp, std::get<1>(name_vmaddr_tuple));
7035 log->
Printf(
"ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7036 "UUID %s with %s 0x%" PRIx64,
7037 module_sp->GetFileSpec().GetPath().c_str(),
7039 value_is_offset ?
"slide" :
"load address", value);
7042 module_sp->SetLoadAddress(process.
GetTarget(), value, value_is_offset,
7047 if (added_modules.
GetSize() > 0) {
7054 if (found_platform_binary)
static llvm::raw_ostream & error(Stream &strm)
static const char * GetName(DWARFDeclContext::Entry entry)
Returns the name of entry if it has one, or the appropriate "anonymous {namespace,...
static const char * memory_read_error
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
static uint32_t MachHeaderSizeFromMagic(uint32_t magic)
static uint32_t GetSegmentPermissions(const llvm::MachO::segment_command_64 &seg_cmd)
static std::optional< struct nlist_64 > ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset, size_t nlist_byte_size)
static void PrintRegisterValue(RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
static llvm::StringRef GetOSName(uint32_t cmd)
static llvm::VersionTuple FindMinimumVersionInfo(DataExtractor &data, lldb::offset_t offset, size_t ncmds)
unsigned int mach_task_self()
static offset_t CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp, offset_t initial_file_offset, StreamString &all_image_infos_payload, SaveCoreStyle core_style)
static lldb::SectionType GetSectionType(uint32_t flags, ConstString section_name)
#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB
static uint32_t MachHeaderSizeFromMagic(uint32_t magic)
#define TRIE_SYMBOL_IS_THUMB
static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset, const bool is_arm, addr_t text_seg_base_addr, std::vector< llvm::StringRef > &nameSlices, std::set< lldb::addr_t > &resolver_addresses, std::vector< TrieEntryWithOffset > &reexports, std::vector< TrieEntryWithOffset > &ext_symbols)
#define THUMB_ADDRESS_BIT_MASK
static SymbolType GetSymbolType(const char *&symbol_name, bool &demangled_is_synthesized, const SectionSP &text_section_sp, const SectionSP &data_section_sp, const SectionSP &data_dirty_section_sp, const SectionSP &data_const_section_sp, const SectionSP &symbol_section)
#define LLDB_PLUGIN_DEFINE(PluginName)
#define KERN_SUCCESS
Constants returned by various RegisterContextDarwin_*** functions.
#define LLDB_SCOPED_TIMERF(...)
SectionList * m_section_list
std::vector< SectionInfo > m_section_infos
SectionSP GetSection(uint8_t n_sect, addr_t file_addr)
MachSymtabSectionInfo(SectionList *section_list)
bool SectionIsLoadable(const lldb_private::Section *section)
llvm::MachO::mach_header m_header
bool m_allow_assembly_emulation_unwind_plans
std::optional< llvm::VersionTuple > m_min_os_version
lldb_private::AddressableBits GetAddressableBits() override
Some object files may have the number of bits used for addressing embedded in them,...
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override
Extract the dependent modules from an object file.
static lldb_private::ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
FileRangeArray m_thread_context_offsets
static bool SaveCore(const lldb::ProcessSP &process_sp, const lldb_private::FileSpec &outfile, lldb::SaveCoreStyle &core_style, lldb_private::Status &error)
ObjectFile::Type CalculateType() override
The object file should be able to calculate its type by looking at its file header and possibly the s...
static lldb_private::ConstString GetSegmentNameLINKEDIT()
static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
std::vector< std::tuple< lldb::offset_t, lldb::offset_t > > FindLC_NOTEByName(std::string name)
void Dump(lldb_private::Stream *s) override
Dump a description of this object to a Stream.
bool AllowAssemblyEmulationUnwindPlans() override
Returns if the function bounds for symbols in this symbol file are likely accurate.
std::string GetIdentifierString() override
Some object files may have an identifier string embedded in them, e.g.
void ProcessSegmentCommand(const llvm::MachO::load_command &load_cmd, lldb::offset_t offset, uint32_t cmd_idx, SegmentParsingContext &context)
std::vector< llvm::MachO::section_64 > m_mach_sections
bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override
Sets the load address for an entire module, assuming a rigid slide of sections, if possible in the im...
void GetProcessSharedCacheUUID(lldb_private::Process *, lldb::addr_t &base_addr, lldb_private::UUID &uuid)
Intended for same-host arm device debugging where lldb needs to detect libraries in the shared cache ...
bool GetIsDynamicLinkEditor() override
Return true if this file is a dynamic link editor (dyld)
lldb::ByteOrder GetByteOrder() const override
Gets whether endian swapping should occur when extracting data from this object file.
bool ParseHeader() override
Attempts to parse the object header.
static lldb_private::ConstString GetSegmentNameDATA_DIRTY()
bool IsStripped() override
Detect if this object file has been stripped of local symbols.
static lldb_private::ConstString GetSegmentNameTEXT()
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
llvm::VersionTuple GetMinimumOSVersion() override
Get the minimum OS version this object file can run on.
static llvm::StringRef GetPluginDescriptionStatic()
static lldb_private::ConstString GetSegmentNameOBJC()
static llvm::StringRef GetPluginNameStatic()
lldb::RegisterContextSP GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override
static bool MagicBytesMatch(lldb::DataBufferSP data_sp, lldb::addr_t offset, lldb::addr_t length)
lldb_private::FileSpecList m_reexported_dylibs
static void GetAllArchSpecs(const llvm::MachO::mach_header &header, const lldb_private::DataExtractor &data, lldb::offset_t lc_offset, lldb_private::ModuleSpec &base_spec, lldb_private::ModuleSpecList &all_specs)
Enumerate all ArchSpecs supported by this Mach-O file.
bool GetCorefileThreadExtraInfos(std::vector< lldb::tid_t > &tids) override
Get metadata about threads from the corefile.
bool IsDynamicLoader() const
static lldb_private::ConstString GetSegmentNameDWARF()
bool IsExecutable() const override
Tells whether this object file is capable of being the main executable for a process.
lldb_private::Address GetEntryPointAddress() override
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
lldb_private::Address m_entry_point_address
bool LoadCoreFileImages(lldb_private::Process &process) override
Load binaries listed in a corefile.
bool CanTrustAddressRanges() override
Can we trust the address ranges accelerator associated with this object file to be complete.
void SanitizeSegmentCommand(llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx)
bool IsSharedCacheBinary() const
llvm::VersionTuple GetSDKVersion() override
Get the SDK OS version this object file was built with.
lldb_private::ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
static lldb_private::ConstString GetSegmentNameDATA()
ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
lldb_private::Address GetBaseAddress() override
Returns base address of this object file.
static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, lldb_private::ModuleSpecList &specs)
lldb::addr_t m_text_address
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
llvm::MachO::dysymtab_command m_dysymtab
bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset, lldb_private::UUID &uuid, ObjectFile::BinaryType &type) override
void ProcessDysymtabCommand(const llvm::MachO::load_command &load_cmd, lldb::offset_t offset)
MachOCorefileAllImageInfos GetCorefileAllImageInfos()
Get the list of binary images that were present in the process when the corefile was produced.
lldb::addr_t CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const lldb_private::Section *mach_header_section, const lldb_private::Section *section)
static lldb_private::ConstString GetSegmentNameLLVM_COV()
bool m_thread_context_offsets_valid
ObjectFile::Strata CalculateStrata() override
The object file should be able to calculate the strata of the object file.
void CreateSections(lldb_private::SectionList &unified_section_list) override
static lldb_private::ConstString GetSegmentNameDATA_CONST()
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override
Get the address type given a file address in an object file.
std::optional< llvm::VersionTuple > m_sdk_versions
void GetLLDBSharedCacheUUID(lldb::addr_t &base_addir, lldb_private::UUID &uuid)
Intended for same-host arm device debugging where lldb will read shared cache libraries out of its ow...
llvm::VersionTuple GetVersion() override
Get the object file version numbers.
EncryptedFileRanges GetEncryptedFileRanges()
uint32_t GetNumThreadContexts() override
static lldb_private::ConstString GetSectionNameEHFrame()
lldb::offset_t m_linkedit_original_offset
lldb_private::Section * GetMachHeaderSection()
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
void InvalidateAllRegisters() override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
bool SetError(int flavor, uint32_t err_idx, int err)
RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
void InvalidateAllRegisters() override
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
bool SetError(int flavor, uint32_t err_idx, int err)
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
RegisterContextDarwin_i386_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
void InvalidateAllRegisters() override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
bool SetError(int flavor, uint32_t err_idx, int err)
RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread, const DataExtractor &data)
int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
static bool Create_LC_THREAD(Thread *thread, Stream &data)
void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data)
int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
void InvalidateAllRegisters() override
int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
bool SetError(int flavor, uint32_t err_idx, int err)
A section + offset based address class.
void SetSection(const lldb::SectionSP §ion_sp)
Set accessor for the section.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections)
Resolve a file virtual address using a section list.
lldb::SectionSP GetSection() const
Get const accessor for the section.
void Clear()
Clear the object's state.
lldb::addr_t GetFileAddress() const
Get the file address.
bool IsValid() const
Check if the object state is valid.
bool SetOffset(lldb::addr_t offset)
Set accessor for the offset.
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
void SetAddressableBits(uint32_t addressing_bits)
When a single value is available for the number of bits.
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool IsAlwaysThumbInstructions() const
Detect whether this architecture uses thumb code exclusively.
bool SetArchitecture(ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os=0)
Change the architecture object type, CPU type and OS type.
uint32_t GetMachOCPUSubType() const
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
uint32_t GetMachOCPUType() const
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
A uniqued constant string class.
void SetCStringWithLength(const char *cstr, size_t cstr_len)
Set the C string value with length.
void SetCString(const char *cstr)
Set the C string value.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
void SetTrimmedCStringWithLength(const char *cstr, size_t fixed_cstr_len)
Set the C string value with the minimum length between fixed_cstr_len and the actual length of the C ...
void Clear()
Clear this object's state.
const char * GetCString() const
Get the string value as a C string.
void GetFunctionAddressAndSizeVector(FunctionAddressAndSizeVector &function_info)
lldb::StreamSP GetAsyncOutputStream()
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
PlatformList & GetPlatformList()
A plug-in interface definition class for dynamic loaders.
virtual bool GetSharedCacheInformation(lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache, LazyBool &private_shared_cache)
Get information about the shared cache for a process, if possible.
static lldb::ModuleSP LoadBinaryWithUUIDAndAddress(Process *process, llvm::StringRef name, UUID uuid, lldb::addr_t value, bool value_is_offset, bool force_symbol_search, bool notify, bool set_address_in_target, bool allow_memory_image_last_resort)
Find/load a binary into lldb given a UUID and the address where it is loaded in memory,...
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
bool AppendIfUnique(const FileSpec &file)
Append a FileSpec object if unique.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
const ConstString & GetFilename() const
Filename string const get accessor.
void ClearDirectory()
Clear the directory in this object.
const ConstString & GetDirectory() const
Directory string const get accessor.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
FileSpec CopyByRemovingLastPathComponent() const
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
int Open(const char *path, int flags, int mode=0600)
Wraps ::open in a platform-independent way.
static FileSystem & Instance()
bool Test(ValueType bit) const
Test a single flag bit.
void void void void void Warning(const char *fmt,...) __attribute__((format(printf
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
A class that handles mangled names.
void SetDemangledName(ConstString name)
ConstString GetDemangledName() const
Demangled name get accessor.
void SetMangledName(ConstString name)
void SetValue(ConstString name)
Set the string value in this object.
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A collection class for Module objects.
void Clear()
Clear the object's state.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
size_t GetSize() const
Gets the size of the module list.
void Append(const ModuleSpec &spec)
ModuleSpec & GetModuleSpecRefAtIndex(size_t i)
void SetObjectSize(uint64_t object_size)
ArchSpec & GetArchitecture()
void SetObjectOffset(uint64_t object_offset)
A plug-in interface definition class for object file parsers.
DataExtractor m_data
The data for this object file so things can be parsed lazily.
Symtab * GetSymtab()
Gets the symbol table for the currently selected architecture (and object for archives).
std::unique_ptr< lldb_private::SectionList > m_sections_up
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
std::unique_ptr< lldb_private::Symtab > m_symtab_up
const lldb::addr_t m_memory_addr
Set if the object file only exists in memory.
static lldb::DataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
@ eTypeExecutable
A normal executable.
@ eTypeDebugInfo
An object file that contains only debug information.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
@ eTypeObjectFile
An intermediate object file.
@ eTypeDynamicLinker
The platform's dynamic linker executable.
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
@ eTypeSharedLibrary
A shared library that can be used during execution.
lldb::addr_t m_file_offset
The offset in bytes into the file, or the address in memory.
static lldb::SymbolType GetSymbolTypeFromName(llvm::StringRef name, lldb::SymbolType symbol_type_hint=lldb::eSymbolTypeUndefined)
bool SetModulesArchitecture(const ArchSpec &new_arch)
Sets the architecture for a module.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
bool IsInMemory() const
Returns true if the object file exists only in memory.
lldb::ProcessWP m_process_wp
lldb::addr_t m_length
The length of this object file if it is known (can be zero if length is unknown or can't be determine...
BinaryType
If we have a corefile binary hint, this enum specifies the binary type which we can use to select the...
@ eBinaryTypeUser
kernel binary
@ eBinaryTypeStandalone
user process binary
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
void Flush()
Flush all data in the process.
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
std::vector< CoreFileMemoryRange > CoreFileMemoryRanges
Target & GetTarget()
Get the target object pointer for this module.
A Progress indicator helper class.
const Entry * FindEntryThatContains(B addr) const
const Entry * GetEntryAtIndex(size_t i) const
void Append(const Entry &entry)
const void * GetBytes() const
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
size_t GetNumSections(uint32_t depth) const
lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const
size_t Slide(lldb::addr_t slide_amount, bool slide_children)
lldb::SectionSP FindSectionContainingFileAddress(lldb::addr_t addr, uint32_t depth=UINT32_MAX) const
size_t AddSection(const lldb::SectionSP §ion_sp)
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
lldb::SectionSP GetSectionAtIndex(size_t idx) const
bool SetSectionLoadAddress(const lldb::SectionSP §ion_sp, lldb::addr_t load_addr, bool warn_multiple=false)
bool IsThreadSpecific() const
ConstString GetName() const
void SetByteSize(lldb::addr_t byte_size)
void SetFileOffset(lldb::offset_t file_offset)
lldb::offset_t GetFileOffset() const
lldb::addr_t GetFileAddress() const
SectionList & GetChildren()
void SetFileSize(lldb::offset_t file_size)
bool Slide(lldb::addr_t slide_amount, bool slide_children)
lldb::addr_t GetByteSize() const
lldb::offset_t GetFileSize() const
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
@ eBinary
Get and put data as binary instead of as the default string mode.
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t PutHex32(uint32_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
size_t PutRawBytes(const void *s, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
unsigned GetIndentLevel() const
Get the current indentation level.
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
Dictionary * GetAsDictionary()
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::shared_ptr< Array > ArraySP
Defines a list of symbol context objects.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Symbol * symbol
The Symbol for a given query.
bool ValueIsAddress() const
void SetReExportedSymbolName(ConstString name)
void SetType(lldb::SymbolType type)
void SetSizeIsSibling(bool b)
Address & GetAddressRef()
uint32_t GetFlags() const
bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
lldb::addr_t GetByteSize() const
lldb::SymbolType GetType() const
void SetFlags(uint32_t flags)
Address GetAddress() const
void SetIsSynthetic(bool b)
void SetByteSize(lldb::addr_t size)
void SetDemangledNameIsSynthesized(bool b)
Symbol * FindSymbolByID(lldb::user_id_t uid) const
Symbol * SymbolAtIndex(size_t idx)
Symbol * FindFirstSymbolWithNameAndType(ConstString name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
Symbol * Resize(size_t count)
Symbol * FindSymbolContainingFileAddress(lldb::addr_t file_addr)
size_t GetNumSymbols() const
MemoryModuleLoadLevel GetMemoryModuleLoadLevel() const
void ModulesDidLoad(ModuleList &module_list)
SectionLoadList & GetSectionLoadList()
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
bool SetSectionLoadAddress(const lldb::SectionSP §ion, lldb::addr_t load_addr, bool warn_multiple=false)
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
virtual lldb::RegisterContextSP GetRegisterContext()=0
std::string GetAsString(llvm::StringRef separator="-") const
#define LLDB_INVALID_ADDRESS_MASK
Address Mask Bits not used for addressing are set to 1 in the mask; all mask bits set is an invalid v...
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_ADDRESS
lldb::ByteOrder InlHostByteOrder()
A class that represents a running process on the host machine.
@ eMemoryModuleLoadLevelPartial
@ eMemoryModuleLoadLevelComplete
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::Process > ProcessSP
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ eSectionTypeDWARFDebugStrOffsets
@ eSectionTypeELFDynamicSymbols
Elf SHT_DYNSYM section.
@ eSectionTypeDWARFDebugPubNames
@ eSectionTypeDataObjCCFStrings
Objective-C const CFString/NSString objects.
@ eSectionTypeDWARFDebugLocDwo
@ eSectionTypeDWARFDebugFrame
@ eSectionTypeContainer
The section contains child sections.
@ eSectionTypeDWARFDebugLocLists
DWARF v5 .debug_loclists.
@ eSectionTypeDWARFDebugTypes
DWARF .debug_types section.
@ eSectionTypeDataSymbolAddress
Address of a symbol in the symbol table.
@ eSectionTypeELFDynamicLinkInfo
Elf SHT_DYNAMIC section.
@ eSectionTypeDWARFDebugMacInfo
@ eSectionTypeAbsoluteAddress
Dummy section for symbols with absolute address.
@ eSectionTypeCompactUnwind
compact unwind section in Mach-O, __TEXT,__unwind_info
@ eSectionTypeELFRelocationEntries
Elf SHT_REL or SHT_REL section.
@ eSectionTypeDWARFAppleNamespaces
@ eSectionTypeDWARFDebugNames
DWARF v5 .debug_names.
@ eSectionTypeDWARFDebugRngLists
DWARF v5 .debug_rnglists.
@ eSectionTypeDWARFDebugStrOffsetsDwo
@ eSectionTypeDWARFDebugMacro
@ eSectionTypeDWARFAppleTypes
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugTypesDwo
@ eSectionTypeDWARFDebugRanges
@ eSectionTypeDWARFDebugRngListsDwo
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugPubTypes
@ eSectionTypeDataObjCMessageRefs
Pointer to function pointer + selector.
@ eSectionTypeDWARFDebugTuIndex
@ eSectionTypeDWARFDebugStr
@ eSectionTypeDWARFDebugLineStr
DWARF v5 .debug_line_str.
@ eSectionTypeDWARFDebugLoc
@ eSectionTypeDWARFAppleNames
@ eSectionTypeDataCStringPointers
Pointers to C string data.
@ eSectionTypeDWARFAppleObjC
@ eSectionTypeSwiftModules
@ eSectionTypeDWARFDebugCuIndex
@ eSectionTypeDWARFDebugAranges
@ eSectionTypeDWARFDebugAbbrevDwo
@ eSectionTypeDWARFGNUDebugAltLink
@ eSectionTypeDWARFDebugStrDwo
@ eSectionTypeDWARFDebugAbbrev
@ eSectionTypeDataPointers
@ eSectionTypeDWARFDebugLocListsDwo
@ eSectionTypeDWARFDebugInfoDwo
@ eSectionTypeDWARFDebugAddr
@ eSectionTypeDataCString
Inlined C string data.
@ eSectionTypeELFSymbolTable
Elf SHT_SYMTAB section.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
std::vector< MachOCorefileImageEntry > all_image_infos
A corefile may include metadata about all of the binaries that were present in the process when the c...
lldb::addr_t load_address
std::vector< std::tuple< lldb_private::ConstString, lldb::addr_t > > segment_load_addresses
lldb_private::SectionList & UnifiedList
SegmentParsingContext(EncryptedFileRanges EncryptedRanges, lldb_private::SectionList &UnifiedList)
const EncryptedFileRanges EncryptedRanges
bool FileAddressesChanged
union RegisterContextDarwin_arm::FPU::@118 floats
TrieEntryWithOffset(lldb::offset_t offset)
lldb::offset_t nodeOffset
void Dump(uint32_t idx) const
bool operator<(const TrieEntryWithOffset &other) const
image_entry(const image_entry &rhs)
uint64_t seg_addrs_offset
uint64_t cacheBaseAddress
BaseType GetRangeBase() const
SizeType GetByteSize() const
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
void SetByteSize(SizeType s)
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_size
Size in bytes of the register.
segment_vmaddr(const segment_vmaddr &rhs)