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;
146 const
char *alt_name,
size_t reg_byte_size,
148 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
149 if (reg_info ==
nullptr)
150 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
153 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
154 if (reg_info->
byte_size >= reg_byte_size)
155 data.Write(reg_value.
GetBytes(), reg_byte_size);
158 for (
size_t i = 0, n = reg_byte_size - reg_info->
byte_size; i < n; ++i)
165 for (
size_t i = 0; i < reg_byte_size; ++i)
189 int flavor = data.
GetU32(&offset);
194 uint32_t count = data.
GetU32(&offset);
197 for (i = 0; i < count; ++i)
394 int flavor = data.
GetU32(&offset);
399 uint32_t count = data.
GetU32(&offset);
402 for (i = 0; i < count; ++i)
510 int flavor = data.
GetU32(&offset);
511 uint32_t count = data.
GetU32(&offset);
517 uint32_t gpr_buf_count = (
sizeof(
gpr.
r) /
sizeof(
gpr.
r[0])) + 1;
518 if (count == gpr_buf_count) {
519 for (uint32_t i = 0; i < (count - 1); ++i) {
527 offset = next_thread_state;
531 uint8_t *fpu_reg_buf = (uint8_t *)&
fpu.
floats;
532 const int fpu_reg_buf_size =
sizeof(
fpu.
floats);
534 fpu_reg_buf) == fpu_reg_buf_size) {
535 offset += fpu_reg_buf_size;
542 offset = next_thread_state;
553 offset = next_thread_state;
644 int flavor = data.
GetU32(&offset);
645 uint32_t count = data.
GetU32(&offset);
651 if (count >= (33 * 2) + 1) {
652 for (uint32_t i = 0; i < 29; ++i)
661 offset = next_thread_state;
664 uint8_t *fpu_reg_buf = (uint8_t *)&
fpu.
v[0];
665 const int fpu_reg_buf_size =
sizeof(
fpu);
666 if (fpu_reg_buf_size == count *
sizeof(uint32_t) &&
668 fpu_reg_buf) == fpu_reg_buf_size) {
674 offset = next_thread_state;
683 offset = next_thread_state;
776 return sizeof(
struct llvm::MachO::mach_header);
780 return sizeof(
struct llvm::MachO::mach_header_64);
789#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
820 if (data_sp->GetByteSize() < length) {
826 auto objfile_up = std::make_unique<ObjectFileMachO>(
827 module_sp, data_sp, data_offset, file, file_offset, length);
828 if (!objfile_up || !objfile_up->ParseHeader())
831 return objfile_up.release();
838 std::unique_ptr<ObjectFile> objfile_up(
840 if (objfile_up.get() && objfile_up->ParseHeader())
841 return objfile_up.release();
850 const size_t initial_count = specs.
GetSize();
855 llvm::MachO::mach_header header;
857 size_t header_and_load_cmds =
859 if (header_and_load_cmds >= data_sp->GetByteSize()) {
860 data_sp =
MapFileData(file, header_and_load_cmds, file_offset);
873 return specs.
GetSize() - initial_count;
878 return g_segment_name_TEXT;
883 return g_segment_name_DATA;
888 return g_segment_name;
893 return g_segment_name;
898 return g_segment_name_OBJC;
902 static ConstString g_section_name_LINKEDIT(
"__LINKEDIT");
903 return g_section_name_LINKEDIT;
908 return g_section_name;
913 return g_section_name;
917 static ConstString g_section_name_eh_frame(
"__eh_frame");
918 return g_section_name_eh_frame;
925 data.
SetData(data_sp, data_offset, data_length);
927 uint32_t magic = data.
GetU32(&offset);
931 uint32_t filetype = data.
GetU32(&offset);
936 if (filetype == llvm::MachO::MH_FILESET)
948 :
ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
949 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
950 m_thread_context_offsets_valid(false), m_reexported_dylibs(),
951 m_allow_assembly_emulation_unwind_plans(true) {
960 :
ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
961 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),
962 m_thread_context_offsets_valid(false), m_reexported_dylibs(),
963 m_allow_assembly_emulation_unwind_plans(true) {
970 llvm::MachO::mach_header &header) {
973 header.magic = data.
GetU32(data_offset_ptr);
974 bool can_parse =
false;
975 bool is_64_bit =
false;
976 switch (header.magic) {
1012 data.
GetU32(data_offset_ptr, &header.cputype, 6);
1014 *data_offset_ptr += 4;
1017 memset(&header, 0,
sizeof(header));
1027 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1028 bool can_parse =
false;
1072 base_spec, all_specs);
1074 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
1079 const ArchSpec &module_arch = module_sp->GetArchitecture();
1084 const size_t header_and_lc_size =
1094 if (data_sp->GetByteSize() != header_and_lc_size)
1106 memset(&
m_header, 0,
sizeof(
struct llvm::MachO::mach_header));
1116 return m_header.filetype == MH_EXECUTE;
1120 return m_header.filetype == MH_DYLINKER;
1124 return m_header.flags & MH_DYLIB_IN_CACHE;
1128 return m_header.filetype == MH_KEXT_BUNDLE;
1138 return AddressClass::eUnknown;
1146 switch (section_type) {
1148 return AddressClass::eUnknown;
1151 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1155 return AddressClass::eCodeAlternateISA;
1157 return AddressClass::eCode;
1160 return AddressClass::eUnknown;
1174 return AddressClass::eData;
1213 return AddressClass::eDebug;
1219 return AddressClass::eRuntime;
1227 return AddressClass::eUnknown;
1233 switch (symbol_type) {
1235 return AddressClass::eUnknown;
1237 return AddressClass::eUnknown;
1242 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1246 return AddressClass::eCodeAlternateISA;
1248 return AddressClass::eCode;
1251 return AddressClass::eData;
1253 return AddressClass::eRuntime;
1255 return AddressClass::eRuntime;
1257 return AddressClass::eDebug;
1259 return AddressClass::eDebug;
1261 return AddressClass::eDebug;
1263 return AddressClass::eDebug;
1265 return AddressClass::eDebug;
1267 return AddressClass::eData;
1269 return AddressClass::eData;
1271 return AddressClass::eData;
1273 return AddressClass::eDebug;
1275 return AddressClass::eDebug;
1277 return AddressClass::eDebug;
1279 return AddressClass::eDebug;
1281 return AddressClass::eDebug;
1283 return AddressClass::eUnknown;
1285 return AddressClass::eDebug;
1287 return AddressClass::eDebug;
1289 return AddressClass::eUnknown;
1291 return AddressClass::eRuntime;
1293 return AddressClass::eRuntime;
1295 return AddressClass::eRuntime;
1297 return AddressClass::eRuntime;
1300 return AddressClass::eUnknown;
1308 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1311 llvm::MachO::load_command lc = {};
1314 if (lc.cmd == LC_DYSYMTAB) {
1318 (
sizeof(
m_dysymtab) /
sizeof(uint32_t)) - 2) ==
1325 offset = load_cmd_offset + lc.cmdsize;
1338 llvm::MachO::encryption_info_command encryption_cmd;
1339 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1341 if (
m_data.
GetU32(&offset, &encryption_cmd, 2) ==
nullptr)
1346 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
1347 encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
1348 if (
m_data.
GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
1349 if (encryption_cmd.cryptid != 0) {
1357 offset = load_cmd_offset + encryption_cmd.cmdsize;
1364 llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx) {
1365 if (
m_length == 0 || seg_cmd.filesize == 0)
1374 sizeof(seg_cmd.segname)) == 0)
1377 sizeof(seg_cmd.segname)) == 0)
1390 const char *lc_segment_name =
1391 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1393 "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "
1394 "the end of the file ({3:x16}), ignoring this section",
1395 cmd_idx, lc_segment_name, seg_cmd.fileoff,
m_length);
1397 seg_cmd.fileoff = 0;
1398 seg_cmd.filesize = 0;
1401 if (seg_cmd.fileoff + seg_cmd.filesize >
m_length) {
1408 const char *lc_segment_name =
1409 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1411 "load command {0} {1} has a fileoff + filesize ({2:x16}) that "
1412 "extends beyond the end of the file ({4:x16}), the segment will be "
1413 "truncated to match",
1414 cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize,
m_length);
1417 seg_cmd.filesize =
m_length - seg_cmd.fileoff;
1423 uint32_t result = 0;
1424 if (seg_cmd.initprot & VM_PROT_READ)
1425 result |= ePermissionsReadable;
1426 if (seg_cmd.initprot & VM_PROT_WRITE)
1427 result |= ePermissionsWritable;
1428 if (seg_cmd.initprot & VM_PROT_EXECUTE)
1429 result |= ePermissionsExecutable;
1436 if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1439 uint32_t mach_sect_type = flags & SECTION_TYPE;
1440 static ConstString g_sect_name_objc_data(
"__objc_data");
1441 static ConstString g_sect_name_objc_msgrefs(
"__objc_msgrefs");
1442 static ConstString g_sect_name_objc_selrefs(
"__objc_selrefs");
1443 static ConstString g_sect_name_objc_classrefs(
"__objc_classrefs");
1444 static ConstString g_sect_name_objc_superrefs(
"__objc_superrefs");
1445 static ConstString g_sect_name_objc_const(
"__objc_const");
1446 static ConstString g_sect_name_objc_classlist(
"__objc_classlist");
1447 static ConstString g_sect_name_cfstring(
"__cfstring");
1449 static ConstString g_sect_name_dwarf_debug_abbrev(
"__debug_abbrev");
1450 static ConstString g_sect_name_dwarf_debug_abbrev_dwo(
"__debug_abbrev.dwo");
1451 static ConstString g_sect_name_dwarf_debug_addr(
"__debug_addr");
1452 static ConstString g_sect_name_dwarf_debug_aranges(
"__debug_aranges");
1453 static ConstString g_sect_name_dwarf_debug_cu_index(
"__debug_cu_index");
1454 static ConstString g_sect_name_dwarf_debug_frame(
"__debug_frame");
1455 static ConstString g_sect_name_dwarf_debug_info(
"__debug_info");
1456 static ConstString g_sect_name_dwarf_debug_info_dwo(
"__debug_info.dwo");
1457 static ConstString g_sect_name_dwarf_debug_line(
"__debug_line");
1458 static ConstString g_sect_name_dwarf_debug_line_dwo(
"__debug_line.dwo");
1459 static ConstString g_sect_name_dwarf_debug_line_str(
"__debug_line_str");
1460 static ConstString g_sect_name_dwarf_debug_loc(
"__debug_loc");
1461 static ConstString g_sect_name_dwarf_debug_loclists(
"__debug_loclists");
1462 static ConstString g_sect_name_dwarf_debug_loclists_dwo(
"__debug_loclists.dwo");
1463 static ConstString g_sect_name_dwarf_debug_macinfo(
"__debug_macinfo");
1464 static ConstString g_sect_name_dwarf_debug_macro(
"__debug_macro");
1465 static ConstString g_sect_name_dwarf_debug_macro_dwo(
"__debug_macro.dwo");
1466 static ConstString g_sect_name_dwarf_debug_names(
"__debug_names");
1467 static ConstString g_sect_name_dwarf_debug_pubnames(
"__debug_pubnames");
1468 static ConstString g_sect_name_dwarf_debug_pubtypes(
"__debug_pubtypes");
1469 static ConstString g_sect_name_dwarf_debug_ranges(
"__debug_ranges");
1470 static ConstString g_sect_name_dwarf_debug_rnglists(
"__debug_rnglists");
1471 static ConstString g_sect_name_dwarf_debug_str(
"__debug_str");
1472 static ConstString g_sect_name_dwarf_debug_str_dwo(
"__debug_str.dwo");
1473 static ConstString g_sect_name_dwarf_debug_str_offs(
"__debug_str_offs");
1474 static ConstString g_sect_name_dwarf_debug_str_offs_dwo(
"__debug_str_offs.dwo");
1475 static ConstString g_sect_name_dwarf_debug_tu_index(
"__debug_tu_index");
1476 static ConstString g_sect_name_dwarf_debug_types(
"__debug_types");
1477 static ConstString g_sect_name_dwarf_apple_names(
"__apple_names");
1478 static ConstString g_sect_name_dwarf_apple_types(
"__apple_types");
1479 static ConstString g_sect_name_dwarf_apple_namespaces(
"__apple_namespac");
1480 static ConstString g_sect_name_dwarf_apple_objc(
"__apple_objc");
1481 static ConstString g_sect_name_eh_frame(
"__eh_frame");
1482 static ConstString g_sect_name_compact_unwind(
"__unwind_info");
1485 static ConstString g_sect_name_go_symtab(
"__gosymtab");
1487 static ConstString g_sect_name_swift_ast(
"__swift_ast");
1489 if (section_name == g_sect_name_dwarf_debug_abbrev)
1491 if (section_name == g_sect_name_dwarf_debug_abbrev_dwo)
1493 if (section_name == g_sect_name_dwarf_debug_addr)
1495 if (section_name == g_sect_name_dwarf_debug_aranges)
1497 if (section_name == g_sect_name_dwarf_debug_cu_index)
1499 if (section_name == g_sect_name_dwarf_debug_frame)
1501 if (section_name == g_sect_name_dwarf_debug_info)
1503 if (section_name == g_sect_name_dwarf_debug_info_dwo)
1505 if (section_name == g_sect_name_dwarf_debug_line)
1507 if (section_name == g_sect_name_dwarf_debug_line_dwo)
1509 if (section_name == g_sect_name_dwarf_debug_line_str)
1511 if (section_name == g_sect_name_dwarf_debug_loc)
1513 if (section_name == g_sect_name_dwarf_debug_loclists)
1515 if (section_name == g_sect_name_dwarf_debug_loclists_dwo)
1517 if (section_name == g_sect_name_dwarf_debug_macinfo)
1519 if (section_name == g_sect_name_dwarf_debug_macro)
1521 if (section_name == g_sect_name_dwarf_debug_macro_dwo)
1523 if (section_name == g_sect_name_dwarf_debug_names)
1525 if (section_name == g_sect_name_dwarf_debug_pubnames)
1527 if (section_name == g_sect_name_dwarf_debug_pubtypes)
1529 if (section_name == g_sect_name_dwarf_debug_ranges)
1531 if (section_name == g_sect_name_dwarf_debug_rnglists)
1533 if (section_name == g_sect_name_dwarf_debug_str)
1535 if (section_name == g_sect_name_dwarf_debug_str_dwo)
1537 if (section_name == g_sect_name_dwarf_debug_str_offs)
1539 if (section_name == g_sect_name_dwarf_debug_str_offs_dwo)
1541 if (section_name == g_sect_name_dwarf_debug_tu_index)
1543 if (section_name == g_sect_name_dwarf_debug_types)
1545 if (section_name == g_sect_name_dwarf_apple_names)
1547 if (section_name == g_sect_name_dwarf_apple_types)
1549 if (section_name == g_sect_name_dwarf_apple_namespaces)
1551 if (section_name == g_sect_name_dwarf_apple_objc)
1553 if (section_name == g_sect_name_objc_selrefs)
1555 if (section_name == g_sect_name_objc_msgrefs)
1557 if (section_name == g_sect_name_eh_frame)
1559 if (section_name == g_sect_name_compact_unwind)
1561 if (section_name == g_sect_name_cfstring)
1563 if (section_name == g_sect_name_go_symtab)
1565 if (section_name == g_sect_name_ctf)
1567 if (section_name == g_sect_name_swift_ast)
1569 if (section_name == g_sect_name_objc_data ||
1570 section_name == g_sect_name_objc_classrefs ||
1571 section_name == g_sect_name_objc_superrefs ||
1572 section_name == g_sect_name_objc_const ||
1573 section_name == g_sect_name_objc_classlist) {
1577 switch (mach_sect_type) {
1580 if (section_name == g_sect_name_text)
1582 if (section_name == g_sect_name_data)
1587 case S_CSTRING_LITERALS:
1589 case S_4BYTE_LITERALS:
1591 case S_8BYTE_LITERALS:
1593 case S_LITERAL_POINTERS:
1595 case S_NON_LAZY_SYMBOL_POINTERS:
1597 case S_LAZY_SYMBOL_POINTERS:
1599 case S_SYMBOL_STUBS:
1602 case S_MOD_INIT_FUNC_POINTERS:
1605 case S_MOD_TERM_FUNC_POINTERS:
1615 case S_16BYTE_LITERALS:
1619 case S_LAZY_DYLIB_SYMBOL_POINTERS:
1639 const llvm::MachO::load_command &load_cmd_,
lldb::offset_t offset,
1641 llvm::MachO::segment_command_64 load_cmd;
1642 memcpy(&load_cmd, &load_cmd_,
sizeof(load_cmd_));
1644 if (!
m_data.
GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
1649 const bool is_dsym = (
m_header.filetype == MH_DSYM);
1650 bool add_section =
true;
1651 bool add_to_unified =
true;
1653 load_cmd.segname, strnlen(load_cmd.segname,
sizeof(load_cmd.segname)));
1657 if (is_dsym && unified_section_sp) {
1661 add_to_unified =
false;
1665 add_section =
false;
1678 const bool segment_is_encrypted =
1679 (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
1684 if (add_section && (const_segname || is_core)) {
1685 segment_sp = std::make_shared<Section>(
1705 segment_sp->SetIsEncrypted(segment_is_encrypted);
1707 segment_sp->SetPermissions(segment_permissions);
1710 }
else if (unified_section_sp) {
1720 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
1724 "Installing dSYM's %s segment file address over ObjectFile's "
1725 "so symbol table/debug info resolves correctly for %s",
1727 module_sp->GetFileSpec().GetFilename().AsCString());
1732 module_sp->GetObjectFile()->GetSymtab();
1738 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
1747 llvm::MachO::section_64 sect64;
1748 ::memset(§64, 0,
sizeof(sect64));
1753 uint32_t segment_sect_idx;
1756 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
1757 for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
1758 ++segment_sect_idx) {
1759 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.sectname,
1760 sizeof(sect64.sectname)) ==
nullptr)
1762 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.segname,
1763 sizeof(sect64.segname)) ==
nullptr)
1768 if (
m_data.
GetU32(&offset, §64.offset, num_u32s) ==
nullptr)
1781 sect64.sectname, strnlen(sect64.sectname,
sizeof(sect64.sectname)));
1782 if (!const_segname) {
1790 sizeof(sect64.segname));
1792 if (segment_sp.get()) {
1793 Section *segment = segment_sp.get();
1796 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1800 curr_seg_min_addr + curr_seg_byte_size;
1801 if (sect64_min_addr >= curr_seg_min_addr) {
1803 sect64_max_addr - curr_seg_min_addr;
1805 if (new_seg_byte_size > curr_seg_byte_size)
1811 sect64_min_addr - curr_seg_min_addr;
1812 segment->
Slide(slide_amount,
false);
1814 segment->
SetByteSize(curr_seg_max_addr - sect64_min_addr);
1818 if (sect64.offset) {
1824 const lldb::addr_t section_min_file_offset = sect64.offset;
1826 section_min_file_offset + sect64.size;
1828 std::min(section_min_file_offset, segment_min_file_offset);
1830 std::max(section_max_file_offset, segment_max_file_offset) -
1837 segment_sp = std::make_shared<Section>(
1854 sect64.offset ? sect64.size : 0,
1859 segment_sp->SetIsFake(
true);
1860 segment_sp->SetPermissions(segment_permissions);
1864 segment_sp->SetIsEncrypted(segment_is_encrypted);
1867 assert(segment_sp.get());
1872 segment_sp, module_sp,
this, ++context.
NextSectionIdx, section_name,
1873 sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
1874 sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
1878 bool section_is_encrypted =
false;
1879 if (!segment_is_encrypted && load_cmd.filesize != 0)
1881 sect64.offset) !=
nullptr;
1883 section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
1884 section_sp->SetPermissions(segment_permissions);
1885 segment_sp->GetChildren().AddSection(section_sp);
1887 if (segment_sp->IsFake()) {
1889 const_segname.
Clear();
1893 if (segment_sp && is_dsym) {
1896 for (sect_uid = first_segment_sectID; sect_uid <= context.
NextSectionIdx;
1899 segment_sp->GetChildren().FindSectionByID(sect_uid));
1903 segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
1905 if (curr_section_sp.get()) {
1906 if (curr_section_sp->GetByteSize() == 0) {
1907 if (next_section_sp.get() !=
nullptr)
1908 curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
1909 curr_section_sp->GetFileAddress());
1911 curr_section_sp->SetByteSize(load_cmd.vmsize);
1920 const llvm::MachO::load_command &load_cmd,
lldb::offset_t offset) {
1924 (
sizeof(
m_dysymtab) /
sizeof(uint32_t)) - 2);
1940 llvm::MachO::load_command load_cmd;
1941 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1946 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
1948 else if (load_cmd.cmd == LC_DYSYMTAB)
1951 offset = load_cmd_offset + load_cmd.cmdsize;
1955 module_sp->SectionFileAddressesChanged();
1977 section_sp->GetFileAddress());
1979 section_sp->GetByteSize());
1981 std::string filename =
"<unknown>";
1983 if (first_section_sp)
1984 filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
1987 llvm::formatv(
"unable to find section {0} for a symbol in "
1988 "{1}, corrupt file?",
2018#define TRIE_SYMBOL_IS_THUMB (1ULL << 63)
2021 printf(
"0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2022 static_cast<unsigned long long>(
address),
2023 static_cast<unsigned long long>(
flags),
2046 printf(
"[%3u] 0x%16.16llx: ", idx,
2047 static_cast<unsigned long long>(
nodeOffset));
2057 const bool is_arm,
addr_t text_seg_base_addr,
2058 std::vector<llvm::StringRef> &nameSlices,
2059 std::set<lldb::addr_t> &resolver_addresses,
2060 std::vector<TrieEntryWithOffset> &reexports,
2061 std::vector<TrieEntryWithOffset> &ext_symbols) {
2067 const uint64_t terminalSize = data.
GetULEB128(&offset);
2069 if (terminalSize != 0) {
2072 const char *import_name =
nullptr;
2073 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
2076 import_name = data.
GetCStr(&offset);
2081 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
2085 resolver_addr += text_seg_base_addr;
2088 resolver_addresses.insert(resolver_addr);
2092 bool add_this_entry =
false;
2094 import_name && import_name[0]) {
2096 add_this_entry =
true;
2098 (import_name ==
nullptr || import_name[0] ==
'\0')) {
2101 add_this_entry =
true;
2103 if (add_this_entry) {
2105 if (!nameSlices.empty()) {
2106 for (
auto name_slice : nameSlices)
2107 name.append(name_slice.data(), name_slice.size());
2109 if (name.size() > 1) {
2118 reexports.push_back(e);
2124 ext_symbols.push_back(e);
2129 const uint8_t childrenCount = data.
GetU8(&children_offset);
2130 for (uint8_t i = 0; i < childrenCount; ++i) {
2131 const char *cstr = data.
GetCStr(&children_offset);
2133 nameSlices.push_back(llvm::StringRef(cstr));
2137 if (childNodeOffset) {
2139 nameSlices, resolver_addresses, reexports,
2144 nameSlices.pop_back();
2150 bool &demangled_is_synthesized,
2158 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2159 if (symbol_section->IsDescendant(text_section_sp.get())) {
2160 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
2161 S_ATTR_SELF_MODIFYING_CODE |
2162 S_ATTR_SOME_INSTRUCTIONS))
2166 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
2167 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
2168 symbol_section->IsDescendant(data_const_section_sp.get())) {
2169 if (symbol_sect_name &&
2170 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
2174 llvm::StringRef symbol_name_ref(symbol_name);
2175 if (symbol_name_ref.starts_with(
"OBJC_")) {
2176 static const llvm::StringRef g_objc_v2_prefix_class(
"OBJC_CLASS_$_");
2177 static const llvm::StringRef g_objc_v2_prefix_metaclass(
2178 "OBJC_METACLASS_$_");
2179 static const llvm::StringRef g_objc_v2_prefix_ivar(
"OBJC_IVAR_$_");
2180 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
2181 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2183 demangled_is_synthesized =
true;
2184 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
2185 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2187 demangled_is_synthesized =
true;
2188 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
2189 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2191 demangled_is_synthesized =
true;
2195 }
else if (symbol_sect_name &&
2196 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
2202 }
else if (symbol_sect_name &&
2203 ::strstr(symbol_sect_name,
"__IMPORT") == symbol_sect_name) {
2209static std::optional<struct nlist_64>
2211 size_t nlist_byte_size) {
2212 struct nlist_64 nlist;
2235 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2236 Progress progress(
"Parsing symbol table", file_name);
2238 llvm::MachO::symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
2239 llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
2240 llvm::MachO::linkedit_data_command exports_trie_load_command = {0, 0, 0, 0};
2241 llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2242 llvm::MachO::dysymtab_command dysymtab =
m_dysymtab;
2251 llvm::DenseSet<addr_t> symbols_added;
2255 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2259 symbols_added.insert(file_addr);
2261 FunctionStarts function_starts;
2265 llvm::StringRef g_objc_v2_prefix_class(
"_OBJC_CLASS_$_");
2266 llvm::StringRef g_objc_v2_prefix_metaclass(
"_OBJC_METACLASS_$_");
2267 llvm::StringRef g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
2270 for (i = 0; i <
m_header.ncmds; ++i) {
2273 llvm::MachO::load_command lc;
2279 symtab_load_command.cmd = lc.cmd;
2280 symtab_load_command.cmdsize = lc.cmdsize;
2282 if (
m_data.
GetU32(&offset, &symtab_load_command.symoff, 4) ==
2288 case LC_DYLD_INFO_ONLY:
2289 if (
m_data.
GetU32(&offset, &dyld_info.rebase_off, 10)) {
2290 dyld_info.cmd = lc.cmd;
2291 dyld_info.cmdsize = lc.cmdsize;
2293 memset(&dyld_info, 0,
sizeof(dyld_info));
2298 case LC_LOAD_WEAK_DYLIB:
2299 case LC_REEXPORT_DYLIB:
2301 case LC_LOAD_UPWARD_DYLIB: {
2302 uint32_t name_offset = cmd_offset +
m_data.
GetU32(&offset);
2311 if (lc.cmd == LC_REEXPORT_DYLIB) {
2315 dylib_files.
Append(file_spec);
2319 case LC_DYLD_EXPORTS_TRIE:
2320 exports_trie_load_command.cmd = lc.cmd;
2321 exports_trie_load_command.cmdsize = lc.cmdsize;
2322 if (
m_data.
GetU32(&offset, &exports_trie_load_command.dataoff, 2) ==
2324 memset(&exports_trie_load_command, 0,
2325 sizeof(exports_trie_load_command));
2327 case LC_FUNCTION_STARTS:
2328 function_starts_load_command.cmd = lc.cmd;
2329 function_starts_load_command.cmdsize = lc.cmdsize;
2330 if (
m_data.
GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
2332 memset(&function_starts_load_command, 0,
2333 sizeof(function_starts_load_command));
2340 image_uuid =
UUID(uuid_bytes, 16);
2347 offset = cmd_offset + lc.cmdsize;
2350 if (!symtab_load_command.cmd)
2354 if (section_list ==
nullptr)
2359 bool bit_width_32 = addr_byte_size == 4;
2360 const size_t nlist_byte_size =
2361 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2363 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2364 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2365 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2366 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2368 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2370 const
addr_t nlist_data_byte_size =
2371 symtab_load_command.nsyms * nlist_byte_size;
2372 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2375 ProcessSP process_sp(m_process_wp.lock());
2376 Process *process = process_sp.get();
2380 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2382 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2384 if (process && m_header.filetype != llvm::MachO::MH_OBJECT &&
2385 !is_local_shared_cache_image) {
2386 Target &target = process->GetTarget();
2392 if (linkedit_section_sp) {
2393 addr_t linkedit_load_addr =
2394 linkedit_section_sp->GetLoadBaseAddress(&target);
2400 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
2401 m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2404 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2405 const addr_t symoff_addr = linkedit_load_addr +
2406 symtab_load_command.symoff -
2407 linkedit_file_offset;
2408 strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
2409 linkedit_file_offset;
2417 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2419 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2421 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2422 if (dysymtab.nindirectsyms != 0) {
2423 const addr_t indirect_syms_addr = linkedit_load_addr +
2424 dysymtab.indirectsymoff -
2425 linkedit_file_offset;
2427 process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
2428 if (indirect_syms_data_sp)
2429 indirect_symbol_index_data.SetData(
2430 indirect_syms_data_sp, 0,
2431 indirect_syms_data_sp->GetByteSize());
2441 if (!is_shared_cache_image) {
2443 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2444 if (strtab_data_sp) {
2445 strtab_data.SetData(strtab_data_sp, 0,
2446 strtab_data_sp->GetByteSize());
2451 if (function_starts_load_command.cmd) {
2452 const addr_t func_start_addr =
2453 linkedit_load_addr + function_starts_load_command.dataoff -
2454 linkedit_file_offset;
2456 ReadMemory(process_sp, func_start_addr,
2457 function_starts_load_command.datasize));
2458 if (func_start_data_sp)
2459 function_starts_data.SetData(func_start_data_sp, 0,
2460 func_start_data_sp->GetByteSize());
2466 if (is_local_shared_cache_image) {
2474 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2477 symtab_load_command.symoff += linkedit_slide;
2478 symtab_load_command.stroff += linkedit_slide;
2479 dyld_info.export_off += linkedit_slide;
2480 dysymtab.indirectsymoff += linkedit_slide;
2481 function_starts_load_command.dataoff += linkedit_slide;
2482 exports_trie_load_command.dataoff += linkedit_slide;
2485 nlist_data.SetData(
m_data, symtab_load_command.symoff,
2486 nlist_data_byte_size);
2487 strtab_data.SetData(
m_data, symtab_load_command.stroff,
2488 strtab_data_byte_size);
2493 && (exports_trie_load_command.datasize > 0)));
2494 if (dyld_info.export_size > 0) {
2495 dyld_trie_data.SetData(
m_data, dyld_info.export_off,
2496 dyld_info.export_size);
2497 }
else if (exports_trie_load_command.datasize > 0) {
2498 dyld_trie_data.SetData(
m_data, exports_trie_load_command.dataoff,
2499 exports_trie_load_command.datasize);
2502 if (dysymtab.nindirectsyms != 0) {
2503 indirect_symbol_index_data.SetData(
m_data, dysymtab.indirectsymoff,
2504 dysymtab.nindirectsyms * 4);
2506 if (function_starts_load_command.cmd) {
2507 function_starts_data.SetData(
m_data, function_starts_load_command.dataoff,
2508 function_starts_load_command.datasize);
2512 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2531 if (text_section_sp.get())
2532 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2533 g_section_name_eh_frame);
2535 eh_frame_section_sp =
2538 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2555 if (text_section_sp && function_starts_data.GetByteSize()) {
2556 FunctionStarts::Entry function_start_entry;
2557 function_start_entry.data =
false;
2559 function_start_entry.addr = text_section_sp->GetFileAddress();
2561 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2564 function_start_entry.addr += delta;
2566 if (function_start_entry.addr & 1) {
2568 function_start_entry.data =
true;
2569 }
else if (always_thumb) {
2570 function_start_entry.data =
true;
2573 function_starts.Append(function_start_entry);
2581 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2587 addr_t text_base_addr = text_section_sp->GetFileAddress();
2588 size_t count = functions.
GetSize();
2589 for (
size_t i = 0; i < count; ++i) {
2593 FunctionStarts::Entry function_start_entry;
2594 function_start_entry.addr = func->
base - text_base_addr;
2596 if (function_start_entry.addr & 1) {
2598 function_start_entry.data =
true;
2599 }
else if (always_thumb) {
2600 function_start_entry.data =
true;
2603 function_starts.Append(function_start_entry);
2609 const size_t function_starts_count = function_starts.GetSize();
2622 Log *unwind_or_symbol_log(
GetLog(LLDBLog::Symbols | LLDBLog::Unwind));
2624 if (unwind_or_symbol_log)
2625 module_sp->LogMessage(
2626 unwind_or_symbol_log,
2627 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2630 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2631 ? eh_frame_section_sp->GetID()
2637 std::vector<uint32_t> N_FUN_indexes;
2638 std::vector<uint32_t> N_NSYM_indexes;
2639 std::vector<uint32_t> N_INCL_indexes;
2640 std::vector<uint32_t> N_BRAC_indexes;
2641 std::vector<uint32_t> N_COMM_indexes;
2642 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2643 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2644 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2645 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2646 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2647 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2650 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2651 uint32_t nlist_idx = 0;
2652 Symbol *symbol_ptr =
nullptr;
2654 uint32_t sym_idx = 0;
2656 size_t num_syms = 0;
2657 std::string memory_symbol_name;
2658 uint32_t unmapped_local_symbols_found = 0;
2660 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2661 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2662 std::set<lldb::addr_t> resolver_addresses;
2664 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2665 if (dyld_trie_data_size > 0) {
2666 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2670 if (text_segment_sp)
2671 text_segment_file_addr = text_segment_sp->GetFileAddress();
2672 std::vector<llvm::StringRef> nameSlices;
2674 nameSlices, resolver_addresses, reexport_trie_entries,
2675 external_sym_trie_entries);
2678 typedef std::set<ConstString> IndirectSymbols;
2679 IndirectSymbols indirect_symbol_names;
2702 UUID process_shared_cache_uuid;
2703 addr_t process_shared_cache_base_addr;
2707 process_shared_cache_uuid);
2710 __block
bool found_image =
false;
2711 __block
void *nlist_buffer =
nullptr;
2712 __block
unsigned nlist_count = 0;
2713 __block
char *string_table =
nullptr;
2714 __block vm_offset_t vm_nlist_memory = 0;
2715 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2716 __block vm_offset_t vm_string_memory = 0;
2717 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2719 auto _ = llvm::make_scope_exit(^{
2720 if (vm_nlist_memory)
2721 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2722 if (vm_string_memory)
2723 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2726 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2727 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2728 UndefinedNameToDescMap undefined_name_to_desc;
2729 SymbolIndexToName reexport_shlib_needs_fixup;
2731 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2733 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2737 if (process_shared_cache_uuid.
IsValid() &&
2738 process_shared_cache_uuid != UUID::fromData(&cache_uuid, 16))
2741 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2746 dyld_image_copy_uuid(image, &dsc_image_uuid);
2747 if (image_uuid != UUID::fromData(dsc_image_uuid, 16))
2754 dyld_image_local_nlist_content_4Symbolication(
2755 image, ^(
const void *nlistStart, uint64_t nlistCount,
2756 const char *stringTable) {
2757 if (!nlistStart || !nlistCount)
2765 nlist_byte_size * nlistCount, &vm_nlist_memory,
2766 &vm_nlist_bytes_read);
2769 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2774 vm_address_t string_address = (vm_address_t)stringTable;
2775 vm_size_t region_size;
2776 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2777 vm_region_basic_info_data_t info;
2778 memory_object_name_t object;
2780 ®ion_size, VM_REGION_BASIC_INFO_64,
2781 (vm_region_info_t)&info, &info_count, &
object);
2787 ((vm_address_t)stringTable - string_address),
2788 &vm_string_memory, &vm_string_bytes_read);
2792 nlist_buffer = (
void *)vm_nlist_memory;
2793 string_table = (
char *)vm_string_memory;
2794 nlist_count = nlistCount;
2800 nlist_count * nlist_byte_size,
2801 byte_order, addr_byte_size);
2802 unmapped_local_symbols_found = nlist_count;
2807 symtab_load_command.nsyms +
m_dysymtab.nindirectsyms +
2808 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2813 for (uint32_t nlist_index = 0;
2814 nlist_index < nlist_count;
2818 std::optional<struct nlist_64> nlist_maybe =
2819 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2823 struct nlist_64 nlist = *nlist_maybe;
2826 const char *symbol_name = string_table + nlist.n_strx;
2828 if (symbol_name == NULL) {
2833 "DSC unmapped local symbol[{0}] has invalid "
2834 "string table offset {1:x} in {2}, ignoring symbol",
2835 nlist_index, nlist.n_strx,
2836 module_sp->GetFileSpec().GetPath());
2839 if (symbol_name[0] ==
'\0')
2842 const char *symbol_name_non_abi_mangled = NULL;
2845 uint32_t symbol_byte_size = 0;
2846 bool add_nlist =
true;
2847 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2848 bool demangled_is_synthesized =
false;
2849 bool is_gsym =
false;
2850 bool set_value =
true;
2852 assert(sym_idx < num_syms);
2857 switch (nlist.n_type) {
2876 if (symbol_name && symbol_name[0] ==
'_' &&
2877 symbol_name[1] ==
'O') {
2878 llvm::StringRef symbol_name_ref(symbol_name);
2879 if (symbol_name_ref.starts_with(
2880 g_objc_v2_prefix_class)) {
2881 symbol_name_non_abi_mangled = symbol_name + 1;
2883 symbol_name + g_objc_v2_prefix_class.size();
2885 demangled_is_synthesized =
true;
2887 }
else if (symbol_name_ref.starts_with(
2888 g_objc_v2_prefix_metaclass)) {
2889 symbol_name_non_abi_mangled = symbol_name + 1;
2891 symbol_name + g_objc_v2_prefix_metaclass.size();
2893 demangled_is_synthesized =
true;
2894 }
else if (symbol_name_ref.starts_with(
2895 g_objc_v2_prefix_ivar)) {
2896 symbol_name_non_abi_mangled = symbol_name + 1;
2898 symbol_name + g_objc_v2_prefix_ivar.size();
2900 demangled_is_synthesized =
true;
2903 if (nlist.n_value != 0)
2905 nlist.n_sect, nlist.n_value);
2920 nlist.n_sect, nlist.n_value);
2922 N_FUN_addr_to_sym_idx.insert(
2923 std::make_pair(nlist.n_value, sym_idx));
2927 N_FUN_indexes.push_back(sym_idx);
2931 if (!N_FUN_indexes.empty()) {
2938 N_FUN_indexes.pop_back();
2950 N_STSYM_addr_to_sym_idx.insert(
2951 std::make_pair(nlist.n_value, sym_idx));
2952 symbol_section = section_info.
GetSection(nlist.n_sect,
2954 if (symbol_name && symbol_name[0]) {
2962 symbol_section = section_info.
GetSection(nlist.n_sect,
2996 symbol_section = section_info.
GetSection(nlist.n_sect,
3009 if (symbol_name == NULL) {
3020 N_NSYM_indexes.clear();
3021 N_INCL_indexes.clear();
3022 N_BRAC_indexes.clear();
3023 N_COMM_indexes.clear();
3024 N_FUN_indexes.clear();
3030 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3031 if (N_SO_has_full_path) {
3032 if ((N_SO_index == sym_idx - 1) &&
3033 ((sym_idx - 1) < num_syms)) {
3039 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3045 N_SO_index = sym_idx;
3047 }
else if ((N_SO_index == sym_idx - 1) &&
3048 ((sym_idx - 1) < num_syms)) {
3053 const char *so_path = sym[sym_idx - 1]
3057 if (so_path && so_path[0]) {
3058 std::string full_so_path(so_path);
3059 const size_t double_slash_pos =
3060 full_so_path.find(
"//");
3061 if (double_slash_pos != std::string::npos) {
3072 &full_so_path[double_slash_pos + 1],
3073 FileSpec::Style::native);
3076 full_so_path.erase(0, double_slash_pos + 1);
3080 if (*full_so_path.rbegin() !=
'/')
3081 full_so_path +=
'/';
3082 full_so_path += symbol_name;
3086 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3090 N_SO_index = sym_idx;
3111 N_INCL_indexes.push_back(sym_idx);
3121 if (!N_INCL_indexes.empty()) {
3126 N_INCL_indexes.pop_back();
3161 symbol_section = section_info.
GetSection(nlist.n_sect,
3172 symbol_section = section_info.
GetSection(nlist.n_sect,
3174 N_BRAC_indexes.push_back(sym_idx);
3184 symbol_section = section_info.
GetSection(nlist.n_sect,
3186 if (!N_BRAC_indexes.empty()) {
3191 N_BRAC_indexes.pop_back();
3208 N_COMM_indexes.push_back(sym_idx);
3213 symbol_section = section_info.
GetSection(nlist.n_sect,
3224 if (!N_COMM_indexes.empty()) {
3229 N_COMM_indexes.pop_back();
3244 uint8_t n_type = N_TYPE & nlist.n_type;
3245 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3249 const char *reexport_name_cstr =
3250 strtab_data.PeekCStr(nlist.n_value);
3251 if (reexport_name_cstr && reexport_name_cstr[0]) {
3254 reexport_name_cstr +
3255 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3258 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3260 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3266 if (symbol_name && symbol_name[0]) {
3268 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3269 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3281 symbol_section = section_info.
GetSection(nlist.n_sect,
3284 if (symbol_section == NULL) {
3290 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3293 uint32_t section_type =
3294 symbol_section->Get() & SECTION_TYPE;
3296 switch (section_type) {
3297 case S_CSTRING_LITERALS:
3300 case S_4BYTE_LITERALS:
3303 case S_8BYTE_LITERALS:
3306 case S_LITERAL_POINTERS:
3309 case S_NON_LAZY_SYMBOL_POINTERS:
3313 case S_LAZY_SYMBOL_POINTERS:
3316 case S_SYMBOL_STUBS:
3320 case S_MOD_INIT_FUNC_POINTERS:
3324 case S_MOD_TERM_FUNC_POINTERS:
3332 case S_16BYTE_LITERALS:
3338 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3342 switch (symbol_section->GetType()) {
3369 const char *symbol_sect_name =
3370 symbol_section->GetName().AsCString();
3371 if (symbol_section->IsDescendant(
3372 text_section_sp.get())) {
3373 if (symbol_section->IsClear(
3374 S_ATTR_PURE_INSTRUCTIONS |
3375 S_ATTR_SELF_MODIFYING_CODE |
3376 S_ATTR_SOME_INSTRUCTIONS))
3380 }
else if (symbol_section->IsDescendant(
3381 data_section_sp.get()) ||
3382 symbol_section->IsDescendant(
3383 data_dirty_section_sp.get()) ||
3384 symbol_section->IsDescendant(
3385 data_const_section_sp.get())) {
3386 if (symbol_sect_name &&
3387 ::strstr(symbol_sect_name,
"__objc") ==
3392 llvm::StringRef symbol_name_ref(symbol_name);
3393 if (symbol_name_ref.starts_with(
"_OBJC_")) {
3395 g_objc_v2_prefix_class(
3398 g_objc_v2_prefix_metaclass(
3399 "_OBJC_METACLASS_$_");
3401 g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
3402 if (symbol_name_ref.starts_with(
3403 g_objc_v2_prefix_class)) {
3404 symbol_name_non_abi_mangled =
3408 g_objc_v2_prefix_class.size();
3410 demangled_is_synthesized =
true;
3412 symbol_name_ref.starts_with(
3413 g_objc_v2_prefix_metaclass)) {
3414 symbol_name_non_abi_mangled =
3418 g_objc_v2_prefix_metaclass.size();
3420 demangled_is_synthesized =
true;
3421 }
else if (symbol_name_ref.starts_with(
3422 g_objc_v2_prefix_ivar)) {
3423 symbol_name_non_abi_mangled =
3427 g_objc_v2_prefix_ivar.size();
3429 demangled_is_synthesized =
true;
3433 }
else if (symbol_sect_name &&
3434 ::strstr(symbol_sect_name,
3435 "__gcc_except_tab") ==
3441 }
else if (symbol_sect_name &&
3442 ::strstr(symbol_sect_name,
"__IMPORT") ==
3445 }
else if (symbol_section->IsDescendant(
3446 objc_section_sp.get())) {
3448 if (symbol_name && symbol_name[0] ==
'.') {
3449 llvm::StringRef symbol_name_ref(symbol_name);
3451 g_objc_v1_prefix_class(
".objc_class_name_");
3452 if (symbol_name_ref.starts_with(
3453 g_objc_v1_prefix_class)) {
3454 symbol_name_non_abi_mangled = symbol_name;
3455 symbol_name = symbol_name +
3456 g_objc_v1_prefix_class.size();
3458 demangled_is_synthesized =
true;
3469 uint64_t symbol_value = nlist.n_value;
3470 if (symbol_name_non_abi_mangled) {
3476 if (symbol_name && symbol_name[0] ==
'_') {
3483 if (is_gsym && is_debug) {
3484 const char *gsym_name =
3490 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3494 if (symbol_section) {
3495 const addr_t section_file_addr =
3496 symbol_section->GetFileAddress();
3497 if (symbol_byte_size == 0 &&
3498 function_starts_count > 0) {
3499 addr_t symbol_lookup_file_addr = nlist.n_value;
3504 FunctionStarts::Entry *func_start_entry =
3505 function_starts.FindEntry(symbol_lookup_file_addr,
3507 if (is_arm && func_start_entry) {
3511 if (func_start_entry->addr !=
3512 symbol_lookup_file_addr &&
3513 func_start_entry->addr !=
3514 (symbol_lookup_file_addr + 1)) {
3516 func_start_entry = NULL;
3519 if (func_start_entry) {
3520 func_start_entry->data =
true;
3522 addr_t symbol_file_addr = func_start_entry->addr;
3523 uint32_t symbol_flags = 0;
3525 if (symbol_file_addr & 1)
3530 const FunctionStarts::Entry *next_func_start_entry =
3531 function_starts.FindNextEntry(func_start_entry);
3532 const addr_t section_end_file_addr =
3534 symbol_section->GetByteSize();
3535 if (next_func_start_entry) {
3536 addr_t next_symbol_file_addr =
3537 next_func_start_entry->addr;
3543 symbol_byte_size = std::min<lldb::addr_t>(
3544 next_symbol_file_addr - symbol_file_addr,
3545 section_end_file_addr - symbol_file_addr);
3548 section_end_file_addr - symbol_file_addr;
3552 symbol_value -= section_file_addr;
3555 if (is_debug ==
false) {
3563 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3564 if (range.first != range.second) {
3565 bool found_it =
false;
3566 for (
auto pos = range.first; pos != range.second;
3568 if (sym[sym_idx].GetMangled().
GetName(
3572 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3578 sym[sym_idx].IsExternal());
3579 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3581 if (resolver_addresses.find(nlist.n_value) !=
3582 resolver_addresses.end())
3584 sym[sym_idx].
Clear();
3592 if (resolver_addresses.find(nlist.n_value) !=
3593 resolver_addresses.end())
3605 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3607 if (range.first != range.second) {
3608 bool found_it =
false;
3609 for (
auto pos = range.first; pos != range.second;
3611 if (sym[sym_idx].GetMangled().
GetName(
3615 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3621 sym[sym_idx].IsExternal());
3622 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3624 sym[sym_idx].
Clear();
3632 const char *gsym_name =
3640 ConstNameToSymbolIndexMap::const_iterator pos =
3641 N_GSYM_name_to_sym_idx.find(gsym_name);
3642 if (pos != N_GSYM_name_to_sym_idx.end()) {
3643 const uint32_t GSYM_sym_idx = pos->second;
3644 m_nlist_idx_to_sym_idx[nlist_idx] =
3653 add_symbol_addr(sym[GSYM_sym_idx]
3660 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3662 sym[sym_idx].
Clear();
3670 sym[sym_idx].
SetID(nlist_idx);
3676 sym[sym_idx].GetAddress().GetFileAddress());
3678 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3680 if (symbol_byte_size > 0)
3683 if (demangled_is_synthesized)
3687 sym[sym_idx].
Clear();
3694 for (
const auto &pos : reexport_shlib_needs_fixup) {
3695 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3696 if (undef_pos != undefined_name_to_desc.end()) {
3697 const uint8_t dylib_ordinal =
3698 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3699 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3709 if (nlist_data.GetByteSize() > 0) {
3713 if (sym ==
nullptr) {
3719 if (unmapped_local_symbols_found) {
3721 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3727 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3728 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3729 UndefinedNameToDescMap undefined_name_to_desc;
3730 SymbolIndexToName reexport_shlib_needs_fixup;
3738 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3740 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3741 if (is_debug != debug_only)
3744 const char *symbol_name_non_abi_mangled =
nullptr;
3745 const char *symbol_name =
nullptr;
3747 if (have_strtab_data) {
3748 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3750 if (symbol_name ==
nullptr) {
3754 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3756 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3759 if (symbol_name[0] ==
'\0')
3760 symbol_name =
nullptr;
3762 const addr_t str_addr = strtab_addr + nlist.n_strx;
3764 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3766 symbol_name = memory_symbol_name.c_str();
3772 bool add_nlist =
true;
3773 bool is_gsym =
false;
3774 bool demangled_is_synthesized =
false;
3775 bool set_value =
true;
3777 assert(sym_idx < num_syms);
3781 switch (nlist.n_type) {
3798 if (symbol_name && symbol_name[0] ==
'_' && symbol_name[1] ==
'O') {
3799 llvm::StringRef symbol_name_ref(symbol_name);
3800 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
3801 symbol_name_non_abi_mangled = symbol_name + 1;
3802 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3804 demangled_is_synthesized =
true;
3806 }
else if (symbol_name_ref.starts_with(
3807 g_objc_v2_prefix_metaclass)) {
3808 symbol_name_non_abi_mangled = symbol_name + 1;
3809 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3811 demangled_is_synthesized =
true;
3812 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
3813 symbol_name_non_abi_mangled = symbol_name + 1;
3814 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3816 demangled_is_synthesized =
true;
3819 if (nlist.n_value != 0)
3821 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3836 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3838 N_FUN_addr_to_sym_idx.insert(
3839 std::make_pair(nlist.n_value, sym_idx));
3843 N_FUN_indexes.push_back(sym_idx);
3847 if (!N_FUN_indexes.empty()) {
3852 N_FUN_indexes.pop_back();
3863 N_STSYM_addr_to_sym_idx.insert(
3864 std::make_pair(nlist.n_value, sym_idx));
3865 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3866 if (symbol_name && symbol_name[0]) {
3874 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3905 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3917 if (symbol_name ==
nullptr) {
3928 N_NSYM_indexes.clear();
3929 N_INCL_indexes.clear();
3930 N_BRAC_indexes.clear();
3931 N_COMM_indexes.clear();
3932 N_FUN_indexes.clear();
3938 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3939 if (N_SO_has_full_path) {
3940 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3945 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3950 N_SO_index = sym_idx;
3952 }
else if ((N_SO_index == sym_idx - 1) &&
3953 ((sym_idx - 1) < num_syms)) {
3957 const char *so_path =
3959 if (so_path && so_path[0]) {
3960 std::string full_so_path(so_path);
3961 const size_t double_slash_pos = full_so_path.find(
"//");
3962 if (double_slash_pos != std::string::npos) {
3970 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3971 FileSpec::Style::native);
3974 full_so_path.erase(0, double_slash_pos + 1);
3978 if (*full_so_path.rbegin() !=
'/')
3979 full_so_path +=
'/';
3980 full_so_path += symbol_name;
3984 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3988 N_SO_index = sym_idx;
4008 N_INCL_indexes.push_back(sym_idx);
4017 if (!N_INCL_indexes.empty()) {
4021 N_INCL_indexes.pop_back();
4056 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4065 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4066 N_BRAC_indexes.push_back(sym_idx);
4075 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4076 if (!N_BRAC_indexes.empty()) {
4080 N_BRAC_indexes.pop_back();
4096 N_COMM_indexes.push_back(sym_idx);
4101 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4110 if (!N_COMM_indexes.empty()) {
4114 N_COMM_indexes.pop_back();
4128 uint8_t n_type = N_TYPE & nlist.n_type;
4129 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
4133 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4134 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
4137 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
4140 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4141 indirect_symbol_names.insert(
4142 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
4148 if (symbol_name && symbol_name[0]) {
4150 ((symbol_name[0] ==
'_') ? 1 : 0));
4151 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4164 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4166 if (!symbol_section) {
4172 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4175 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4177 switch (section_type) {
4178 case S_CSTRING_LITERALS:
4181 case S_4BYTE_LITERALS:
4184 case S_8BYTE_LITERALS:
4187 case S_LITERAL_POINTERS:
4190 case S_NON_LAZY_SYMBOL_POINTERS:
4193 case S_LAZY_SYMBOL_POINTERS:
4196 case S_SYMBOL_STUBS:
4200 case S_MOD_INIT_FUNC_POINTERS:
4203 case S_MOD_TERM_FUNC_POINTERS:
4210 case S_16BYTE_LITERALS:
4216 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4220 switch (symbol_section->GetType()) {
4242 const char *symbol_sect_name =
4243 symbol_section->GetName().AsCString();
4244 if (symbol_section->IsDescendant(text_section_sp.get())) {
4245 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4246 S_ATTR_SELF_MODIFYING_CODE |
4247 S_ATTR_SOME_INSTRUCTIONS))
4251 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4252 symbol_section->IsDescendant(
4253 data_dirty_section_sp.get()) ||
4254 symbol_section->IsDescendant(
4255 data_const_section_sp.get())) {
4256 if (symbol_sect_name &&
4257 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4261 llvm::StringRef symbol_name_ref(symbol_name);
4262 if (symbol_name_ref.starts_with(
"_OBJC_")) {
4263 llvm::StringRef g_objc_v2_prefix_class(
4265 llvm::StringRef g_objc_v2_prefix_metaclass(
4266 "_OBJC_METACLASS_$_");
4267 llvm::StringRef g_objc_v2_prefix_ivar(
4269 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
4270 symbol_name_non_abi_mangled = symbol_name + 1;
4272 symbol_name + g_objc_v2_prefix_class.size();
4274 demangled_is_synthesized =
true;
4275 }
else if (symbol_name_ref.starts_with(
4276 g_objc_v2_prefix_metaclass)) {
4277 symbol_name_non_abi_mangled = symbol_name + 1;
4279 symbol_name + g_objc_v2_prefix_metaclass.size();
4281 demangled_is_synthesized =
true;
4282 }
else if (symbol_name_ref.starts_with(
4283 g_objc_v2_prefix_ivar)) {
4284 symbol_name_non_abi_mangled = symbol_name + 1;
4286 symbol_name + g_objc_v2_prefix_ivar.size();
4288 demangled_is_synthesized =
true;
4292 }
else if (symbol_sect_name &&
4293 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4299 }
else if (symbol_sect_name &&
4300 ::strstr(symbol_sect_name,
"__IMPORT") ==
4303 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4305 if (symbol_name && symbol_name[0] ==
'.') {
4306 llvm::StringRef symbol_name_ref(symbol_name);
4307 llvm::StringRef g_objc_v1_prefix_class(
4308 ".objc_class_name_");
4309 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4310 symbol_name_non_abi_mangled = symbol_name;
4311 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4313 demangled_is_synthesized =
true;
4324 sym[sym_idx].
Clear();
4328 uint64_t symbol_value = nlist.n_value;
4330 if (symbol_name_non_abi_mangled) {
4336 if (symbol_name && symbol_name[0] ==
'_') {
4347 const char *gsym_name = sym[sym_idx]
4352 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4355 if (symbol_section) {
4356 const addr_t section_file_addr = symbol_section->GetFileAddress();
4357 if (symbol_byte_size == 0 && function_starts_count > 0) {
4358 addr_t symbol_lookup_file_addr = nlist.n_value;
4362 FunctionStarts::Entry *func_start_entry =
4363 function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
4364 if (is_arm && func_start_entry) {
4367 if (func_start_entry->addr != symbol_lookup_file_addr &&
4368 func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
4370 func_start_entry =
nullptr;
4373 if (func_start_entry) {
4374 func_start_entry->data =
true;
4376 addr_t symbol_file_addr = func_start_entry->addr;
4380 const FunctionStarts::Entry *next_func_start_entry =
4381 function_starts.FindNextEntry(func_start_entry);
4382 const addr_t section_end_file_addr =
4383 section_file_addr + symbol_section->GetByteSize();
4384 if (next_func_start_entry) {
4385 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4390 symbol_byte_size = std::min<lldb::addr_t>(
4391 next_symbol_file_addr - symbol_file_addr,
4392 section_end_file_addr - symbol_file_addr);
4394 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4398 symbol_value -= section_file_addr;
4407 std::pair<ValueToSymbolIndexMap::const_iterator,
4408 ValueToSymbolIndexMap::const_iterator>
4410 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4411 if (range.first != range.second) {
4412 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4413 pos != range.second; ++pos) {
4417 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4421 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4422 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4423 if (resolver_addresses.find(nlist.n_value) !=
4424 resolver_addresses.end())
4426 sym[sym_idx].
Clear();
4431 if (resolver_addresses.find(nlist.n_value) !=
4432 resolver_addresses.end())
4442 std::pair<ValueToSymbolIndexMap::const_iterator,
4443 ValueToSymbolIndexMap::const_iterator>
4445 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4446 if (range.first != range.second) {
4447 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4448 pos != range.second; ++pos) {
4452 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4456 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4457 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4458 sym[sym_idx].
Clear();
4464 const char *gsym_name = sym[sym_idx]
4469 ConstNameToSymbolIndexMap::const_iterator pos =
4470 N_GSYM_name_to_sym_idx.find(gsym_name);
4471 if (pos != N_GSYM_name_to_sym_idx.end()) {
4472 const uint32_t GSYM_sym_idx = pos->second;
4473 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4479 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4483 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4484 sym[sym_idx].
Clear();
4492 sym[sym_idx].
SetID(nlist_idx);
4498 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4500 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4501 if (nlist.n_desc & N_WEAK_REF)
4504 if (symbol_byte_size > 0)
4507 if (demangled_is_synthesized)
4516 std::vector<struct nlist_64> nlists;
4517 nlists.reserve(symtab_load_command.nsyms);
4518 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
4520 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4521 nlists.push_back(*nlist);
4531 for (
auto &nlist : nlists) {
4532 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4538 for (
auto &nlist : nlists) {
4543 for (
const auto &pos : reexport_shlib_needs_fixup) {
4544 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4545 if (undef_pos != undefined_name_to_desc.end()) {
4546 const uint8_t dylib_ordinal =
4547 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4548 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4556 int trie_symbol_table_augment_count = 0;
4557 for (
auto &e : external_sym_trie_entries) {
4558 if (!symbols_added.contains(e.entry.address))
4559 trie_symbol_table_augment_count++;
4562 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4563 num_syms = sym_idx + trie_symbol_table_augment_count;
4564 sym = symtab.
Resize(num_syms);
4566 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4569 for (
auto &e : external_sym_trie_entries) {
4570 if (symbols_added.contains(e.entry.address))
4576 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4578 const char *symbol_name = e.entry.name.GetCString();
4579 bool demangled_is_synthesized =
false;
4581 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4582 data_section_sp, data_dirty_section_sp,
4583 data_const_section_sp, symbol_section);
4586 if (symbol_section) {
4587 sym[sym_idx].
SetID(synthetic_sym_id++);
4589 if (demangled_is_synthesized)
4602 if (function_starts_count > 0) {
4603 uint32_t num_synthetic_function_symbols = 0;
4604 for (i = 0; i < function_starts_count; ++i) {
4605 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4606 ++num_synthetic_function_symbols;
4609 if (num_synthetic_function_symbols > 0) {
4610 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4611 num_syms = sym_idx + num_synthetic_function_symbols;
4612 sym = symtab.
Resize(num_syms);
4614 for (i = 0; i < function_starts_count; ++i) {
4615 const FunctionStarts::Entry *func_start_entry =
4616 function_starts.GetEntryAtIndex(i);
4617 if (!symbols_added.contains(func_start_entry->addr)) {
4618 addr_t symbol_file_addr = func_start_entry->addr;
4619 uint32_t symbol_flags = 0;
4620 if (func_start_entry->data)
4623 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4625 uint32_t symbol_byte_size = 0;
4626 if (symbol_section) {
4627 const addr_t section_file_addr = symbol_section->GetFileAddress();
4628 const FunctionStarts::Entry *next_func_start_entry =
4629 function_starts.FindNextEntry(func_start_entry);
4630 const addr_t section_end_file_addr =
4631 section_file_addr + symbol_section->GetByteSize();
4632 if (next_func_start_entry) {
4633 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4636 symbol_byte_size = std::min<lldb::addr_t>(
4637 next_symbol_file_addr - symbol_file_addr,
4638 section_end_file_addr - symbol_file_addr);
4640 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4642 sym[sym_idx].
SetID(synthetic_sym_id++);
4652 sym[sym_idx].
SetFlags(symbol_flags);
4653 if (symbol_byte_size)
4665 if (sym_idx < num_syms) {
4667 sym = symtab.
Resize(num_syms);
4672 if (indirect_symbol_index_data.GetByteSize()) {
4673 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4674 m_nlist_idx_to_sym_idx.end();
4681 if (symbol_stub_byte_size == 0)
4684 const uint32_t num_symbol_stubs =
4687 if (num_symbol_stubs == 0)
4690 const uint32_t symbol_stub_index_offset =
4692 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4693 const uint32_t symbol_stub_index =
4694 symbol_stub_index_offset + stub_idx;
4697 (stub_idx * symbol_stub_byte_size);
4699 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4700 symbol_stub_offset, 4)) {
4701 const uint32_t stub_sym_id =
4702 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4703 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4706 NListIndexToSymbolIndexMap::const_iterator index_pos =
4707 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4708 Symbol *stub_symbol =
nullptr;
4709 if (index_pos != end_index_pos) {
4720 Address so_addr(symbol_stub_addr, section_list);
4727 if (resolver_addresses.find(symbol_stub_addr) ==
4728 resolver_addresses.end())
4738 if (sym_idx >= num_syms) {
4739 sym = symtab.
Resize(++num_syms);
4740 stub_symbol =
nullptr;
4742 sym[sym_idx].
SetID(synthetic_sym_id++);
4743 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4744 if (resolver_addresses.find(symbol_stub_addr) ==
4745 resolver_addresses.end())
4757 log->
Warning(
"symbol stub referencing symbol table symbol "
4758 "%u that isn't in our minimal symbol table, "
4769 if (!reexport_trie_entries.empty()) {
4770 for (
const auto &e : reexport_trie_entries) {
4771 if (e.entry.import_name) {
4774 if (indirect_symbol_names.find(e.entry.name) ==
4775 indirect_symbol_names.end()) {
4777 if (sym_idx >= num_syms)
4778 sym = symtab.
Resize(++num_syms);
4779 sym[sym_idx].
SetID(synthetic_sym_id++);
4784 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
4798 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4799 s->
Printf(
"%p: ",
static_cast<void *
>(
this));
4806 *s <<
", file = '" <<
m_file;
4810 base_spec, all_specs);
4811 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
4836 llvm::MachO::uuid_command load_cmd;
4839 for (i = 0; i < header.ncmds; ++i) {
4841 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
4844 if (load_cmd.cmd == LC_UUID) {
4845 const uint8_t *uuid_bytes = data.
PeekData(offset, 16);
4851 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4852 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4853 0xbb, 0x14, 0xf0, 0x0d};
4855 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4858 return UUID(uuid_bytes, 16);
4862 offset = cmd_offset + load_cmd.cmdsize;
4869 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4870 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4871 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4872 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4873 case llvm::MachO::LC_VERSION_MIN_TVOS:
4874 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4875 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4876 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4878 llvm_unreachable(
"unexpected LC_VERSION load command");
4884 llvm::StringRef os_type;
4885 llvm::StringRef environment;
4886 OSEnv(uint32_t cmd) {
4888 case llvm::MachO::PLATFORM_MACOS:
4889 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4891 case llvm::MachO::PLATFORM_IOS:
4892 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4894 case llvm::MachO::PLATFORM_TVOS:
4895 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4897 case llvm::MachO::PLATFORM_WATCHOS:
4898 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4900 case llvm::MachO::PLATFORM_BRIDGEOS:
4901 os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
4903 case llvm::MachO::PLATFORM_DRIVERKIT:
4904 os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);
4906 case llvm::MachO::PLATFORM_MACCATALYST:
4907 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4908 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
4910 case llvm::MachO::PLATFORM_IOSSIMULATOR:
4911 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4913 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4915 case llvm::MachO::PLATFORM_TVOSSIMULATOR:
4916 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4918 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4920 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
4921 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4923 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4925 case llvm::MachO::PLATFORM_XROS:
4926 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4928 case llvm::MachO::PLATFORM_XROS_SIMULATOR:
4929 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4931 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4934 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
4935 LLDB_LOGF(log,
"unsupported platform in LC_BUILD_VERSION");
4942 uint32_t major_version, minor_version, patch_version;
4943 MinOS(uint32_t version)
4944 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),
4945 patch_version(version & 0xffu) {}
4956 if (!base_arch.IsValid())
4959 bool found_any =
false;
4960 auto add_triple = [&](
const llvm::Triple &triple) {
4961 auto spec = base_spec;
4963 if (spec.GetArchitecture().IsValid()) {
4971 llvm::Triple base_triple = base_arch.GetTriple();
4972 base_triple.setOS(llvm::Triple::UnknownOS);
4973 base_triple.setOSName(llvm::StringRef());
4975 if (header.filetype == MH_PRELOAD) {
4976 if (header.cputype == CPU_TYPE_ARM) {
4982 base_triple.setVendor(llvm::Triple::Apple);
4987 base_triple.setVendor(llvm::Triple::UnknownVendor);
4988 base_triple.setVendorName(llvm::StringRef());
4990 return add_triple(base_triple);
4993 llvm::MachO::load_command load_cmd;
4998 for (uint32_t i = 0; i < header.ncmds; ++i) {
5000 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
5003 llvm::MachO::version_min_command version_min;
5004 switch (load_cmd.cmd) {
5005 case llvm::MachO::LC_VERSION_MIN_MACOSX:
5006 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
5007 case llvm::MachO::LC_VERSION_MIN_TVOS:
5008 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
5009 if (load_cmd.cmdsize !=
sizeof(version_min))
5014 MinOS min_os(version_min.version);
5015 llvm::SmallString<32> os_name;
5016 llvm::raw_svector_ostream os(os_name);
5017 os <<
GetOSName(load_cmd.cmd) << min_os.major_version <<
'.'
5018 << min_os.minor_version <<
'.' << min_os.patch_version;
5020 auto triple = base_triple;
5021 triple.setOSName(os.str());
5024 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
5025 (base_triple.getArch() == llvm::Triple::x86_64 ||
5026 base_triple.getArch() == llvm::Triple::x86)) {
5033 triple.setEnvironment(llvm::Triple::Simulator);
5042 offset = cmd_offset + load_cmd.cmdsize;
5048 for (uint32_t i = 0; i < header.ncmds; ++i) {
5050 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
5054 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
5055 llvm::MachO::build_version_command build_version;
5056 if (load_cmd.cmdsize <
sizeof(build_version)) {
5060 if (data.
ExtractBytes(cmd_offset,
sizeof(build_version),
5063 MinOS min_os(build_version.minos);
5064 OSEnv os_env(build_version.platform);
5065 llvm::SmallString<16> os_name;
5066 llvm::raw_svector_ostream os(os_name);
5067 os << os_env.os_type << min_os.major_version <<
'.'
5068 << min_os.minor_version <<
'.' << min_os.patch_version;
5069 auto triple = base_triple;
5070 triple.setOSName(os.str());
5072 if (!os_env.environment.empty())
5073 triple.setEnvironmentName(os_env.environment);
5077 offset = cmd_offset + load_cmd.cmdsize;
5081 add_triple(base_triple);
5086 ModuleSP module_sp,
const llvm::MachO::mach_header &header,
5091 base_spec, all_specs);
5096 const ArchSpec &module_arch = module_sp->GetArchitecture();
5097 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
5114 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5127 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5128 llvm::MachO::load_command load_cmd;
5130 std::vector<std::string> rpath_paths;
5131 std::vector<std::string> rpath_relative_paths;
5132 std::vector<std::string> at_exec_relative_paths;
5134 for (i = 0; i <
m_header.ncmds; ++i) {
5135 const uint32_t cmd_offset = offset;
5139 switch (load_cmd.cmd) {
5142 case LC_LOAD_WEAK_DYLIB:
5143 case LC_REEXPORT_DYLIB:
5144 case LC_LOAD_DYLINKER:
5146 case LC_LOAD_UPWARD_DYLIB: {
5147 uint32_t name_offset = cmd_offset +
m_data.
GetU32(&offset);
5152 bool is_delayed_init =
false;
5154 if (use_command_marker == 0x1a741800 ) {
5163 is_delayed_init =
true;
5166 if (path && !is_delayed_init) {
5167 if (load_cmd.cmd == LC_RPATH)
5168 rpath_paths.push_back(path);
5170 if (path[0] ==
'@') {
5171 if (strncmp(path,
"@rpath", strlen(
"@rpath")) == 0)
5172 rpath_relative_paths.push_back(path + strlen(
"@rpath"));
5173 else if (strncmp(path,
"@executable_path",
5174 strlen(
"@executable_path")) == 0)
5175 at_exec_relative_paths.push_back(path +
5176 strlen(
"@executable_path"));
5189 offset = cmd_offset + load_cmd.cmdsize;
5195 if (!rpath_paths.empty()) {
5197 const std::string this_directory =
5199 for (
auto &rpath : rpath_paths) {
5201 rpath = this_directory + rpath.substr(
g_loader_path.size());
5206 for (
const auto &rpath_relative_path : rpath_relative_paths) {
5207 for (
const auto &rpath : rpath_paths) {
5208 std::string path = rpath;
5209 path += rpath_relative_path;
5229 for (
const auto &at_exec_relative_path : at_exec_relative_paths) {
5276 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5277 llvm::MachO::load_command load_cmd;
5283 for (i = 0; i <
m_header.ncmds; ++i) {
5288 switch (load_cmd.cmd) {
5291 while (offset < cmd_offset + load_cmd.cmdsize) {
5300 case llvm::MachO::CPU_TYPE_ARM:
5311 case llvm::MachO::CPU_TYPE_ARM64:
5312 case llvm::MachO::CPU_TYPE_ARM64_32:
5321 case llvm::MachO::CPU_TYPE_I386:
5331 case llvm::MachO::CPU_TYPE_X86_64:
5348 offset += count * 4;
5355 if (text_segment_sp) {
5357 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5368 offset = cmd_offset + load_cmd.cmdsize;
5374 ConstString(
"_dyld_start"), SymbolType::eSymbolTypeCode,
5398 module_sp->FindSymbolsWithNameAndType(
ConstString(
"start"),
5417 if (text_segment_sp) {
5428 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5433 llvm::MachO::thread_command thread_cmd;
5434 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5435 const uint32_t cmd_offset = offset;
5439 if (thread_cmd.cmd == LC_THREAD) {
5444 offset = cmd_offset + thread_cmd.cmdsize;
5451std::vector<std::tuple<offset_t, offset_t>>
5453 std::vector<std::tuple<offset_t, offset_t>> results;
5456 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5459 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5460 const uint32_t cmd_offset = offset;
5461 llvm::MachO::load_command lc = {};
5464 if (lc.cmd == LC_NOTE) {
5465 char data_owner[17];
5467 data_owner[16] =
'\0';
5470 if (name == data_owner) {
5473 results.push_back({payload_offset, payload_size});
5476 offset = cmd_offset + lc.cmdsize;
5484 GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));
5487 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5490 for (
auto lc_note : lc_notes) {
5491 offset_t payload_offset = std::get<0>(lc_note);
5492 offset_t payload_size = std::get<1>(lc_note);
5494 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr) {
5496 uint32_t strsize = payload_size -
sizeof(uint32_t);
5497 std::string result(strsize,
'\0');
5499 LLDB_LOGF(log,
"LC_NOTE 'kern ver str' found with text '%s'",
5509 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5510 const uint32_t cmd_offset = offset;
5511 llvm::MachO::ident_command ident_command;
5512 if (
m_data.
GetU32(&offset, &ident_command, 2) ==
nullptr)
5514 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
5515 std::string result(ident_command.cmdsize,
'\0');
5516 if (
m_data.
CopyData(offset, ident_command.cmdsize, result.data()) ==
5517 ident_command.cmdsize) {
5518 LLDB_LOGF(log,
"LC_IDENT found with text '%s'", result.c_str());
5522 offset = cmd_offset + ident_command.cmdsize;
5534 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5536 for (
auto lc_note : lc_notes) {
5537 offset_t payload_offset = std::get<0>(lc_note);
5539 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr) {
5544 "LC_NOTE 'addrable bits' v3 found, value %d "
5552 if (lo_addr_bits == hi_addr_bits)
5556 LLDB_LOGF(log,
"LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
5557 lo_addr_bits, hi_addr_bits);
5562 return addressable_bits;
5566 bool &value_is_offset,
5570 GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));
5572 value_is_offset =
false;
5574 uint32_t log2_pagesize = 0;
5575 uint32_t platform = 0;
5578 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5581 for (
auto lc_note : lc_notes) {
5582 offset_t payload_offset = std::get<0>(lc_note);
5617 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr &&
5619 uint32_t binspec_type = 0;
5621 memset(raw_uuid, 0,
sizeof(
uuid_t));
5628 if (version > 1 && !
m_data.
GetU64(&payload_offset, &slide, 1))
5632 value_is_offset =
true;
5639 const char *typestr =
"unrecognized type";
5640 switch (binspec_type) {
5647 typestr =
"xnu kernel";
5651 typestr =
"userland dyld";
5655 typestr =
"standalone";
5659 "LC_NOTE 'main bin spec' found, version %d type %d "
5660 "(%s), value 0x%" PRIx64
" value-is-slide==%s uuid %s",
5661 version, type, typestr, value,
5662 value_is_offset ?
"true" :
"false",
5664 if (!
m_data.
GetU32(&payload_offset, &log2_pagesize, 1))
5666 if (version > 1 && !
m_data.
GetU32(&payload_offset, &platform, 1))
5680 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5682 Log *log(
GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));
5684 for (
auto lc_note : lc_notes) {
5685 offset_t payload_offset = std::get<0>(lc_note);
5686 offset_t strsize = std::get<1>(lc_note);
5687 std::string buf(strsize,
'\0');
5688 if (
m_data.
CopyData(payload_offset, strsize, buf.data()) != strsize) {
5690 "Unable to read %" PRIu64
5691 " bytes of 'process metadata' LC_NOTE JSON contents",
5695 while (buf.back() ==
'\0')
5696 buf.resize(buf.size() - 1);
5700 LLDB_LOGF(log,
"Unable to read 'process metadata' LC_NOTE, did not "
5701 "get a dictionary.");
5707 "'process metadata' LC_NOTE does not have a 'threads' key");
5711 LLDB_LOGF(log,
"Unable to read 'process metadata' LC_NOTE, number of "
5712 "threads does not match number of LC_THREADS.");
5715 const size_t num_threads = threads->
GetSize();
5716 for (
size_t i = 0; i < num_threads; i++) {
5717 std::optional<StructuredData::Dictionary *> maybe_thread =
5719 if (!maybe_thread) {
5721 "Unable to read 'process metadata' LC_NOTE, threads "
5722 "array does not have a dictionary at index %zu.",
5731 tids.push_back(tid);
5736 logmsg.
Printf(
"LC_NOTE 'process metadata' found: ");
5737 dict->
Dump(logmsg,
false);
5753 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5759 if (thread_context_file_range) {
5765 case llvm::MachO::CPU_TYPE_ARM64:
5766 case llvm::MachO::CPU_TYPE_ARM64_32:
5768 std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);
5771 case llvm::MachO::CPU_TYPE_ARM:
5773 std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);
5776 case llvm::MachO::CPU_TYPE_I386:
5778 std::make_shared<RegisterContextDarwin_i386_Mach>(thread, data);
5781 case llvm::MachO::CPU_TYPE_X86_64:
5783 std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
5826 case MH_KEXT_BUNDLE:
5854 if (
m_header.flags & MH_DYLDLINK) {
5882 case MH_KEXT_BUNDLE:
5893 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5894 llvm::MachO::dylib_command load_cmd;
5896 uint32_t version_cmd = 0;
5897 uint64_t version = 0;
5899 for (i = 0; i <
m_header.ncmds; ++i) {
5904 if (load_cmd.cmd == LC_ID_DYLIB) {
5905 if (version_cmd == 0) {
5906 version_cmd = load_cmd.cmd;
5907 if (
m_data.
GetU32(&offset, &load_cmd.dylib, 4) ==
nullptr)
5909 version = load_cmd.dylib.current_version;
5914 offset = cmd_offset + load_cmd.cmdsize;
5917 if (version_cmd == LC_ID_DYLIB) {
5918 unsigned major = (version & 0xFFFF0000ull) >> 16;
5919 unsigned minor = (version & 0x0000FF00ull) >> 8;
5920 unsigned subminor = (version & 0x000000FFull);
5921 return llvm::VersionTuple(major, minor, subminor);
5924 return llvm::VersionTuple();
5931 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5948 private_shared_cache);
5950 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
5953 "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64,
5976#if defined(__APPLE__)
5977 uint8_t *(*dyld_get_all_image_infos)(void);
5978 dyld_get_all_image_infos =
5979 (uint8_t * (*)()) dlsym(RTLD_DEFAULT,
"_dyld_get_all_image_infos");
5980 if (dyld_get_all_image_infos) {
5981 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5982 if (dyld_all_image_infos_address) {
5983 uint32_t *version = (uint32_t *)
5984 dyld_all_image_infos_address;
5985 if (*version >= 13) {
5986 uuid_t *sharedCacheUUID_address = 0;
5987 int wordsize =
sizeof(uint8_t *);
5988 if (wordsize == 8) {
5989 sharedCacheUUID_address =
5990 (
uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5995 *)((uint8_t *)dyld_all_image_infos_address +
5998 sharedCacheUUID_address =
5999 (
uuid_t *)((uint8_t *)dyld_all_image_infos_address +
6001 if (*version >= 15) {
6005 *)((uint8_t *)dyld_all_image_infos_address +
6009 uuid =
UUID(sharedCacheUUID_address,
sizeof(
uuid_t));
6015 unsigned int task, uint64_t timestamp,
6016 unsigned int *kernelError);
6017 void (*dyld_process_info_get_cache)(
void *info,
void *cacheInfo);
6020 dyld_process_info_create = (
void *(*)(
unsigned int , uint64_t,
6022 dlsym(RTLD_DEFAULT,
"_dyld_process_info_create");
6023 dyld_process_info_get_cache = (void (*)(
void *,
void *))dlsym(
6024 RTLD_DEFAULT,
"_dyld_process_info_get_cache");
6025 dyld_process_info_release =
6026 (void (*)(
void *))dlsym(RTLD_DEFAULT,
"_dyld_process_info_release");
6028 if (dyld_process_info_create && dyld_process_info_get_cache) {
6029 unsigned int kern_ret;
6035 dyld_process_info_get_cache(process_info, &sc_info);
6040 dyld_process_info_release(process_info);
6044 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
6047 "lldb's in-memory shared cache has a UUID of %s base address of "
6056 for (
size_t i = 0; i < ncmds; i++) {
6058 llvm::MachO::load_command lc = {};
6059 if (data.
GetU32(&offset, &lc.cmd, 2) ==
nullptr)
6062 uint32_t version = 0;
6063 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
6064 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
6065 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
6066 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
6074 version = data.
GetU32(&offset);
6075 }
else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
6085 offset +=
sizeof(uint32_t);
6086 version = data.
GetU32(&offset);
6090 const uint32_t xxxx = version >> 16;
6091 const uint32_t yy = (version >> 8) & 0xffu;
6092 const uint32_t zz = version & 0xffu;
6094 return llvm::VersionTuple(xxxx, yy, zz);
6096 offset = load_cmd_offset + lc.cmdsize;
6098 return llvm::VersionTuple();
6116 return m_header.filetype == llvm::MachO::MH_DYLINKER;
6122 return m_header.filetype == llvm::MachO::MH_DSYM;
6148 return text_segment_sp.get();
6150 const size_t num_sections = section_list->
GetSize();
6151 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6179 const bool is_memory_image = (bool)
m_process_wp.lock();
6191 if (module_sp && header_section && section &&
6195 return section->
GetFileAddress() - file_addr + header_load_address;
6201 bool value_is_offset) {
6202 Log *log(
GetLog(LLDBLog::DynamicLoader));
6211 size_t num_loaded_sections = 0;
6212 const size_t num_sections = section_list->
GetSize();
6216 const bool warn_multiple =
true;
6220 logmsg <<
"ObjectFileMachO::SetLoadAddress ";
6228 if (value_is_offset) {
6230 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6236 "ObjectFileMachO::SetLoadAddress segment '%s' load addr is "
6238 section_sp->GetName().AsCString(),
6239 section_sp->GetFileAddress() + value);
6241 section_sp, section_sp->GetFileAddress() + value,
6243 ++num_loaded_sections;
6251 if (mach_header_section) {
6252 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6257 value, mach_header_section, section_sp.get());
6260 "ObjectFileMachO::SetLoadAddress segment '%s' load addr is "
6262 section_sp->GetName().AsCString(), section_load_addr);
6264 section_sp, section_load_addr, warn_multiple))
6265 ++num_loaded_sections;
6270 return num_loaded_sections > 0;
6355 Target &target = process_sp->GetTarget();
6361 if (options.
GetStyle() == SaveCoreStyle::eSaveCoreStackOnly)
6364 std::set<std::string> executing_uuids;
6365 std::vector<ThreadSP> thread_list =
6366 process_sp->CalculateCoreFileThreadList(options);
6367 for (
const ThreadSP &thread_sp : thread_list) {
6368 uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
6369 for (uint32_t j = 0; j < stack_frame_count; j++) {
6370 StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
6371 Address pc = stack_frame_sp->GetFrameCodeAddress();
6374 UUID uuid = module_sp->GetUUID();
6382 size_t modules_count = modules.
GetSize();
6400 std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;
6401 for (
size_t i = 0; i < modules_count; i++) {
6405 size_t sections_count = sections->
GetSize();
6406 std::vector<segment_vmaddr> segment_vmaddrs;
6407 for (
size_t j = 0; j < sections_count; j++) {
6409 if (!section->GetParent().get()) {
6410 addr_t vmaddr = section->GetLoadBaseAddress(&target);
6423 seg_vmaddr.
vmaddr = vmaddr;
6425 segment_vmaddrs.push_back(seg_vmaddr);
6428 modules_segment_vmaddrs.push_back(segment_vmaddrs);
6431 offset_t size_of_vmaddr_structs = 0;
6432 for (
size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6433 size_of_vmaddr_structs +=
6437 offset_t size_of_filepath_cstrings = 0;
6438 for (
size_t i = 0; i < modules_count; i++) {
6440 size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;
6449 start_of_entries +
sizeof(
image_entry) * modules_count;
6450 offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;
6452 offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;
6458 offset_t current_string_offset = start_of_filenames;
6459 offset_t current_segaddrs_offset = start_of_seg_vmaddrs;
6460 std::vector<struct image_entry> image_entries;
6461 for (
size_t i = 0; i < modules_count; i++) {
6465 memcpy(&ent.
uuid, module_sp->GetUUID().GetBytes().data(),
sizeof(ent.
uuid));
6466 if (modules_segment_vmaddrs[i].size() > 0) {
6471 ObjectFile *objfile = module_sp->GetObjectFile();
6485 if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=
6486 executing_uuids.end())
6487 all_image_infos_payload.
PutHex32(1);
6489 all_image_infos_payload.
PutHex32(0);
6492 current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;
6497 for (
size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6498 if (modules_segment_vmaddrs[i].size() == 0)
6501 all_image_infos_payload.
PutRawBytes(segvm.segname,
sizeof(segvm.segname));
6502 all_image_infos_payload.
PutHex64(segvm.vmaddr);
6503 all_image_infos_payload.
PutHex64(segvm.unused);
6507 for (
size_t i = 0; i < modules_count; i++) {
6509 std::string filepath = module_sp->GetFileSpec().GetPath();
6510 all_image_infos_payload.
PutRawBytes(filepath.data(), filepath.size() + 1);
6513 return final_file_offset;
6533 if (options.
GetStyle() == SaveCoreStyle::eSaveCoreUnspecified)
6536 Target &target = process_sp->GetTarget();
6538 const llvm::Triple &target_triple = target_arch.
GetTriple();
6539 if (target_triple.getVendor() == llvm::Triple::Apple &&
6540 (target_triple.getOS() == llvm::Triple::MacOSX ||
6541 target_triple.getOS() == llvm::Triple::IOS ||
6542 target_triple.getOS() == llvm::Triple::WatchOS ||
6543 target_triple.getOS() == llvm::Triple::TvOS ||
6544 target_triple.getOS() == llvm::Triple::XROS)) {
6547 bool make_core =
false;
6549 case llvm::Triple::aarch64:
6550 case llvm::Triple::aarch64_32:
6551 case llvm::Triple::arm:
6552 case llvm::Triple::thumb:
6553 case llvm::Triple::x86:
6554 case llvm::Triple::x86_64:
6558 error.SetErrorStringWithFormat(
"unsupported core architecture: %s",
6559 target_triple.str().c_str());
6565 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6566 if (
error.Success()) {
6569 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6570 for (
const auto &core_range : core_ranges) {
6571 uint32_t cmd_type = LC_SEGMENT_64;
6572 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6573 if (addr_byte_size == 4) {
6574 cmd_type = LC_SEGMENT;
6575 segment_size =
sizeof(llvm::MachO::segment_command);
6579 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6581 uint32_t vm_prot = 0;
6582 if (core_range.lldb_permissions & ePermissionsReadable)
6583 vm_prot |= VM_PROT_READ;
6584 if (core_range.lldb_permissions & ePermissionsWritable)
6585 vm_prot |= VM_PROT_WRITE;
6586 if (core_range.lldb_permissions & ePermissionsExecutable)
6587 vm_prot |= VM_PROT_EXECUTE;
6588 const addr_t vm_addr = core_range.range.start();
6589 const addr_t vm_size = core_range.range.size();
6590 llvm::MachO::segment_command_64 segment = {
6602 segment_load_commands.push_back(segment);
6607 llvm::MachO::mach_header_64 mach_header;
6608 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6611 mach_header.filetype = MH_CORE;
6612 mach_header.ncmds = segment_load_commands.size();
6613 mach_header.flags = 0;
6614 mach_header.reserved = 0;
6615 ThreadList &thread_list = process_sp->GetThreadList();
6616 const uint32_t num_threads = thread_list.
GetSize();
6622 std::vector<StreamString> LC_THREAD_datas(num_threads);
6623 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6625 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6626 LC_THREAD_data.SetByteOrder(byte_order);
6628 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6631 switch (mach_header.cputype) {
6632 case llvm::MachO::CPU_TYPE_ARM64:
6633 case llvm::MachO::CPU_TYPE_ARM64_32:
6635 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6638 case llvm::MachO::CPU_TYPE_ARM:
6640 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6643 case llvm::MachO::CPU_TYPE_I386:
6645 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6648 case llvm::MachO::CPU_TYPE_X86_64:
6650 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6657 if (addr_byte_size == 8) {
6658 mach_header.sizeofcmds = segment_load_commands.size() *
6659 sizeof(llvm::MachO::segment_command_64);
6661 mach_header.sizeofcmds = segment_load_commands.size() *
6662 sizeof(llvm::MachO::segment_command);
6666 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6667 ++mach_header.ncmds;
6668 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6673 uint64_t address_mask = process_sp->GetCodeAddressMask();
6676 mach_header.ncmds++;
6677 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6681 mach_header.ncmds++;
6682 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6685 mach_header.ncmds++;
6686 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6689 buffer.
PutHex32(mach_header.magic);
6690 buffer.
PutHex32(mach_header.cputype);
6691 buffer.
PutHex32(mach_header.cpusubtype);
6692 buffer.
PutHex32(mach_header.filetype);
6693 buffer.
PutHex32(mach_header.ncmds);
6694 buffer.
PutHex32(mach_header.sizeofcmds);
6695 buffer.
PutHex32(mach_header.flags);
6696 if (addr_byte_size == 8) {
6697 buffer.
PutHex32(mach_header.reserved);
6702 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6704 file_offset = llvm::alignTo(file_offset, 16);
6705 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6709 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6711 addrable_bits_lcnote_up->name =
"addrable bits";
6712 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6713 int bits = std::bitset<64>(~address_mask).count();
6714 addrable_bits_lcnote_up->payload.PutHex32(4);
6715 addrable_bits_lcnote_up->payload.PutHex32(
6717 addrable_bits_lcnote_up->payload.PutHex32(
6719 addrable_bits_lcnote_up->payload.PutHex32(0);
6721 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6723 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6727 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6729 thread_extrainfo_lcnote_up->name =
"process metadata";
6730 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6733 std::make_shared<StructuredData::Dictionary>());
6735 std::make_shared<StructuredData::Array>());
6737 process_sp->CalculateCoreFileThreadList(options)) {
6739 std::make_shared<StructuredData::Dictionary>());
6740 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6741 threads->AddItem(thread);
6743 dict->AddItem(
"threads", threads);
6745 dict->Dump(strm,
false);
6749 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6750 file_offset = llvm::alignTo(file_offset, 16);
6751 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6754 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6756 all_image_infos_lcnote_up->name =
"all image infos";
6757 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6759 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6761 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6764 for (
auto &lcnote : lc_notes) {
6767 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6769 memset(namebuf, 0,
sizeof(namebuf));
6775 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6777 buffer.
PutHex64(lcnote->payload_file_offset);
6778 buffer.
PutHex64(lcnote->payload.GetSize());
6782 file_offset = llvm::alignTo(file_offset, 4096);
6784 for (
auto &segment : segment_load_commands) {
6785 segment.fileoff = file_offset;
6786 file_offset += segment.filesize;
6790 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6791 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6793 buffer.
PutHex32(8 + LC_THREAD_data_size);
6794 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6798 for (
const auto &segment : segment_load_commands) {
6801 buffer.
PutRawBytes(segment.segname,
sizeof(segment.segname));
6802 if (addr_byte_size == 8) {
6808 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmaddr));
6809 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmsize));
6810 buffer.
PutHex32(
static_cast<uint32_t
>(segment.fileoff));
6811 buffer.
PutHex32(
static_cast<uint32_t
>(segment.filesize));
6819 std::string core_file_path(outfile.
GetPath());
6824 error = core_file.takeError();
6827 uint8_t bytes[0x1000];
6829 size_t bytes_written = buffer.
GetString().size();
6831 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6832 if (
error.Success()) {
6834 for (
auto &lcnote : lc_notes) {
6835 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6837 error.SetErrorStringWithFormat(
"Unable to seek to corefile pos "
6838 "to write '%s' LC_NOTE payload",
6839 lcnote->name.c_str());
6842 bytes_written = lcnote->payload.GetSize();
6843 error = core_file.get()->Write(lcnote->payload.GetData(),
6845 if (!
error.Success())
6850 for (
const auto &segment : segment_load_commands) {
6851 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6852 error.SetErrorStringWithFormat(
6853 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6854 segment.fileoff, core_file_path.c_str());
6860 " bytes of data for memory region at 0x%" PRIx64
"\n",
6861 segment.vmsize, segment.vmaddr);
6862 addr_t bytes_left = segment.vmsize;
6863 addr_t addr = segment.vmaddr;
6865 while (bytes_left > 0 &&
error.Success()) {
6866 const size_t bytes_to_read =
6867 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6872 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6875 if (bytes_read == bytes_to_read) {
6876 size_t bytes_written = bytes_read;
6877 error = core_file.get()->Write(bytes, bytes_written);
6878 bytes_left -= bytes_read;
6883 memset(bytes, 0, bytes_to_read);
6884 size_t bytes_written = bytes_to_read;
6885 error = core_file.get()->Write(bytes, bytes_written);
6886 bytes_left -= bytes_to_read;
6887 addr += bytes_to_read;
6904 Log *log(
GetLog(LLDBLog::Object | LLDBLog::Symbols | LLDBLog::Process |
6905 LLDBLog::DynamicLoader));
6908 for (
auto lc_note : lc_notes) {
6909 offset_t payload_offset = std::get<0>(lc_note);
6916 uint64_t entries_fileoff =
m_data.
GetU64(&payload_offset);
6921 LLDB_LOGF(log,
"LC_NOTE 'all image infos' found version %d with %d images",
6923 payload_offset = entries_fileoff;
6924 for (uint32_t i = 0; i < imgcount; i++) {
6930 uint64_t load_address =
m_data.
GetU64(&payload_offset);
6932 uint32_t segment_count =
m_data.
GetU32(&payload_offset);
6933 uint32_t currently_executing =
m_data.
GetU32(&payload_offset);
6939 image_entry.currently_executing = currently_executing;
6941 offset_t seg_vmaddrs_offset = seg_addrs_offset;
6942 for (uint32_t j = 0; j < segment_count; j++) {
6946 seg_vmaddrs_offset += 16;
6948 seg_vmaddrs_offset += 8;
6950 std::tuple<ConstString, addr_t> new_seg{
ConstString(segname), vmaddr};
6951 image_entry.segment_load_addresses.push_back(new_seg);
6953 LLDB_LOGF(log,
" image entry: %s %s 0x%" PRIx64
" %s",
6957 image_entry.currently_executing ?
"currently executing"
6958 :
"not currently executing");
6964 for (
auto lc_note : lc_notes) {
6965 offset_t payload_offset = std::get<0>(lc_note);
6971 uint64_t load_address =
m_data.
GetU64(&payload_offset);
6983 "LC_NOTE 'load binary' found, filename %s uuid %s load "
6984 "address 0x%" PRIx64
" slide 0x%" PRIx64,
6988 :
"00000000-0000-0000-0000-000000000000",
6989 load_address, slide);
6998 Log *log =
GetLog(LLDBLog::Object | LLDBLog::DynamicLoader);
7001 bool found_platform_binary =
false;
7004 ModuleSP module_sp, local_filesystem_module_sp;
7016 "ObjectFileMachO::%s binary at 0x%" PRIx64
7017 " is a platform binary, has been handled by a Platform plugin.",
7035 const bool notify =
false;
7038 const bool allow_memory_image_last_resort =
7041 &process, image.
filename, image.
uuid, value, value_is_offset,
7043 allow_memory_image_last_resort);
7049 added_modules.
Append(module_sp,
false );
7055 log->
Printf(
"ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7056 "UUID %s with section load addresses",
7057 module_sp->GetFileSpec().GetPath().c_str(),
7061 SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList();
7067 sect_sp, std::get<1>(name_vmaddr_tuple));
7074 log->
Printf(
"ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7075 "UUID %s with %s 0x%" PRIx64,
7076 module_sp->GetFileSpec().GetPath().c_str(),
7078 value_is_offset ?
"slide" :
"load address", value);
7081 module_sp->SetLoadAddress(process.
GetTarget(), value, value_is_offset,
7086 if (added_modules.
GetSize() > 0) {
7093 if (found_platform_binary)
static llvm::raw_ostream & error(Stream &strm)
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 constexpr llvm::StringLiteral g_loader_path
static std::optional< struct nlist_64 > ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset, size_t nlist_byte_size)
static constexpr llvm::StringLiteral g_executable_path
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 lldb::SectionType GetSectionType(uint32_t flags, ConstString section_name)
#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB
static uint32_t MachHeaderSizeFromMagic(uint32_t magic)
static offset_t CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp, offset_t initial_file_offset, StreamString &all_image_infos_payload, lldb_private::SaveCoreOptions &options)
#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(...)
static llvm::StringRef GetName(XcodeSDK::Type type)
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
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
static bool SaveCore(const lldb::ProcessSP &process_sp, lldb_private::SaveCoreOptions &options, lldb_private::Status &error)
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.
std::string GetString() const
Get the string value as a std::string.
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::WritableDataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
@ eTypeExecutable
A normal executable.
@ eTypeDebugInfo
An object file that contains only debug information.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
@ eTypeObjectFile
An intermediate object file.
@ eTypeDynamicLinker
The platform's dynamic linker executable.
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
@ eTypeSharedLibrary
A shared library that can be used during execution.
lldb::addr_t m_file_offset
The offset in bytes into the file, or the address in memory.
static lldb::SymbolType GetSymbolTypeFromName(llvm::StringRef name, lldb::SymbolType symbol_type_hint=lldb::eSymbolTypeUndefined)
bool SetModulesArchitecture(const ArchSpec &new_arch)
Sets the architecture for a module.
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
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
const std::optional< lldb_private::FileSpec > GetOutputFile() const
lldb::SaveCoreStyle GetStyle() const
void SetStyle(lldb::SaveCoreStyle style)
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.
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.
@ eBinary
Get and put data as binary instead of as the default string mode.
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::@117 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)