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;
1215 return AddressClass::eDebug;
1221 return AddressClass::eRuntime;
1229 return AddressClass::eUnknown;
1235 switch (symbol_type) {
1237 return AddressClass::eUnknown;
1239 return AddressClass::eUnknown;
1244 if (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1248 return AddressClass::eCodeAlternateISA;
1250 return AddressClass::eCode;
1253 return AddressClass::eData;
1255 return AddressClass::eRuntime;
1257 return AddressClass::eRuntime;
1259 return AddressClass::eDebug;
1261 return AddressClass::eDebug;
1263 return AddressClass::eDebug;
1265 return AddressClass::eDebug;
1267 return AddressClass::eDebug;
1269 return AddressClass::eData;
1271 return AddressClass::eData;
1273 return AddressClass::eData;
1275 return AddressClass::eDebug;
1277 return AddressClass::eDebug;
1279 return AddressClass::eDebug;
1281 return AddressClass::eDebug;
1283 return AddressClass::eDebug;
1285 return AddressClass::eUnknown;
1287 return AddressClass::eDebug;
1289 return AddressClass::eDebug;
1291 return AddressClass::eUnknown;
1293 return AddressClass::eRuntime;
1295 return AddressClass::eRuntime;
1297 return AddressClass::eRuntime;
1299 return AddressClass::eRuntime;
1302 return AddressClass::eUnknown;
1310 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1313 llvm::MachO::load_command lc = {};
1316 if (lc.cmd == LC_DYSYMTAB) {
1320 (
sizeof(
m_dysymtab) /
sizeof(uint32_t)) - 2) ==
1327 offset = load_cmd_offset + lc.cmdsize;
1340 llvm::MachO::encryption_info_command encryption_cmd;
1341 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1343 if (
m_data.
GetU32(&offset, &encryption_cmd, 2) ==
nullptr)
1348 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
1349 encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
1350 if (
m_data.
GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
1351 if (encryption_cmd.cryptid != 0) {
1359 offset = load_cmd_offset + encryption_cmd.cmdsize;
1366 llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx) {
1367 if (
m_length == 0 || seg_cmd.filesize == 0)
1376 sizeof(seg_cmd.segname)) == 0)
1379 sizeof(seg_cmd.segname)) == 0)
1392 const char *lc_segment_name =
1393 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1395 "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "
1396 "the end of the file ({3:x16}), ignoring this section",
1397 cmd_idx, lc_segment_name, seg_cmd.fileoff,
m_length);
1399 seg_cmd.fileoff = 0;
1400 seg_cmd.filesize = 0;
1403 if (seg_cmd.fileoff + seg_cmd.filesize >
m_length) {
1410 const char *lc_segment_name =
1411 seg_cmd.cmd == LC_SEGMENT_64 ?
"LC_SEGMENT_64" :
"LC_SEGMENT";
1413 "load command {0} {1} has a fileoff + filesize ({2:x16}) that "
1414 "extends beyond the end of the file ({3:x16}), the segment will be "
1415 "truncated to match",
1416 cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize,
m_length);
1419 seg_cmd.filesize =
m_length - seg_cmd.fileoff;
1425 uint32_t result = 0;
1426 if (seg_cmd.initprot & VM_PROT_READ)
1427 result |= ePermissionsReadable;
1428 if (seg_cmd.initprot & VM_PROT_WRITE)
1429 result |= ePermissionsWritable;
1430 if (seg_cmd.initprot & VM_PROT_EXECUTE)
1431 result |= ePermissionsExecutable;
1438 if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1441 uint32_t mach_sect_type = flags & SECTION_TYPE;
1442 static ConstString g_sect_name_objc_data(
"__objc_data");
1443 static ConstString g_sect_name_objc_msgrefs(
"__objc_msgrefs");
1444 static ConstString g_sect_name_objc_selrefs(
"__objc_selrefs");
1445 static ConstString g_sect_name_objc_classrefs(
"__objc_classrefs");
1446 static ConstString g_sect_name_objc_superrefs(
"__objc_superrefs");
1447 static ConstString g_sect_name_objc_const(
"__objc_const");
1448 static ConstString g_sect_name_objc_classlist(
"__objc_classlist");
1449 static ConstString g_sect_name_cfstring(
"__cfstring");
1451 static ConstString g_sect_name_dwarf_debug_abbrev(
"__debug_abbrev");
1452 static ConstString g_sect_name_dwarf_debug_abbrev_dwo(
"__debug_abbrev.dwo");
1453 static ConstString g_sect_name_dwarf_debug_addr(
"__debug_addr");
1454 static ConstString g_sect_name_dwarf_debug_aranges(
"__debug_aranges");
1455 static ConstString g_sect_name_dwarf_debug_cu_index(
"__debug_cu_index");
1456 static ConstString g_sect_name_dwarf_debug_frame(
"__debug_frame");
1457 static ConstString g_sect_name_dwarf_debug_info(
"__debug_info");
1458 static ConstString g_sect_name_dwarf_debug_info_dwo(
"__debug_info.dwo");
1459 static ConstString g_sect_name_dwarf_debug_line(
"__debug_line");
1460 static ConstString g_sect_name_dwarf_debug_line_dwo(
"__debug_line.dwo");
1461 static ConstString g_sect_name_dwarf_debug_line_str(
"__debug_line_str");
1462 static ConstString g_sect_name_dwarf_debug_loc(
"__debug_loc");
1463 static ConstString g_sect_name_dwarf_debug_loclists(
"__debug_loclists");
1464 static ConstString g_sect_name_dwarf_debug_loclists_dwo(
"__debug_loclists.dwo");
1465 static ConstString g_sect_name_dwarf_debug_macinfo(
"__debug_macinfo");
1466 static ConstString g_sect_name_dwarf_debug_macro(
"__debug_macro");
1467 static ConstString g_sect_name_dwarf_debug_macro_dwo(
"__debug_macro.dwo");
1468 static ConstString g_sect_name_dwarf_debug_names(
"__debug_names");
1469 static ConstString g_sect_name_dwarf_debug_pubnames(
"__debug_pubnames");
1470 static ConstString g_sect_name_dwarf_debug_pubtypes(
"__debug_pubtypes");
1471 static ConstString g_sect_name_dwarf_debug_ranges(
"__debug_ranges");
1472 static ConstString g_sect_name_dwarf_debug_rnglists(
"__debug_rnglists");
1473 static ConstString g_sect_name_dwarf_debug_str(
"__debug_str");
1474 static ConstString g_sect_name_dwarf_debug_str_dwo(
"__debug_str.dwo");
1475 static ConstString g_sect_name_dwarf_debug_str_offs(
"__debug_str_offs");
1476 static ConstString g_sect_name_dwarf_debug_str_offs_dwo(
"__debug_str_offs.dwo");
1477 static ConstString g_sect_name_dwarf_debug_tu_index(
"__debug_tu_index");
1478 static ConstString g_sect_name_dwarf_debug_types(
"__debug_types");
1479 static ConstString g_sect_name_dwarf_apple_names(
"__apple_names");
1480 static ConstString g_sect_name_dwarf_apple_types(
"__apple_types");
1481 static ConstString g_sect_name_dwarf_apple_namespaces(
"__apple_namespac");
1482 static ConstString g_sect_name_dwarf_apple_objc(
"__apple_objc");
1483 static ConstString g_sect_name_eh_frame(
"__eh_frame");
1484 static ConstString g_sect_name_compact_unwind(
"__unwind_info");
1487 static ConstString g_sect_name_go_symtab(
"__gosymtab");
1489 static ConstString g_sect_name_lldb_summaries(
"__lldbsummaries");
1490 static ConstString g_sect_name_lldb_formatters(
"__lldbformatters");
1491 static ConstString g_sect_name_swift_ast(
"__swift_ast");
1493 if (section_name == g_sect_name_dwarf_debug_abbrev)
1495 if (section_name == g_sect_name_dwarf_debug_abbrev_dwo)
1497 if (section_name == g_sect_name_dwarf_debug_addr)
1499 if (section_name == g_sect_name_dwarf_debug_aranges)
1501 if (section_name == g_sect_name_dwarf_debug_cu_index)
1503 if (section_name == g_sect_name_dwarf_debug_frame)
1505 if (section_name == g_sect_name_dwarf_debug_info)
1507 if (section_name == g_sect_name_dwarf_debug_info_dwo)
1509 if (section_name == g_sect_name_dwarf_debug_line)
1511 if (section_name == g_sect_name_dwarf_debug_line_dwo)
1513 if (section_name == g_sect_name_dwarf_debug_line_str)
1515 if (section_name == g_sect_name_dwarf_debug_loc)
1517 if (section_name == g_sect_name_dwarf_debug_loclists)
1519 if (section_name == g_sect_name_dwarf_debug_loclists_dwo)
1521 if (section_name == g_sect_name_dwarf_debug_macinfo)
1523 if (section_name == g_sect_name_dwarf_debug_macro)
1525 if (section_name == g_sect_name_dwarf_debug_macro_dwo)
1527 if (section_name == g_sect_name_dwarf_debug_names)
1529 if (section_name == g_sect_name_dwarf_debug_pubnames)
1531 if (section_name == g_sect_name_dwarf_debug_pubtypes)
1533 if (section_name == g_sect_name_dwarf_debug_ranges)
1535 if (section_name == g_sect_name_dwarf_debug_rnglists)
1537 if (section_name == g_sect_name_dwarf_debug_str)
1539 if (section_name == g_sect_name_dwarf_debug_str_dwo)
1541 if (section_name == g_sect_name_dwarf_debug_str_offs)
1543 if (section_name == g_sect_name_dwarf_debug_str_offs_dwo)
1545 if (section_name == g_sect_name_dwarf_debug_tu_index)
1547 if (section_name == g_sect_name_dwarf_debug_types)
1549 if (section_name == g_sect_name_dwarf_apple_names)
1551 if (section_name == g_sect_name_dwarf_apple_types)
1553 if (section_name == g_sect_name_dwarf_apple_namespaces)
1555 if (section_name == g_sect_name_dwarf_apple_objc)
1557 if (section_name == g_sect_name_objc_selrefs)
1559 if (section_name == g_sect_name_objc_msgrefs)
1561 if (section_name == g_sect_name_eh_frame)
1563 if (section_name == g_sect_name_compact_unwind)
1565 if (section_name == g_sect_name_cfstring)
1567 if (section_name == g_sect_name_go_symtab)
1569 if (section_name == g_sect_name_ctf)
1571 if (section_name == g_sect_name_lldb_summaries)
1573 if (section_name == g_sect_name_lldb_formatters)
1575 if (section_name == g_sect_name_swift_ast)
1577 if (section_name == g_sect_name_objc_data ||
1578 section_name == g_sect_name_objc_classrefs ||
1579 section_name == g_sect_name_objc_superrefs ||
1580 section_name == g_sect_name_objc_const ||
1581 section_name == g_sect_name_objc_classlist) {
1585 switch (mach_sect_type) {
1588 if (section_name == g_sect_name_text)
1590 if (section_name == g_sect_name_data)
1595 case S_CSTRING_LITERALS:
1597 case S_4BYTE_LITERALS:
1599 case S_8BYTE_LITERALS:
1601 case S_LITERAL_POINTERS:
1603 case S_NON_LAZY_SYMBOL_POINTERS:
1605 case S_LAZY_SYMBOL_POINTERS:
1607 case S_SYMBOL_STUBS:
1610 case S_MOD_INIT_FUNC_POINTERS:
1613 case S_MOD_TERM_FUNC_POINTERS:
1623 case S_16BYTE_LITERALS:
1627 case S_LAZY_DYLIB_SYMBOL_POINTERS:
1647 const llvm::MachO::load_command &load_cmd_,
lldb::offset_t offset,
1649 llvm::MachO::segment_command_64 load_cmd;
1650 memcpy(&load_cmd, &load_cmd_,
sizeof(load_cmd_));
1652 if (!
m_data.
GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
1657 const bool is_dsym = (
m_header.filetype == MH_DSYM);
1658 bool add_section =
true;
1659 bool add_to_unified =
true;
1661 load_cmd.segname, strnlen(load_cmd.segname,
sizeof(load_cmd.segname)));
1665 if (is_dsym && unified_section_sp) {
1669 add_to_unified =
false;
1673 add_section =
false;
1686 const bool segment_is_encrypted =
1687 (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
1692 if (add_section && (const_segname || is_core)) {
1693 segment_sp = std::make_shared<Section>(
1713 segment_sp->SetIsEncrypted(segment_is_encrypted);
1715 segment_sp->SetPermissions(segment_permissions);
1718 }
else if (unified_section_sp) {
1728 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
1732 "Installing dSYM's %s segment file address over ObjectFile's "
1733 "so symbol table/debug info resolves correctly for %s",
1735 module_sp->GetFileSpec().GetFilename().AsCString());
1740 module_sp->GetObjectFile()->GetSymtab();
1746 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
1755 llvm::MachO::section_64 sect64;
1756 ::memset(§64, 0,
sizeof(sect64));
1761 uint32_t segment_sect_idx;
1764 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
1765 for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
1766 ++segment_sect_idx) {
1767 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.sectname,
1768 sizeof(sect64.sectname)) ==
nullptr)
1770 if (
m_data.
GetU8(&offset, (uint8_t *)sect64.segname,
1771 sizeof(sect64.segname)) ==
nullptr)
1776 if (
m_data.
GetU32(&offset, §64.offset, num_u32s) ==
nullptr)
1789 sect64.sectname, strnlen(sect64.sectname,
sizeof(sect64.sectname)));
1790 if (!const_segname) {
1798 sizeof(sect64.segname));
1800 if (segment_sp.get()) {
1801 Section *segment = segment_sp.get();
1804 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1808 curr_seg_min_addr + curr_seg_byte_size;
1809 if (sect64_min_addr >= curr_seg_min_addr) {
1811 sect64_max_addr - curr_seg_min_addr;
1813 if (new_seg_byte_size > curr_seg_byte_size)
1819 sect64_min_addr - curr_seg_min_addr;
1820 segment->
Slide(slide_amount,
false);
1822 segment->
SetByteSize(curr_seg_max_addr - sect64_min_addr);
1826 if (sect64.offset) {
1832 const lldb::addr_t section_min_file_offset = sect64.offset;
1834 section_min_file_offset + sect64.size;
1836 std::min(section_min_file_offset, segment_min_file_offset);
1838 std::max(section_max_file_offset, segment_max_file_offset) -
1845 segment_sp = std::make_shared<Section>(
1862 sect64.offset ? sect64.size : 0,
1867 segment_sp->SetIsFake(
true);
1868 segment_sp->SetPermissions(segment_permissions);
1872 segment_sp->SetIsEncrypted(segment_is_encrypted);
1875 assert(segment_sp.get());
1880 segment_sp, module_sp,
this, ++context.
NextSectionIdx, section_name,
1881 sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
1882 sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
1886 bool section_is_encrypted =
false;
1887 if (!segment_is_encrypted && load_cmd.filesize != 0)
1889 sect64.offset) !=
nullptr;
1891 section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
1892 section_sp->SetPermissions(segment_permissions);
1893 segment_sp->GetChildren().AddSection(section_sp);
1895 if (segment_sp->IsFake()) {
1897 const_segname.
Clear();
1901 if (segment_sp && is_dsym) {
1904 for (sect_uid = first_segment_sectID; sect_uid <= context.
NextSectionIdx;
1907 segment_sp->GetChildren().FindSectionByID(sect_uid));
1911 segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
1913 if (curr_section_sp.get()) {
1914 if (curr_section_sp->GetByteSize() == 0) {
1915 if (next_section_sp.get() !=
nullptr)
1916 curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
1917 curr_section_sp->GetFileAddress());
1919 curr_section_sp->SetByteSize(load_cmd.vmsize);
1928 const llvm::MachO::load_command &load_cmd,
lldb::offset_t offset) {
1932 (
sizeof(
m_dysymtab) /
sizeof(uint32_t)) - 2);
1948 llvm::MachO::load_command load_cmd;
1949 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
1954 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
1956 else if (load_cmd.cmd == LC_DYSYMTAB)
1959 offset = load_cmd_offset + load_cmd.cmdsize;
1963 module_sp->SectionFileAddressesChanged();
1985 section_sp->GetFileAddress());
1987 section_sp->GetByteSize());
1989 std::string filename =
"<unknown>";
1991 if (first_section_sp)
1992 filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
1995 llvm::formatv(
"unable to find section {0} for a symbol in "
1996 "{1}, corrupt file?",
2026#define TRIE_SYMBOL_IS_THUMB (1ULL << 63)
2029 printf(
"0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2030 static_cast<unsigned long long>(
address),
2031 static_cast<unsigned long long>(
flags),
2054 printf(
"[%3u] 0x%16.16llx: ", idx,
2055 static_cast<unsigned long long>(
nodeOffset));
2065 const bool is_arm,
addr_t text_seg_base_addr,
2066 std::vector<llvm::StringRef> &nameSlices,
2067 std::set<lldb::addr_t> &resolver_addresses,
2068 std::vector<TrieEntryWithOffset> &reexports,
2069 std::vector<TrieEntryWithOffset> &ext_symbols) {
2075 const uint64_t terminalSize = data.
GetULEB128(&offset);
2077 if (terminalSize != 0) {
2080 const char *import_name =
nullptr;
2081 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
2084 import_name = data.
GetCStr(&offset);
2089 if (e.
entry.
flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
2093 resolver_addr += text_seg_base_addr;
2096 resolver_addresses.insert(resolver_addr);
2100 bool add_this_entry =
false;
2102 import_name && import_name[0]) {
2104 add_this_entry =
true;
2106 (import_name ==
nullptr || import_name[0] ==
'\0')) {
2109 add_this_entry =
true;
2111 if (add_this_entry) {
2113 if (!nameSlices.empty()) {
2114 for (
auto name_slice : nameSlices)
2115 name.append(name_slice.data(), name_slice.size());
2117 if (name.size() > 1) {
2126 reexports.push_back(e);
2132 ext_symbols.push_back(e);
2137 const uint8_t childrenCount = data.
GetU8(&children_offset);
2138 for (uint8_t i = 0; i < childrenCount; ++i) {
2139 const char *cstr = data.
GetCStr(&children_offset);
2141 nameSlices.push_back(llvm::StringRef(cstr));
2145 if (childNodeOffset) {
2147 nameSlices, resolver_addresses, reexports,
2152 nameSlices.pop_back();
2158 bool &demangled_is_synthesized,
2166 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2167 if (symbol_section->IsDescendant(text_section_sp.get())) {
2168 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
2169 S_ATTR_SELF_MODIFYING_CODE |
2170 S_ATTR_SOME_INSTRUCTIONS))
2174 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
2175 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
2176 symbol_section->IsDescendant(data_const_section_sp.get())) {
2177 if (symbol_sect_name &&
2178 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
2182 llvm::StringRef symbol_name_ref(symbol_name);
2183 if (symbol_name_ref.starts_with(
"OBJC_")) {
2184 static const llvm::StringRef g_objc_v2_prefix_class(
"OBJC_CLASS_$_");
2185 static const llvm::StringRef g_objc_v2_prefix_metaclass(
2186 "OBJC_METACLASS_$_");
2187 static const llvm::StringRef g_objc_v2_prefix_ivar(
"OBJC_IVAR_$_");
2188 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
2189 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2191 demangled_is_synthesized =
true;
2192 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
2193 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2195 demangled_is_synthesized =
true;
2196 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
2197 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2199 demangled_is_synthesized =
true;
2203 }
else if (symbol_sect_name &&
2204 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
2210 }
else if (symbol_sect_name &&
2211 ::strstr(symbol_sect_name,
"__IMPORT") == symbol_sect_name) {
2217static std::optional<struct nlist_64>
2219 size_t nlist_byte_size) {
2220 struct nlist_64 nlist;
2243 LLDB_LOG(log,
"Parsing symbol table for {0}", file_name);
2244 Progress progress(
"Parsing symbol table", file_name);
2246 llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
2247 llvm::MachO::linkedit_data_command exports_trie_load_command = {0, 0, 0, 0};
2248 llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2249 llvm::MachO::dysymtab_command dysymtab =
m_dysymtab;
2259 llvm::DenseSet<addr_t> symbols_added;
2263 auto add_symbol_addr = [&symbols_added](
lldb::addr_t file_addr) {
2267 symbols_added.insert(file_addr);
2269 FunctionStarts function_starts;
2273 llvm::StringRef g_objc_v2_prefix_class(
"_OBJC_CLASS_$_");
2274 llvm::StringRef g_objc_v2_prefix_metaclass(
"_OBJC_METACLASS_$_");
2275 llvm::StringRef g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
2278 for (i = 0; i <
m_header.ncmds; ++i) {
2281 llvm::MachO::load_command lc;
2295 symtab_load_command.
cmd = lc.cmd;
2296 symtab_load_command.
cmdsize = lc.cmdsize;
2304 case LC_DYLD_INFO_ONLY:
2305 if (
m_data.
GetU32(&offset, &dyld_info.rebase_off, 10)) {
2306 dyld_info.cmd = lc.cmd;
2307 dyld_info.cmdsize = lc.cmdsize;
2309 memset(&dyld_info, 0,
sizeof(dyld_info));
2314 case LC_LOAD_WEAK_DYLIB:
2315 case LC_REEXPORT_DYLIB:
2317 case LC_LOAD_UPWARD_DYLIB: {
2318 uint32_t name_offset = cmd_offset +
m_data.
GetU32(&offset);
2327 if (lc.cmd == LC_REEXPORT_DYLIB) {
2331 dylib_files.
Append(file_spec);
2335 case LC_DYLD_EXPORTS_TRIE:
2336 exports_trie_load_command.cmd = lc.cmd;
2337 exports_trie_load_command.cmdsize = lc.cmdsize;
2338 if (
m_data.
GetU32(&offset, &exports_trie_load_command.dataoff, 2) ==
2340 memset(&exports_trie_load_command, 0,
2341 sizeof(exports_trie_load_command));
2343 case LC_FUNCTION_STARTS:
2344 function_starts_load_command.cmd = lc.cmd;
2345 function_starts_load_command.cmdsize = lc.cmdsize;
2346 if (
m_data.
GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
2348 memset(&function_starts_load_command, 0,
2349 sizeof(function_starts_load_command));
2356 image_uuid =
UUID(uuid_bytes, 16);
2363 offset = cmd_offset + lc.cmdsize;
2366 if (!symtab_load_command.
cmd)
2370 if (section_list ==
nullptr)
2375 bool bit_width_32 = addr_byte_size == 4;
2376 const size_t nlist_byte_size =
2377 bit_width_32 ?
sizeof(
struct nlist) : sizeof(struct nlist_64);
2379 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);
2380 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);
2381 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);
2382 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,
2384 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);
2386 const
addr_t nlist_data_byte_size =
2387 symtab_load_command.nsyms * nlist_byte_size;
2388 const
addr_t strtab_data_byte_size = symtab_load_command.strsize;
2391 ProcessSP process_sp(m_process_wp.lock());
2392 Process *process = process_sp.get();
2396 bool is_local_shared_cache_image = is_shared_cache_image && !
IsInMemory();
2398 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2400 if (process && m_header.filetype != llvm::MachO::MH_OBJECT &&
2401 !is_local_shared_cache_image) {
2402 Target &target = process->GetTarget();
2408 if (linkedit_section_sp) {
2409 addr_t linkedit_load_addr =
2410 linkedit_section_sp->GetLoadBaseAddress(&target);
2416 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
2417 m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2420 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2421 const addr_t symoff_addr = linkedit_load_addr +
2422 symtab_load_command.
symoff -
2423 linkedit_file_offset;
2424 strtab_addr = linkedit_load_addr + symtab_load_command.
stroff -
2425 linkedit_file_offset;
2433 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2435 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2437 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2438 if (dysymtab.nindirectsyms != 0) {
2439 const addr_t indirect_syms_addr = linkedit_load_addr +
2440 dysymtab.indirectsymoff -
2441 linkedit_file_offset;
2443 process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
2444 if (indirect_syms_data_sp)
2445 indirect_symbol_index_data.SetData(
2446 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2456 if (!is_shared_cache_image) {
2458 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
2459 if (strtab_data_sp) {
2460 strtab_data.SetData(strtab_data_sp, 0,
2461 strtab_data_sp->GetByteSize());
2466 if (function_starts_load_command.cmd) {
2467 const addr_t func_start_addr =
2468 linkedit_load_addr + function_starts_load_command.dataoff -
2469 linkedit_file_offset;
2471 ReadMemory(process_sp, func_start_addr,
2472 function_starts_load_command.datasize));
2473 if (func_start_data_sp)
2474 function_starts_data.SetData(func_start_data_sp, 0,
2475 func_start_data_sp->GetByteSize());
2481 if (is_local_shared_cache_image) {
2489 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();
2492 symtab_load_command.
symoff += linkedit_slide;
2493 symtab_load_command.
stroff += linkedit_slide;
2494 dyld_info.export_off += linkedit_slide;
2495 dysymtab.indirectsymoff += linkedit_slide;
2496 function_starts_load_command.dataoff += linkedit_slide;
2497 exports_trie_load_command.dataoff += linkedit_slide;
2501 nlist_data_byte_size);
2502 strtab_data.SetData(
m_data, symtab_load_command.
stroff,
2503 strtab_data_byte_size);
2508 && (exports_trie_load_command.datasize > 0)));
2509 if (dyld_info.export_size > 0) {
2510 dyld_trie_data.SetData(
m_data, dyld_info.export_off,
2511 dyld_info.export_size);
2512 }
else if (exports_trie_load_command.datasize > 0) {
2513 dyld_trie_data.SetData(
m_data, exports_trie_load_command.dataoff,
2514 exports_trie_load_command.datasize);
2517 if (dysymtab.nindirectsyms != 0) {
2518 indirect_symbol_index_data.SetData(
m_data, dysymtab.indirectsymoff,
2519 dysymtab.nindirectsyms * 4);
2521 if (function_starts_load_command.cmd) {
2522 function_starts_data.SetData(
m_data, function_starts_load_command.dataoff,
2523 function_starts_load_command.datasize);
2527 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2546 if (text_section_sp.get())
2547 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2548 g_section_name_eh_frame);
2550 eh_frame_section_sp =
2553 const bool is_arm = (
m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
2570 if (text_section_sp && function_starts_data.GetByteSize()) {
2571 FunctionStarts::Entry function_start_entry;
2572 function_start_entry.data =
false;
2574 function_start_entry.addr = text_section_sp->GetFileAddress();
2576 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2579 function_start_entry.addr += delta;
2581 if (function_start_entry.addr & 1) {
2583 function_start_entry.data =
true;
2584 }
else if (always_thumb) {
2585 function_start_entry.data =
true;
2588 function_starts.Append(function_start_entry);
2596 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2602 addr_t text_base_addr = text_section_sp->GetFileAddress();
2603 size_t count = functions.
GetSize();
2604 for (
size_t i = 0; i < count; ++i) {
2608 FunctionStarts::Entry function_start_entry;
2609 function_start_entry.addr = func->
base - text_base_addr;
2611 if (function_start_entry.addr & 1) {
2613 function_start_entry.data =
true;
2614 }
else if (always_thumb) {
2615 function_start_entry.data =
true;
2618 function_starts.Append(function_start_entry);
2624 const size_t function_starts_count = function_starts.GetSize();
2637 Log *unwind_or_symbol_log(
GetLog(LLDBLog::Symbols | LLDBLog::Unwind));
2639 if (unwind_or_symbol_log)
2640 module_sp->LogMessage(
2641 unwind_or_symbol_log,
2642 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2645 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()
2646 ? eh_frame_section_sp->GetID()
2652 std::vector<uint32_t> N_FUN_indexes;
2653 std::vector<uint32_t> N_NSYM_indexes;
2654 std::vector<uint32_t> N_INCL_indexes;
2655 std::vector<uint32_t> N_BRAC_indexes;
2656 std::vector<uint32_t> N_COMM_indexes;
2657 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2658 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2659 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;
2660 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2661 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2662 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2665 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2666 uint32_t nlist_idx = 0;
2667 Symbol *symbol_ptr =
nullptr;
2669 uint32_t sym_idx = 0;
2671 size_t num_syms = 0;
2672 std::string memory_symbol_name;
2673 uint32_t unmapped_local_symbols_found = 0;
2675 std::vector<TrieEntryWithOffset> reexport_trie_entries;
2676 std::vector<TrieEntryWithOffset> external_sym_trie_entries;
2677 std::set<lldb::addr_t> resolver_addresses;
2679 const size_t dyld_trie_data_size = dyld_trie_data.
GetByteSize();
2680 if (dyld_trie_data_size > 0) {
2681 LLDB_LOG(log,
"Parsing {0} bytes of dyld trie data", dyld_trie_data_size);
2685 if (text_segment_sp)
2686 text_segment_file_addr = text_segment_sp->GetFileAddress();
2687 std::vector<llvm::StringRef> nameSlices;
2689 nameSlices, resolver_addresses, reexport_trie_entries,
2690 external_sym_trie_entries);
2693 typedef std::set<ConstString> IndirectSymbols;
2694 IndirectSymbols indirect_symbol_names;
2717 UUID process_shared_cache_uuid;
2718 addr_t process_shared_cache_base_addr;
2722 process_shared_cache_uuid);
2725 __block
bool found_image =
false;
2726 __block
void *nlist_buffer =
nullptr;
2727 __block
unsigned nlist_count = 0;
2728 __block
char *string_table =
nullptr;
2729 __block vm_offset_t vm_nlist_memory = 0;
2730 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;
2731 __block vm_offset_t vm_string_memory = 0;
2732 __block mach_msg_type_number_t vm_string_bytes_read = 0;
2734 auto _ = llvm::make_scope_exit(^{
2735 if (vm_nlist_memory)
2736 vm_deallocate(
mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);
2737 if (vm_string_memory)
2738 vm_deallocate(
mach_task_self(), vm_string_memory, vm_string_bytes_read);
2741 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
2742 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
2743 UndefinedNameToDescMap undefined_name_to_desc;
2744 SymbolIndexToName reexport_shlib_needs_fixup;
2746 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {
2748 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);
2752 if (process_shared_cache_uuid.
IsValid() &&
2753 process_shared_cache_uuid != UUID::fromData(&cache_uuid, 16))
2756 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
2761 dyld_image_copy_uuid(image, &dsc_image_uuid);
2762 if (image_uuid != UUID::fromData(dsc_image_uuid, 16))
2769 dyld_image_local_nlist_content_4Symbolication(
2770 image, ^(
const void *nlistStart, uint64_t nlistCount,
2771 const char *stringTable) {
2772 if (!nlistStart || !nlistCount)
2780 nlist_byte_size * nlistCount, &vm_nlist_memory,
2781 &vm_nlist_bytes_read);
2784 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);
2789 vm_address_t string_address = (vm_address_t)stringTable;
2790 vm_size_t region_size;
2791 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
2792 vm_region_basic_info_data_t info;
2793 memory_object_name_t object;
2795 ®ion_size, VM_REGION_BASIC_INFO_64,
2796 (vm_region_info_t)&info, &info_count, &
object);
2802 ((vm_address_t)stringTable - string_address),
2803 &vm_string_memory, &vm_string_bytes_read);
2807 nlist_buffer = (
void *)vm_nlist_memory;
2808 string_table = (
char *)vm_string_memory;
2809 nlist_count = nlistCount;
2815 nlist_count * nlist_byte_size,
2816 byte_order, addr_byte_size);
2817 unmapped_local_symbols_found = nlist_count;
2823 unmapped_local_symbols_found -
m_dysymtab.nlocalsym);
2828 for (uint32_t nlist_index = 0;
2829 nlist_index < nlist_count;
2833 std::optional<struct nlist_64> nlist_maybe =
2834 ParseNList(dsc_local_symbols_data, nlist_data_offset,
2838 struct nlist_64 nlist = *nlist_maybe;
2841 const char *symbol_name = string_table + nlist.n_strx;
2843 if (symbol_name == NULL) {
2848 "DSC unmapped local symbol[{0}] has invalid "
2849 "string table offset {1:x} in {2}, ignoring symbol",
2850 nlist_index, nlist.n_strx,
2851 module_sp->GetFileSpec().GetPath());
2854 if (symbol_name[0] ==
'\0')
2857 const char *symbol_name_non_abi_mangled = NULL;
2860 uint32_t symbol_byte_size = 0;
2861 bool add_nlist =
true;
2862 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2863 bool demangled_is_synthesized =
false;
2864 bool is_gsym =
false;
2865 bool set_value =
true;
2867 assert(sym_idx < num_syms);
2872 switch (nlist.n_type) {
2891 if (symbol_name && symbol_name[0] ==
'_' &&
2892 symbol_name[1] ==
'O') {
2893 llvm::StringRef symbol_name_ref(symbol_name);
2894 if (symbol_name_ref.starts_with(
2895 g_objc_v2_prefix_class)) {
2896 symbol_name_non_abi_mangled = symbol_name + 1;
2898 symbol_name + g_objc_v2_prefix_class.size();
2900 demangled_is_synthesized =
true;
2902 }
else if (symbol_name_ref.starts_with(
2903 g_objc_v2_prefix_metaclass)) {
2904 symbol_name_non_abi_mangled = symbol_name + 1;
2906 symbol_name + g_objc_v2_prefix_metaclass.size();
2908 demangled_is_synthesized =
true;
2909 }
else if (symbol_name_ref.starts_with(
2910 g_objc_v2_prefix_ivar)) {
2911 symbol_name_non_abi_mangled = symbol_name + 1;
2913 symbol_name + g_objc_v2_prefix_ivar.size();
2915 demangled_is_synthesized =
true;
2918 if (nlist.n_value != 0)
2920 nlist.n_sect, nlist.n_value);
2935 nlist.n_sect, nlist.n_value);
2937 N_FUN_addr_to_sym_idx.insert(
2938 std::make_pair(nlist.n_value, sym_idx));
2942 N_FUN_indexes.push_back(sym_idx);
2946 if (!N_FUN_indexes.empty()) {
2953 N_FUN_indexes.pop_back();
2965 N_STSYM_addr_to_sym_idx.insert(
2966 std::make_pair(nlist.n_value, sym_idx));
2967 symbol_section = section_info.
GetSection(nlist.n_sect,
2969 if (symbol_name && symbol_name[0]) {
2977 symbol_section = section_info.
GetSection(nlist.n_sect,
3011 symbol_section = section_info.
GetSection(nlist.n_sect,
3024 if (symbol_name == NULL) {
3035 N_NSYM_indexes.clear();
3036 N_INCL_indexes.clear();
3037 N_BRAC_indexes.clear();
3038 N_COMM_indexes.clear();
3039 N_FUN_indexes.clear();
3045 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3046 if (N_SO_has_full_path) {
3047 if ((N_SO_index == sym_idx - 1) &&
3048 ((sym_idx - 1) < num_syms)) {
3054 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3060 N_SO_index = sym_idx;
3062 }
else if ((N_SO_index == sym_idx - 1) &&
3063 ((sym_idx - 1) < num_syms)) {
3068 const char *so_path = sym[sym_idx - 1]
3072 if (so_path && so_path[0]) {
3073 std::string full_so_path(so_path);
3074 const size_t double_slash_pos =
3075 full_so_path.find(
"//");
3076 if (double_slash_pos != std::string::npos) {
3087 &full_so_path[double_slash_pos + 1],
3088 FileSpec::Style::native);
3091 full_so_path.erase(0, double_slash_pos + 1);
3095 if (*full_so_path.rbegin() !=
'/')
3096 full_so_path +=
'/';
3097 full_so_path += symbol_name;
3101 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3105 N_SO_index = sym_idx;
3126 N_INCL_indexes.push_back(sym_idx);
3136 if (!N_INCL_indexes.empty()) {
3141 N_INCL_indexes.pop_back();
3176 symbol_section = section_info.
GetSection(nlist.n_sect,
3187 symbol_section = section_info.
GetSection(nlist.n_sect,
3189 N_BRAC_indexes.push_back(sym_idx);
3199 symbol_section = section_info.
GetSection(nlist.n_sect,
3201 if (!N_BRAC_indexes.empty()) {
3206 N_BRAC_indexes.pop_back();
3223 N_COMM_indexes.push_back(sym_idx);
3228 symbol_section = section_info.
GetSection(nlist.n_sect,
3239 if (!N_COMM_indexes.empty()) {
3244 N_COMM_indexes.pop_back();
3259 uint8_t n_type = N_TYPE & nlist.n_type;
3260 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
3264 const char *reexport_name_cstr =
3265 strtab_data.PeekCStr(nlist.n_value);
3266 if (reexport_name_cstr && reexport_name_cstr[0]) {
3269 reexport_name_cstr +
3270 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
3273 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3275 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
3281 if (symbol_name && symbol_name[0]) {
3283 symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0));
3284 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3296 symbol_section = section_info.
GetSection(nlist.n_sect,
3299 if (symbol_section == NULL) {
3305 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3308 uint32_t section_type =
3309 symbol_section->Get() & SECTION_TYPE;
3311 switch (section_type) {
3312 case S_CSTRING_LITERALS:
3315 case S_4BYTE_LITERALS:
3318 case S_8BYTE_LITERALS:
3321 case S_LITERAL_POINTERS:
3324 case S_NON_LAZY_SYMBOL_POINTERS:
3328 case S_LAZY_SYMBOL_POINTERS:
3331 case S_SYMBOL_STUBS:
3335 case S_MOD_INIT_FUNC_POINTERS:
3339 case S_MOD_TERM_FUNC_POINTERS:
3347 case S_16BYTE_LITERALS:
3353 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3357 switch (symbol_section->GetType()) {
3384 const char *symbol_sect_name =
3385 symbol_section->GetName().AsCString();
3386 if (symbol_section->IsDescendant(
3387 text_section_sp.get())) {
3388 if (symbol_section->IsClear(
3389 S_ATTR_PURE_INSTRUCTIONS |
3390 S_ATTR_SELF_MODIFYING_CODE |
3391 S_ATTR_SOME_INSTRUCTIONS))
3395 }
else if (symbol_section->IsDescendant(
3396 data_section_sp.get()) ||
3397 symbol_section->IsDescendant(
3398 data_dirty_section_sp.get()) ||
3399 symbol_section->IsDescendant(
3400 data_const_section_sp.get())) {
3401 if (symbol_sect_name &&
3402 ::strstr(symbol_sect_name,
"__objc") ==
3407 llvm::StringRef symbol_name_ref(symbol_name);
3408 if (symbol_name_ref.starts_with(
"_OBJC_")) {
3410 g_objc_v2_prefix_class(
3413 g_objc_v2_prefix_metaclass(
3414 "_OBJC_METACLASS_$_");
3416 g_objc_v2_prefix_ivar(
"_OBJC_IVAR_$_");
3417 if (symbol_name_ref.starts_with(
3418 g_objc_v2_prefix_class)) {
3419 symbol_name_non_abi_mangled =
3423 g_objc_v2_prefix_class.size();
3425 demangled_is_synthesized =
true;
3427 symbol_name_ref.starts_with(
3428 g_objc_v2_prefix_metaclass)) {
3429 symbol_name_non_abi_mangled =
3433 g_objc_v2_prefix_metaclass.size();
3435 demangled_is_synthesized =
true;
3436 }
else if (symbol_name_ref.starts_with(
3437 g_objc_v2_prefix_ivar)) {
3438 symbol_name_non_abi_mangled =
3442 g_objc_v2_prefix_ivar.size();
3444 demangled_is_synthesized =
true;
3448 }
else if (symbol_sect_name &&
3449 ::strstr(symbol_sect_name,
3450 "__gcc_except_tab") ==
3456 }
else if (symbol_sect_name &&
3457 ::strstr(symbol_sect_name,
"__IMPORT") ==
3460 }
else if (symbol_section->IsDescendant(
3461 objc_section_sp.get())) {
3463 if (symbol_name && symbol_name[0] ==
'.') {
3464 llvm::StringRef symbol_name_ref(symbol_name);
3466 g_objc_v1_prefix_class(
".objc_class_name_");
3467 if (symbol_name_ref.starts_with(
3468 g_objc_v1_prefix_class)) {
3469 symbol_name_non_abi_mangled = symbol_name;
3470 symbol_name = symbol_name +
3471 g_objc_v1_prefix_class.size();
3473 demangled_is_synthesized =
true;
3484 uint64_t symbol_value = nlist.n_value;
3485 if (symbol_name_non_abi_mangled) {
3491 if (symbol_name && symbol_name[0] ==
'_') {
3498 if (is_gsym && is_debug) {
3499 const char *gsym_name =
3505 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3509 if (symbol_section) {
3510 const addr_t section_file_addr =
3511 symbol_section->GetFileAddress();
3512 if (symbol_byte_size == 0 &&
3513 function_starts_count > 0) {
3514 addr_t symbol_lookup_file_addr = nlist.n_value;
3519 FunctionStarts::Entry *func_start_entry =
3520 function_starts.FindEntry(symbol_lookup_file_addr,
3522 if (is_arm && func_start_entry) {
3526 if (func_start_entry->addr !=
3527 symbol_lookup_file_addr &&
3528 func_start_entry->addr !=
3529 (symbol_lookup_file_addr + 1)) {
3531 func_start_entry = NULL;
3534 if (func_start_entry) {
3535 func_start_entry->data =
true;
3537 addr_t symbol_file_addr = func_start_entry->addr;
3538 uint32_t symbol_flags = 0;
3540 if (symbol_file_addr & 1)
3545 const FunctionStarts::Entry *next_func_start_entry =
3546 function_starts.FindNextEntry(func_start_entry);
3547 const addr_t section_end_file_addr =
3549 symbol_section->GetByteSize();
3550 if (next_func_start_entry) {
3551 addr_t next_symbol_file_addr =
3552 next_func_start_entry->addr;
3558 symbol_byte_size = std::min<lldb::addr_t>(
3559 next_symbol_file_addr - symbol_file_addr,
3560 section_end_file_addr - symbol_file_addr);
3563 section_end_file_addr - symbol_file_addr;
3567 symbol_value -= section_file_addr;
3570 if (is_debug ==
false) {
3578 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3579 if (range.first != range.second) {
3580 bool found_it =
false;
3581 for (
auto pos = range.first; pos != range.second;
3583 if (sym[sym_idx].GetMangled().
GetName(
3587 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3593 sym[sym_idx].IsExternal());
3594 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3596 if (resolver_addresses.find(nlist.n_value) !=
3597 resolver_addresses.end())
3599 sym[sym_idx].
Clear();
3607 if (resolver_addresses.find(nlist.n_value) !=
3608 resolver_addresses.end())
3620 auto range = N_STSYM_addr_to_sym_idx.equal_range(
3622 if (range.first != range.second) {
3623 bool found_it =
false;
3624 for (
auto pos = range.first; pos != range.second;
3626 if (sym[sym_idx].GetMangled().
GetName(
3630 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3636 sym[sym_idx].IsExternal());
3637 sym[pos->second].
SetFlags(nlist.n_type << 16 |
3639 sym[sym_idx].
Clear();
3647 const char *gsym_name =
3655 ConstNameToSymbolIndexMap::const_iterator pos =
3656 N_GSYM_name_to_sym_idx.find(gsym_name);
3657 if (pos != N_GSYM_name_to_sym_idx.end()) {
3658 const uint32_t GSYM_sym_idx = pos->second;
3659 m_nlist_idx_to_sym_idx[nlist_idx] =
3668 add_symbol_addr(sym[GSYM_sym_idx]
3675 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 |
3677 sym[sym_idx].
Clear();
3685 sym[sym_idx].
SetID(nlist_idx);
3691 sym[sym_idx].GetAddress().GetFileAddress());
3693 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
3695 if (symbol_byte_size > 0)
3698 if (demangled_is_synthesized)
3702 sym[sym_idx].
Clear();
3709 for (
const auto &pos : reexport_shlib_needs_fixup) {
3710 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3711 if (undef_pos != undefined_name_to_desc.end()) {
3712 const uint8_t dylib_ordinal =
3713 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3714 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
3724 if (nlist_data.GetByteSize() > 0) {
3728 if (sym ==
nullptr) {
3734 if (unmapped_local_symbols_found) {
3736 nlist_data_offset += (
m_dysymtab.nlocalsym * nlist_byte_size);
3742 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;
3743 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;
3744 UndefinedNameToDescMap undefined_name_to_desc;
3745 SymbolIndexToName reexport_shlib_needs_fixup;
3753 auto ParseSymbolLambda = [&](
struct nlist_64 &nlist, uint32_t nlist_idx,
3755 const bool is_debug = ((nlist.n_type & N_STAB) != 0);
3756 if (is_debug != debug_only)
3759 const char *symbol_name_non_abi_mangled =
nullptr;
3760 const char *symbol_name =
nullptr;
3762 if (have_strtab_data) {
3763 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3765 if (symbol_name ==
nullptr) {
3769 "symbol[{0}] has invalid string table offset {1:x} in {2}, "
3771 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));
3774 if (symbol_name[0] ==
'\0')
3775 symbol_name =
nullptr;
3777 const addr_t str_addr = strtab_addr + nlist.n_strx;
3779 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3781 symbol_name = memory_symbol_name.c_str();
3787 bool add_nlist =
true;
3788 bool is_gsym =
false;
3789 bool demangled_is_synthesized =
false;
3790 bool set_value =
true;
3792 assert(sym_idx < num_syms);
3796 switch (nlist.n_type) {
3813 if (symbol_name && symbol_name[0] ==
'_' && symbol_name[1] ==
'O') {
3814 llvm::StringRef symbol_name_ref(symbol_name);
3815 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
3816 symbol_name_non_abi_mangled = symbol_name + 1;
3817 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3819 demangled_is_synthesized =
true;
3821 }
else if (symbol_name_ref.starts_with(
3822 g_objc_v2_prefix_metaclass)) {
3823 symbol_name_non_abi_mangled = symbol_name + 1;
3824 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3826 demangled_is_synthesized =
true;
3827 }
else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
3828 symbol_name_non_abi_mangled = symbol_name + 1;
3829 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3831 demangled_is_synthesized =
true;
3834 if (nlist.n_value != 0)
3836 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3851 section_info.
GetSection(nlist.n_sect, nlist.n_value);
3853 N_FUN_addr_to_sym_idx.insert(
3854 std::make_pair(nlist.n_value, sym_idx));
3858 N_FUN_indexes.push_back(sym_idx);
3862 if (!N_FUN_indexes.empty()) {
3867 N_FUN_indexes.pop_back();
3878 N_STSYM_addr_to_sym_idx.insert(
3879 std::make_pair(nlist.n_value, sym_idx));
3880 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3881 if (symbol_name && symbol_name[0]) {
3889 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3920 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
3932 if (symbol_name ==
nullptr) {
3943 N_NSYM_indexes.clear();
3944 N_INCL_indexes.clear();
3945 N_BRAC_indexes.clear();
3946 N_COMM_indexes.clear();
3947 N_FUN_indexes.clear();
3953 const bool N_SO_has_full_path = symbol_name[0] ==
'/';
3954 if (N_SO_has_full_path) {
3955 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
3960 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3965 N_SO_index = sym_idx;
3967 }
else if ((N_SO_index == sym_idx - 1) &&
3968 ((sym_idx - 1) < num_syms)) {
3972 const char *so_path =
3974 if (so_path && so_path[0]) {
3975 std::string full_so_path(so_path);
3976 const size_t double_slash_pos = full_so_path.find(
"//");
3977 if (double_slash_pos != std::string::npos) {
3985 so_dir.
SetFile(&full_so_path[double_slash_pos + 1],
3986 FileSpec::Style::native);
3989 full_so_path.erase(0, double_slash_pos + 1);
3993 if (*full_so_path.rbegin() !=
'/')
3994 full_so_path +=
'/';
3995 full_so_path += symbol_name;
3999 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
4003 N_SO_index = sym_idx;
4023 N_INCL_indexes.push_back(sym_idx);
4032 if (!N_INCL_indexes.empty()) {
4036 N_INCL_indexes.pop_back();
4071 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4080 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4081 N_BRAC_indexes.push_back(sym_idx);
4090 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4091 if (!N_BRAC_indexes.empty()) {
4095 N_BRAC_indexes.pop_back();
4111 N_COMM_indexes.push_back(sym_idx);
4116 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4125 if (!N_COMM_indexes.empty()) {
4129 N_COMM_indexes.pop_back();
4143 uint8_t n_type = N_TYPE & nlist.n_type;
4144 sym[sym_idx].
SetExternal((N_EXT & nlist.n_type) != 0);
4148 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4149 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {
4152 ((reexport_name_cstr[0] ==
'_') ? 1 : 0));
4155 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4156 indirect_symbol_names.insert(
4157 ConstString(symbol_name + ((symbol_name[0] ==
'_') ? 1 : 0)));
4163 if (symbol_name && symbol_name[0]) {
4165 ((symbol_name[0] ==
'_') ? 1 : 0));
4166 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4179 symbol_section = section_info.
GetSection(nlist.n_sect, nlist.n_value);
4181 if (!symbol_section) {
4187 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4190 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4192 switch (section_type) {
4193 case S_CSTRING_LITERALS:
4196 case S_4BYTE_LITERALS:
4199 case S_8BYTE_LITERALS:
4202 case S_LITERAL_POINTERS:
4205 case S_NON_LAZY_SYMBOL_POINTERS:
4208 case S_LAZY_SYMBOL_POINTERS:
4211 case S_SYMBOL_STUBS:
4215 case S_MOD_INIT_FUNC_POINTERS:
4218 case S_MOD_TERM_FUNC_POINTERS:
4225 case S_16BYTE_LITERALS:
4231 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4235 switch (symbol_section->GetType()) {
4257 const char *symbol_sect_name =
4258 symbol_section->GetName().AsCString();
4259 if (symbol_section->IsDescendant(text_section_sp.get())) {
4260 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4261 S_ATTR_SELF_MODIFYING_CODE |
4262 S_ATTR_SOME_INSTRUCTIONS))
4266 }
else if (symbol_section->IsDescendant(data_section_sp.get()) ||
4267 symbol_section->IsDescendant(
4268 data_dirty_section_sp.get()) ||
4269 symbol_section->IsDescendant(
4270 data_const_section_sp.get())) {
4271 if (symbol_sect_name &&
4272 ::strstr(symbol_sect_name,
"__objc") == symbol_sect_name) {
4276 llvm::StringRef symbol_name_ref(symbol_name);
4277 if (symbol_name_ref.starts_with(
"_OBJC_")) {
4278 llvm::StringRef g_objc_v2_prefix_class(
4280 llvm::StringRef g_objc_v2_prefix_metaclass(
4281 "_OBJC_METACLASS_$_");
4282 llvm::StringRef g_objc_v2_prefix_ivar(
4284 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
4285 symbol_name_non_abi_mangled = symbol_name + 1;
4287 symbol_name + g_objc_v2_prefix_class.size();
4289 demangled_is_synthesized =
true;
4290 }
else if (symbol_name_ref.starts_with(
4291 g_objc_v2_prefix_metaclass)) {
4292 symbol_name_non_abi_mangled = symbol_name + 1;
4294 symbol_name + g_objc_v2_prefix_metaclass.size();
4296 demangled_is_synthesized =
true;
4297 }
else if (symbol_name_ref.starts_with(
4298 g_objc_v2_prefix_ivar)) {
4299 symbol_name_non_abi_mangled = symbol_name + 1;
4301 symbol_name + g_objc_v2_prefix_ivar.size();
4303 demangled_is_synthesized =
true;
4307 }
else if (symbol_sect_name &&
4308 ::strstr(symbol_sect_name,
"__gcc_except_tab") ==
4314 }
else if (symbol_sect_name &&
4315 ::strstr(symbol_sect_name,
"__IMPORT") ==
4318 }
else if (symbol_section->IsDescendant(objc_section_sp.get())) {
4320 if (symbol_name && symbol_name[0] ==
'.') {
4321 llvm::StringRef symbol_name_ref(symbol_name);
4322 llvm::StringRef g_objc_v1_prefix_class(
4323 ".objc_class_name_");
4324 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {
4325 symbol_name_non_abi_mangled = symbol_name;
4326 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4328 demangled_is_synthesized =
true;
4339 sym[sym_idx].
Clear();
4343 uint64_t symbol_value = nlist.n_value;
4345 if (symbol_name_non_abi_mangled) {
4351 if (symbol_name && symbol_name[0] ==
'_') {
4362 const char *gsym_name = sym[sym_idx]
4367 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4370 if (symbol_section) {
4371 const addr_t section_file_addr = symbol_section->GetFileAddress();
4372 if (symbol_byte_size == 0 && function_starts_count > 0) {
4373 addr_t symbol_lookup_file_addr = nlist.n_value;
4377 FunctionStarts::Entry *func_start_entry =
4378 function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
4379 if (is_arm && func_start_entry) {
4382 if (func_start_entry->addr != symbol_lookup_file_addr &&
4383 func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
4385 func_start_entry =
nullptr;
4388 if (func_start_entry) {
4389 func_start_entry->data =
true;
4391 addr_t symbol_file_addr = func_start_entry->addr;
4395 const FunctionStarts::Entry *next_func_start_entry =
4396 function_starts.FindNextEntry(func_start_entry);
4397 const addr_t section_end_file_addr =
4398 section_file_addr + symbol_section->GetByteSize();
4399 if (next_func_start_entry) {
4400 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4405 symbol_byte_size = std::min<lldb::addr_t>(
4406 next_symbol_file_addr - symbol_file_addr,
4407 section_end_file_addr - symbol_file_addr);
4409 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4413 symbol_value -= section_file_addr;
4422 std::pair<ValueToSymbolIndexMap::const_iterator,
4423 ValueToSymbolIndexMap::const_iterator>
4425 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4426 if (range.first != range.second) {
4427 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4428 pos != range.second; ++pos) {
4432 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4436 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4437 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4438 if (resolver_addresses.find(nlist.n_value) !=
4439 resolver_addresses.end())
4441 sym[sym_idx].
Clear();
4446 if (resolver_addresses.find(nlist.n_value) !=
4447 resolver_addresses.end())
4457 std::pair<ValueToSymbolIndexMap::const_iterator,
4458 ValueToSymbolIndexMap::const_iterator>
4460 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4461 if (range.first != range.second) {
4462 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4463 pos != range.second; ++pos) {
4467 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4471 sym[pos->second].
SetExternal(sym[sym_idx].IsExternal());
4472 sym[pos->second].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4473 sym[sym_idx].
Clear();
4479 const char *gsym_name = sym[sym_idx]
4484 ConstNameToSymbolIndexMap::const_iterator pos =
4485 N_GSYM_name_to_sym_idx.find(gsym_name);
4486 if (pos != N_GSYM_name_to_sym_idx.end()) {
4487 const uint32_t GSYM_sym_idx = pos->second;
4488 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4494 sym[GSYM_sym_idx].GetAddress().GetFileAddress());
4498 sym[GSYM_sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4499 sym[sym_idx].
Clear();
4507 sym[sym_idx].
SetID(nlist_idx);
4513 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
4515 sym[sym_idx].
SetFlags(nlist.n_type << 16 | nlist.n_desc);
4516 if (nlist.n_desc & N_WEAK_REF)
4519 if (symbol_byte_size > 0)
4522 if (demangled_is_synthesized)
4531 std::vector<struct nlist_64> nlists;
4532 nlists.reserve(symtab_load_command.
nsyms);
4533 for (; nlist_idx < symtab_load_command.
nsyms; ++nlist_idx) {
4535 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))
4536 nlists.push_back(*nlist);
4546 for (
auto &nlist : nlists) {
4547 if (!ParseSymbolLambda(nlist, nlist_idx++,
DebugSymbols))
4553 for (
auto &nlist : nlists) {
4558 for (
const auto &pos : reexport_shlib_needs_fixup) {
4559 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4560 if (undef_pos != undefined_name_to_desc.end()) {
4561 const uint8_t dylib_ordinal =
4562 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4563 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.
GetSize())
4571 int trie_symbol_table_augment_count = 0;
4572 for (
auto &e : external_sym_trie_entries) {
4573 if (!symbols_added.contains(e.entry.address))
4574 trie_symbol_table_augment_count++;
4577 if (num_syms < sym_idx + trie_symbol_table_augment_count) {
4578 num_syms = sym_idx + trie_symbol_table_augment_count;
4579 sym = symtab.
Resize(num_syms);
4581 uint32_t synthetic_sym_id = symtab_load_command.
nsyms;
4584 for (
auto &e : external_sym_trie_entries) {
4585 if (symbols_added.contains(e.entry.address))
4591 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {
4593 const char *symbol_name = e.entry.name.GetCString();
4594 bool demangled_is_synthesized =
false;
4596 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,
4597 data_section_sp, data_dirty_section_sp,
4598 data_const_section_sp, symbol_section);
4601 if (symbol_section) {
4602 sym[sym_idx].
SetID(synthetic_sym_id++);
4604 if (demangled_is_synthesized)
4617 if (function_starts_count > 0) {
4618 uint32_t num_synthetic_function_symbols = 0;
4619 for (i = 0; i < function_starts_count; ++i) {
4620 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))
4621 ++num_synthetic_function_symbols;
4624 if (num_synthetic_function_symbols > 0) {
4625 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4626 num_syms = sym_idx + num_synthetic_function_symbols;
4627 sym = symtab.
Resize(num_syms);
4629 for (i = 0; i < function_starts_count; ++i) {
4630 const FunctionStarts::Entry *func_start_entry =
4631 function_starts.GetEntryAtIndex(i);
4632 if (!symbols_added.contains(func_start_entry->addr)) {
4633 addr_t symbol_file_addr = func_start_entry->addr;
4634 uint32_t symbol_flags = 0;
4635 if (func_start_entry->data)
4638 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4640 uint32_t symbol_byte_size = 0;
4641 if (symbol_section) {
4642 const addr_t section_file_addr = symbol_section->GetFileAddress();
4643 const FunctionStarts::Entry *next_func_start_entry =
4644 function_starts.FindNextEntry(func_start_entry);
4645 const addr_t section_end_file_addr =
4646 section_file_addr + symbol_section->GetByteSize();
4647 if (next_func_start_entry) {
4648 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4651 symbol_byte_size = std::min<lldb::addr_t>(
4652 next_symbol_file_addr - symbol_file_addr,
4653 section_end_file_addr - symbol_file_addr);
4655 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4657 sym[sym_idx].
SetID(synthetic_sym_id++);
4667 sym[sym_idx].
SetFlags(symbol_flags);
4668 if (symbol_byte_size)
4680 if (sym_idx < num_syms) {
4682 sym = symtab.
Resize(num_syms);
4687 if (indirect_symbol_index_data.GetByteSize()) {
4688 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4689 m_nlist_idx_to_sym_idx.end();
4696 if (symbol_stub_byte_size == 0)
4699 const uint32_t num_symbol_stubs =
4702 if (num_symbol_stubs == 0)
4705 const uint32_t symbol_stub_index_offset =
4707 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
4708 const uint32_t symbol_stub_index =
4709 symbol_stub_index_offset + stub_idx;
4712 (stub_idx * symbol_stub_byte_size);
4714 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4715 symbol_stub_offset, 4)) {
4716 const uint32_t stub_sym_id =
4717 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4718 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4721 NListIndexToSymbolIndexMap::const_iterator index_pos =
4722 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4723 Symbol *stub_symbol =
nullptr;
4724 if (index_pos != end_index_pos) {
4735 Address so_addr(symbol_stub_addr, section_list);
4742 if (resolver_addresses.find(symbol_stub_addr) ==
4743 resolver_addresses.end())
4753 if (sym_idx >= num_syms) {
4754 sym = symtab.
Resize(++num_syms);
4755 stub_symbol =
nullptr;
4757 sym[sym_idx].
SetID(synthetic_sym_id++);
4758 sym[sym_idx].
GetMangled() = stub_symbol_mangled_name;
4759 if (resolver_addresses.find(symbol_stub_addr) ==
4760 resolver_addresses.end())
4772 log->
Warning(
"symbol stub referencing symbol table symbol "
4773 "%u that isn't in our minimal symbol table, "
4784 if (!reexport_trie_entries.empty()) {
4785 for (
const auto &e : reexport_trie_entries) {
4786 if (e.entry.import_name) {
4789 if (indirect_symbol_names.find(e.entry.name) ==
4790 indirect_symbol_names.end()) {
4792 if (sym_idx >= num_syms)
4793 sym = symtab.
Resize(++num_syms);
4794 sym[sym_idx].
SetID(synthetic_sym_id++);
4799 if (e.entry.other > 0 && e.entry.other <= dylib_files.
GetSize()) {
4813 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4814 s->
Printf(
"%p: ",
static_cast<void *
>(
this));
4821 *s <<
", file = '" <<
m_file;
4825 base_spec, all_specs);
4826 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
4851 llvm::MachO::uuid_command load_cmd;
4854 for (i = 0; i < header.ncmds; ++i) {
4856 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
4859 if (load_cmd.cmd == LC_UUID) {
4860 const uint8_t *uuid_bytes = data.
PeekData(offset, 16);
4866 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4867 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4868 0xbb, 0x14, 0xf0, 0x0d};
4870 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4873 return UUID(uuid_bytes, 16);
4877 offset = cmd_offset + load_cmd.cmdsize;
4884 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4885 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4886 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4887 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4888 case llvm::MachO::LC_VERSION_MIN_TVOS:
4889 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4890 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4891 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4893 llvm_unreachable(
"unexpected LC_VERSION load command");
4899 llvm::StringRef os_type;
4900 llvm::StringRef environment;
4901 OSEnv(uint32_t cmd) {
4903 case llvm::MachO::PLATFORM_MACOS:
4904 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
4906 case llvm::MachO::PLATFORM_IOS:
4907 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4909 case llvm::MachO::PLATFORM_TVOS:
4910 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4912 case llvm::MachO::PLATFORM_WATCHOS:
4913 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4915 case llvm::MachO::PLATFORM_BRIDGEOS:
4916 os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
4918 case llvm::MachO::PLATFORM_DRIVERKIT:
4919 os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);
4921 case llvm::MachO::PLATFORM_MACCATALYST:
4922 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4923 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);
4925 case llvm::MachO::PLATFORM_IOSSIMULATOR:
4926 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
4928 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4930 case llvm::MachO::PLATFORM_TVOSSIMULATOR:
4931 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
4933 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4935 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:
4936 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
4938 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4940 case llvm::MachO::PLATFORM_XROS:
4941 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4943 case llvm::MachO::PLATFORM_XROS_SIMULATOR:
4944 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
4946 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
4949 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
4950 LLDB_LOGF(log,
"unsupported platform in LC_BUILD_VERSION");
4957 uint32_t major_version, minor_version, patch_version;
4958 MinOS(uint32_t version)
4959 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),
4960 patch_version(version & 0xffu) {}
4971 if (!base_arch.IsValid())
4974 bool found_any =
false;
4975 auto add_triple = [&](
const llvm::Triple &triple) {
4976 auto spec = base_spec;
4978 if (spec.GetArchitecture().IsValid()) {
4986 llvm::Triple base_triple = base_arch.GetTriple();
4987 base_triple.setOS(llvm::Triple::UnknownOS);
4988 base_triple.setOSName(llvm::StringRef());
4990 if (header.filetype == MH_PRELOAD) {
4991 if (header.cputype == CPU_TYPE_ARM) {
4997 base_triple.setVendor(llvm::Triple::Apple);
5002 base_triple.setVendor(llvm::Triple::UnknownVendor);
5003 base_triple.setVendorName(llvm::StringRef());
5005 return add_triple(base_triple);
5008 llvm::MachO::load_command load_cmd;
5013 for (uint32_t i = 0; i < header.ncmds; ++i) {
5015 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
5018 llvm::MachO::version_min_command version_min;
5019 switch (load_cmd.cmd) {
5020 case llvm::MachO::LC_VERSION_MIN_MACOSX:
5021 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
5022 case llvm::MachO::LC_VERSION_MIN_TVOS:
5023 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
5024 if (load_cmd.cmdsize !=
sizeof(version_min))
5029 MinOS min_os(version_min.version);
5030 llvm::SmallString<32> os_name;
5031 llvm::raw_svector_ostream os(os_name);
5032 os <<
GetOSName(load_cmd.cmd) << min_os.major_version <<
'.'
5033 << min_os.minor_version <<
'.' << min_os.patch_version;
5035 auto triple = base_triple;
5036 triple.setOSName(os.str());
5039 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&
5040 (base_triple.getArch() == llvm::Triple::x86_64 ||
5041 base_triple.getArch() == llvm::Triple::x86)) {
5048 triple.setEnvironment(llvm::Triple::Simulator);
5057 offset = cmd_offset + load_cmd.cmdsize;
5063 for (uint32_t i = 0; i < header.ncmds; ++i) {
5065 if (data.
GetU32(&offset, &load_cmd, 2) ==
nullptr)
5069 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
5070 llvm::MachO::build_version_command build_version;
5071 if (load_cmd.cmdsize <
sizeof(build_version)) {
5075 if (data.
ExtractBytes(cmd_offset,
sizeof(build_version),
5078 MinOS min_os(build_version.minos);
5079 OSEnv os_env(build_version.platform);
5080 llvm::SmallString<16> os_name;
5081 llvm::raw_svector_ostream os(os_name);
5082 os << os_env.os_type << min_os.major_version <<
'.'
5083 << min_os.minor_version <<
'.' << min_os.patch_version;
5084 auto triple = base_triple;
5085 triple.setOSName(os.str());
5087 if (!os_env.environment.empty())
5088 triple.setEnvironmentName(os_env.environment);
5092 offset = cmd_offset + load_cmd.cmdsize;
5096 add_triple(base_triple);
5101 ModuleSP module_sp,
const llvm::MachO::mach_header &header,
5106 base_spec, all_specs);
5111 const ArchSpec &module_arch = module_sp->GetArchitecture();
5112 for (
unsigned i = 0, e = all_specs.
GetSize(); i != e; ++i) {
5129 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5142 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5143 llvm::MachO::load_command load_cmd;
5145 std::vector<std::string> rpath_paths;
5146 std::vector<std::string> rpath_relative_paths;
5147 std::vector<std::string> at_exec_relative_paths;
5149 for (i = 0; i <
m_header.ncmds; ++i) {
5150 const uint32_t cmd_offset = offset;
5154 switch (load_cmd.cmd) {
5157 case LC_LOAD_WEAK_DYLIB:
5158 case LC_REEXPORT_DYLIB:
5159 case LC_LOAD_DYLINKER:
5161 case LC_LOAD_UPWARD_DYLIB: {
5162 uint32_t name_offset = cmd_offset +
m_data.
GetU32(&offset);
5167 bool is_delayed_init =
false;
5169 if (use_command_marker == 0x1a741800 ) {
5178 is_delayed_init =
true;
5181 if (path && !is_delayed_init) {
5182 if (load_cmd.cmd == LC_RPATH)
5183 rpath_paths.push_back(path);
5185 if (path[0] ==
'@') {
5186 if (strncmp(path,
"@rpath", strlen(
"@rpath")) == 0)
5187 rpath_relative_paths.push_back(path + strlen(
"@rpath"));
5188 else if (strncmp(path,
"@executable_path",
5189 strlen(
"@executable_path")) == 0)
5190 at_exec_relative_paths.push_back(path +
5191 strlen(
"@executable_path"));
5204 offset = cmd_offset + load_cmd.cmdsize;
5210 if (!rpath_paths.empty()) {
5212 const std::string this_directory =
5214 for (
auto &rpath : rpath_paths) {
5216 rpath = this_directory + rpath.substr(
g_loader_path.size());
5221 for (
const auto &rpath_relative_path : rpath_relative_paths) {
5222 for (
const auto &rpath : rpath_paths) {
5223 std::string path = rpath;
5224 path += rpath_relative_path;
5244 for (
const auto &at_exec_relative_path : at_exec_relative_paths) {
5291 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5292 llvm::MachO::load_command load_cmd;
5298 for (i = 0; i <
m_header.ncmds; ++i) {
5303 switch (load_cmd.cmd) {
5306 while (offset < cmd_offset + load_cmd.cmdsize) {
5315 case llvm::MachO::CPU_TYPE_ARM:
5326 case llvm::MachO::CPU_TYPE_ARM64:
5327 case llvm::MachO::CPU_TYPE_ARM64_32:
5336 case llvm::MachO::CPU_TYPE_I386:
5346 case llvm::MachO::CPU_TYPE_X86_64:
5363 offset += count * 4;
5370 if (text_segment_sp) {
5372 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5383 offset = cmd_offset + load_cmd.cmdsize;
5389 ConstString(
"_dyld_start"), SymbolType::eSymbolTypeCode,
5413 module_sp->FindSymbolsWithNameAndType(
ConstString(
"start"),
5432 if (text_segment_sp) {
5443 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5448 llvm::MachO::thread_command thread_cmd;
5449 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5450 const uint32_t cmd_offset = offset;
5454 if (thread_cmd.cmd == LC_THREAD) {
5459 offset = cmd_offset + thread_cmd.cmdsize;
5466std::vector<std::tuple<offset_t, offset_t>>
5468 std::vector<std::tuple<offset_t, offset_t>> results;
5471 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5474 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5475 const uint32_t cmd_offset = offset;
5476 llvm::MachO::load_command lc = {};
5479 if (lc.cmd == LC_NOTE) {
5480 char data_owner[17];
5482 data_owner[16] =
'\0';
5485 if (name == data_owner) {
5488 results.push_back({payload_offset, payload_size});
5491 offset = cmd_offset + lc.cmdsize;
5499 GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));
5502 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5505 for (
auto lc_note : lc_notes) {
5506 offset_t payload_offset = std::get<0>(lc_note);
5507 offset_t payload_size = std::get<1>(lc_note);
5509 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr) {
5511 uint32_t strsize = payload_size -
sizeof(uint32_t);
5512 std::string result(strsize,
'\0');
5514 LLDB_LOGF(log,
"LC_NOTE 'kern ver str' found with text '%s'",
5524 for (uint32_t i = 0; i <
m_header.ncmds; ++i) {
5525 const uint32_t cmd_offset = offset;
5526 llvm::MachO::ident_command ident_command;
5527 if (
m_data.
GetU32(&offset, &ident_command, 2) ==
nullptr)
5529 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
5530 std::string result(ident_command.cmdsize,
'\0');
5531 if (
m_data.
CopyData(offset, ident_command.cmdsize, result.data()) ==
5532 ident_command.cmdsize) {
5533 LLDB_LOGF(log,
"LC_IDENT found with text '%s'", result.c_str());
5537 offset = cmd_offset + ident_command.cmdsize;
5549 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5551 for (
auto lc_note : lc_notes) {
5552 offset_t payload_offset = std::get<0>(lc_note);
5554 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr) {
5559 "LC_NOTE 'addrable bits' v3 found, value %d "
5567 if (lo_addr_bits == hi_addr_bits)
5571 LLDB_LOGF(log,
"LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
5572 lo_addr_bits, hi_addr_bits);
5577 return addressable_bits;
5581 bool &value_is_offset,
5585 GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));
5587 value_is_offset =
false;
5589 uint32_t log2_pagesize = 0;
5590 uint32_t platform = 0;
5593 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5596 for (
auto lc_note : lc_notes) {
5597 offset_t payload_offset = std::get<0>(lc_note);
5632 if (
m_data.
GetU32(&payload_offset, &version, 1) !=
nullptr &&
5634 uint32_t binspec_type = 0;
5636 memset(raw_uuid, 0,
sizeof(
uuid_t));
5643 if (version > 1 && !
m_data.
GetU64(&payload_offset, &slide, 1))
5647 value_is_offset =
true;
5654 const char *typestr =
"unrecognized type";
5655 switch (binspec_type) {
5662 typestr =
"xnu kernel";
5666 typestr =
"userland dyld";
5670 typestr =
"standalone";
5674 "LC_NOTE 'main bin spec' found, version %d type %d "
5675 "(%s), value 0x%" PRIx64
" value-is-slide==%s uuid %s",
5676 version, type, typestr, value,
5677 value_is_offset ?
"true" :
"false",
5679 if (!
m_data.
GetU32(&payload_offset, &log2_pagesize, 1))
5681 if (version > 1 && !
m_data.
GetU32(&payload_offset, &platform, 1))
5692 std::vector<lldb::tid_t> &tids) {
5696 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5698 Log *log(
GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));
5700 for (
auto lc_note : lc_notes) {
5701 offset_t payload_offset = std::get<0>(lc_note);
5702 offset_t strsize = std::get<1>(lc_note);
5703 std::string buf(strsize,
'\0');
5704 if (
m_data.
CopyData(payload_offset, strsize, buf.data()) != strsize) {
5706 "Unable to read %" PRIu64
5707 " bytes of 'process metadata' LC_NOTE JSON contents",
5711 while (buf.back() ==
'\0')
5712 buf.resize(buf.size() - 1);
5716 LLDB_LOGF(log,
"Unable to read 'process metadata' LC_NOTE, did not "
5717 "get a dictionary.");
5723 "'process metadata' LC_NOTE does not have a 'threads' key");
5727 LLDB_LOGF(log,
"Unable to read 'process metadata' LC_NOTE, number of "
5728 "threads does not match number of LC_THREADS.");
5731 const size_t num_threads = threads->
GetSize();
5732 for (
size_t i = 0; i < num_threads; i++) {
5733 std::optional<StructuredData::Dictionary *> maybe_thread =
5735 if (!maybe_thread) {
5737 "Unable to read 'process metadata' LC_NOTE, threads "
5738 "array does not have a dictionary at index %zu.",
5747 tids.push_back(tid);
5752 logmsg.
Printf(
"LC_NOTE 'process metadata' found: ");
5753 dict->
Dump(logmsg,
false);
5769 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5775 if (thread_context_file_range) {
5781 case llvm::MachO::CPU_TYPE_ARM64:
5782 case llvm::MachO::CPU_TYPE_ARM64_32:
5784 std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);
5787 case llvm::MachO::CPU_TYPE_ARM:
5789 std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);
5792 case llvm::MachO::CPU_TYPE_I386:
5794 std::make_shared<RegisterContextDarwin_i386_Mach>(thread, data);
5797 case llvm::MachO::CPU_TYPE_X86_64:
5799 std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
5842 case MH_KEXT_BUNDLE:
5870 if (
m_header.flags & MH_DYLDLINK) {
5898 case MH_KEXT_BUNDLE:
5909 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5910 llvm::MachO::dylib_command load_cmd;
5912 uint32_t version_cmd = 0;
5913 uint64_t version = 0;
5915 for (i = 0; i <
m_header.ncmds; ++i) {
5920 if (load_cmd.cmd == LC_ID_DYLIB) {
5921 if (version_cmd == 0) {
5922 version_cmd = load_cmd.cmd;
5923 if (
m_data.
GetU32(&offset, &load_cmd.dylib, 4) ==
nullptr)
5925 version = load_cmd.dylib.current_version;
5930 offset = cmd_offset + load_cmd.cmdsize;
5933 if (version_cmd == LC_ID_DYLIB) {
5934 unsigned major = (version & 0xFFFF0000ull) >> 16;
5935 unsigned minor = (version & 0x0000FF00ull) >> 8;
5936 unsigned subminor = (version & 0x000000FFull);
5937 return llvm::VersionTuple(major, minor, subminor);
5940 return llvm::VersionTuple();
5947 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5964 private_shared_cache);
5966 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
5969 "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64,
5992#if defined(__APPLE__)
5993 uint8_t *(*dyld_get_all_image_infos)(void);
5994 dyld_get_all_image_infos =
5995 (uint8_t * (*)()) dlsym(RTLD_DEFAULT,
"_dyld_get_all_image_infos");
5996 if (dyld_get_all_image_infos) {
5997 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5998 if (dyld_all_image_infos_address) {
5999 uint32_t *version = (uint32_t *)
6000 dyld_all_image_infos_address;
6001 if (*version >= 13) {
6002 uuid_t *sharedCacheUUID_address = 0;
6003 int wordsize =
sizeof(uint8_t *);
6004 if (wordsize == 8) {
6005 sharedCacheUUID_address =
6006 (
uuid_t *)((uint8_t *)dyld_all_image_infos_address +
6011 *)((uint8_t *)dyld_all_image_infos_address +
6014 sharedCacheUUID_address =
6015 (
uuid_t *)((uint8_t *)dyld_all_image_infos_address +
6017 if (*version >= 15) {
6021 *)((uint8_t *)dyld_all_image_infos_address +
6025 uuid =
UUID(sharedCacheUUID_address,
sizeof(
uuid_t));
6031 unsigned int task, uint64_t timestamp,
6032 unsigned int *kernelError);
6033 void (*dyld_process_info_get_cache)(
void *info,
void *cacheInfo);
6036 dyld_process_info_create = (
void *(*)(
unsigned int , uint64_t,
6038 dlsym(RTLD_DEFAULT,
"_dyld_process_info_create");
6039 dyld_process_info_get_cache = (void (*)(
void *,
void *))dlsym(
6040 RTLD_DEFAULT,
"_dyld_process_info_get_cache");
6041 dyld_process_info_release =
6042 (void (*)(
void *))dlsym(RTLD_DEFAULT,
"_dyld_process_info_release");
6044 if (dyld_process_info_create && dyld_process_info_get_cache) {
6045 unsigned int kern_ret;
6051 dyld_process_info_get_cache(process_info, &sc_info);
6056 dyld_process_info_release(process_info);
6060 Log *log(
GetLog(LLDBLog::Symbols | LLDBLog::Process));
6063 "lldb's in-memory shared cache has a UUID of %s base address of "
6072 for (
size_t i = 0; i < ncmds; i++) {
6074 llvm::MachO::load_command lc = {};
6075 if (data.
GetU32(&offset, &lc.cmd, 2) ==
nullptr)
6078 uint32_t version = 0;
6079 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
6080 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
6081 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
6082 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
6090 version = data.
GetU32(&offset);
6091 }
else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
6101 offset +=
sizeof(uint32_t);
6102 version = data.
GetU32(&offset);
6106 const uint32_t xxxx = version >> 16;
6107 const uint32_t yy = (version >> 8) & 0xffu;
6108 const uint32_t zz = version & 0xffu;
6110 return llvm::VersionTuple(xxxx, yy, zz);
6112 offset = load_cmd_offset + lc.cmdsize;
6114 return llvm::VersionTuple();
6132 return m_header.filetype == llvm::MachO::MH_DYLINKER;
6138 return m_header.filetype == llvm::MachO::MH_DSYM;
6164 return text_segment_sp.get();
6166 const size_t num_sections = section_list->
GetSize();
6167 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6195 const bool is_memory_image = (bool)
m_process_wp.lock();
6207 if (module_sp && header_section && section &&
6211 return section->
GetFileAddress() - file_addr + header_load_address;
6217 bool value_is_offset) {
6218 Log *log(
GetLog(LLDBLog::DynamicLoader));
6227 size_t num_loaded_sections = 0;
6228 const size_t num_sections = section_list->
GetSize();
6232 const bool warn_multiple =
true;
6236 logmsg <<
"ObjectFileMachO::SetLoadAddress ";
6244 if (value_is_offset) {
6246 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6252 "ObjectFileMachO::SetLoadAddress segment '%s' load addr is "
6254 section_sp->GetName().AsCString(),
6255 section_sp->GetFileAddress() + value);
6257 section_sp, section_sp->GetFileAddress() + value,
6259 ++num_loaded_sections;
6267 if (mach_header_section) {
6268 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
6273 value, mach_header_section, section_sp.get());
6276 "ObjectFileMachO::SetLoadAddress segment '%s' load addr is "
6278 section_sp->GetName().AsCString(), section_load_addr);
6280 section_sp, section_load_addr, warn_multiple))
6281 ++num_loaded_sections;
6286 return num_loaded_sections > 0;
6371 Target &target = process_sp->GetTarget();
6377 if (options.
GetStyle() == SaveCoreStyle::eSaveCoreStackOnly)
6380 std::set<std::string> executing_uuids;
6381 std::vector<ThreadSP> thread_list =
6382 process_sp->CalculateCoreFileThreadList(options);
6383 for (
const ThreadSP &thread_sp : thread_list) {
6384 uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
6385 for (uint32_t j = 0; j < stack_frame_count; j++) {
6386 StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
6387 Address pc = stack_frame_sp->GetFrameCodeAddress();
6390 UUID uuid = module_sp->GetUUID();
6398 size_t modules_count = modules.
GetSize();
6416 std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;
6417 for (
size_t i = 0; i < modules_count; i++) {
6421 size_t sections_count = sections->
GetSize();
6422 std::vector<segment_vmaddr> segment_vmaddrs;
6423 for (
size_t j = 0; j < sections_count; j++) {
6425 if (!section->GetParent().get()) {
6426 addr_t vmaddr = section->GetLoadBaseAddress(&target);
6439 seg_vmaddr.
vmaddr = vmaddr;
6441 segment_vmaddrs.push_back(seg_vmaddr);
6444 modules_segment_vmaddrs.push_back(segment_vmaddrs);
6447 offset_t size_of_vmaddr_structs = 0;
6448 for (
size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6449 size_of_vmaddr_structs +=
6453 offset_t size_of_filepath_cstrings = 0;
6454 for (
size_t i = 0; i < modules_count; i++) {
6456 size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;
6465 start_of_entries +
sizeof(
image_entry) * modules_count;
6466 offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;
6468 offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;
6474 offset_t current_string_offset = start_of_filenames;
6475 offset_t current_segaddrs_offset = start_of_seg_vmaddrs;
6476 std::vector<struct image_entry> image_entries;
6477 for (
size_t i = 0; i < modules_count; i++) {
6481 memcpy(&ent.
uuid, module_sp->GetUUID().GetBytes().data(),
sizeof(ent.
uuid));
6482 if (modules_segment_vmaddrs[i].size() > 0) {
6487 ObjectFile *objfile = module_sp->GetObjectFile();
6501 if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=
6502 executing_uuids.end())
6503 all_image_infos_payload.
PutHex32(1);
6505 all_image_infos_payload.
PutHex32(0);
6508 current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;
6513 for (
size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
6514 if (modules_segment_vmaddrs[i].size() == 0)
6517 all_image_infos_payload.
PutRawBytes(segvm.segname,
sizeof(segvm.segname));
6518 all_image_infos_payload.
PutHex64(segvm.vmaddr);
6519 all_image_infos_payload.
PutHex64(segvm.unused);
6523 for (
size_t i = 0; i < modules_count; i++) {
6525 std::string filepath = module_sp->GetFileSpec().GetPath();
6526 all_image_infos_payload.
PutRawBytes(filepath.data(), filepath.size() + 1);
6529 return final_file_offset;
6549 if (options.
GetStyle() == SaveCoreStyle::eSaveCoreUnspecified)
6552 Target &target = process_sp->GetTarget();
6554 const llvm::Triple &target_triple = target_arch.
GetTriple();
6555 if (target_triple.getVendor() == llvm::Triple::Apple &&
6556 (target_triple.getOS() == llvm::Triple::MacOSX ||
6557 target_triple.getOS() == llvm::Triple::IOS ||
6558 target_triple.getOS() == llvm::Triple::WatchOS ||
6559 target_triple.getOS() == llvm::Triple::TvOS ||
6560 target_triple.getOS() == llvm::Triple::XROS)) {
6563 bool make_core =
false;
6565 case llvm::Triple::aarch64:
6566 case llvm::Triple::aarch64_32:
6567 case llvm::Triple::arm:
6568 case llvm::Triple::thumb:
6569 case llvm::Triple::x86:
6570 case llvm::Triple::x86_64:
6575 "unsupported core architecture: %s", target_triple.str().c_str());
6581 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
6582 if (
error.Success()) {
6585 std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6586 for (
const auto &core_range_info : core_ranges) {
6588 const auto &core_range = core_range_info.data;
6589 uint32_t cmd_type = LC_SEGMENT_64;
6590 uint32_t segment_size =
sizeof(llvm::MachO::segment_command_64);
6591 if (addr_byte_size == 4) {
6592 cmd_type = LC_SEGMENT;
6593 segment_size =
sizeof(llvm::MachO::segment_command);
6597 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
6599 uint32_t vm_prot = 0;
6600 if (core_range.lldb_permissions & ePermissionsReadable)
6601 vm_prot |= VM_PROT_READ;
6602 if (core_range.lldb_permissions & ePermissionsWritable)
6603 vm_prot |= VM_PROT_WRITE;
6604 if (core_range.lldb_permissions & ePermissionsExecutable)
6605 vm_prot |= VM_PROT_EXECUTE;
6606 const addr_t vm_addr = core_range.range.start();
6607 const addr_t vm_size = core_range.range.size();
6608 llvm::MachO::segment_command_64 segment = {
6620 segment_load_commands.push_back(segment);
6625 llvm::MachO::mach_header_64 mach_header;
6626 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6629 mach_header.filetype = MH_CORE;
6630 mach_header.ncmds = segment_load_commands.size();
6631 mach_header.flags = 0;
6632 mach_header.reserved = 0;
6633 ThreadList &thread_list = process_sp->GetThreadList();
6634 const uint32_t num_threads = thread_list.
GetSize();
6640 std::vector<StreamString> LC_THREAD_datas(num_threads);
6641 for (
auto &LC_THREAD_data : LC_THREAD_datas) {
6643 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6644 LC_THREAD_data.SetByteOrder(byte_order);
6646 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6649 switch (mach_header.cputype) {
6650 case llvm::MachO::CPU_TYPE_ARM64:
6651 case llvm::MachO::CPU_TYPE_ARM64_32:
6653 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6656 case llvm::MachO::CPU_TYPE_ARM:
6658 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6661 case llvm::MachO::CPU_TYPE_I386:
6663 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6666 case llvm::MachO::CPU_TYPE_X86_64:
6668 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6675 if (addr_byte_size == 8) {
6676 mach_header.sizeofcmds = segment_load_commands.size() *
6677 sizeof(llvm::MachO::segment_command_64);
6679 mach_header.sizeofcmds = segment_load_commands.size() *
6680 sizeof(llvm::MachO::segment_command);
6684 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6685 ++mach_header.ncmds;
6686 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6691 uint64_t address_mask = process_sp->GetCodeAddressMask();
6694 mach_header.ncmds++;
6695 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6699 mach_header.ncmds++;
6700 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6703 mach_header.ncmds++;
6704 mach_header.sizeofcmds +=
sizeof(llvm::MachO::note_command);
6707 buffer.
PutHex32(mach_header.magic);
6708 buffer.
PutHex32(mach_header.cputype);
6709 buffer.
PutHex32(mach_header.cpusubtype);
6710 buffer.
PutHex32(mach_header.filetype);
6711 buffer.
PutHex32(mach_header.ncmds);
6712 buffer.
PutHex32(mach_header.sizeofcmds);
6713 buffer.
PutHex32(mach_header.flags);
6714 if (addr_byte_size == 8) {
6715 buffer.
PutHex32(mach_header.reserved);
6720 addr_t file_offset = buffer.
GetSize() + mach_header.sizeofcmds;
6722 file_offset = llvm::alignTo(file_offset, 16);
6723 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
6727 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
6729 addrable_bits_lcnote_up->name =
"addrable bits";
6730 addrable_bits_lcnote_up->payload_file_offset = file_offset;
6731 int bits = std::bitset<64>(~address_mask).count();
6732 addrable_bits_lcnote_up->payload.PutHex32(4);
6733 addrable_bits_lcnote_up->payload.PutHex32(
6735 addrable_bits_lcnote_up->payload.PutHex32(
6737 addrable_bits_lcnote_up->payload.PutHex32(0);
6739 file_offset += addrable_bits_lcnote_up->payload.GetSize();
6741 lc_notes.push_back(std::move(addrable_bits_lcnote_up));
6745 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(
6747 thread_extrainfo_lcnote_up->name =
"process metadata";
6748 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;
6751 std::make_shared<StructuredData::Dictionary>());
6753 std::make_shared<StructuredData::Array>());
6755 process_sp->CalculateCoreFileThreadList(options)) {
6757 std::make_shared<StructuredData::Dictionary>());
6758 thread->AddIntegerItem(
"thread_id", thread_sp->GetID());
6759 threads->AddItem(thread);
6761 dict->AddItem(
"threads", threads);
6763 dict->Dump(strm,
false);
6767 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();
6768 file_offset = llvm::alignTo(file_offset, 16);
6769 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));
6772 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
6774 all_image_infos_lcnote_up->name =
"all image infos";
6775 all_image_infos_lcnote_up->payload_file_offset = file_offset;
6777 process_sp, file_offset, all_image_infos_lcnote_up->payload,
6779 lc_notes.push_back(std::move(all_image_infos_lcnote_up));
6782 for (
auto &lcnote : lc_notes) {
6785 buffer.
PutHex32(
sizeof(llvm::MachO::note_command));
6787 memset(namebuf, 0,
sizeof(namebuf));
6793 strncpy(namebuf, lcnote->name.c_str(),
sizeof(namebuf));
6795 buffer.
PutHex64(lcnote->payload_file_offset);
6796 buffer.
PutHex64(lcnote->payload.GetSize());
6800 file_offset = llvm::alignTo(file_offset, 4096);
6802 for (
auto &segment : segment_load_commands) {
6803 segment.fileoff = file_offset;
6804 file_offset += segment.filesize;
6808 for (
const auto &LC_THREAD_data : LC_THREAD_datas) {
6809 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6811 buffer.
PutHex32(8 + LC_THREAD_data_size);
6812 buffer.
Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);
6816 for (
const auto &segment : segment_load_commands) {
6819 buffer.
PutRawBytes(segment.segname,
sizeof(segment.segname));
6820 if (addr_byte_size == 8) {
6826 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmaddr));
6827 buffer.
PutHex32(
static_cast<uint32_t
>(segment.vmsize));
6828 buffer.
PutHex32(
static_cast<uint32_t
>(segment.fileoff));
6829 buffer.
PutHex32(
static_cast<uint32_t
>(segment.filesize));
6837 std::string core_file_path(outfile.
GetPath());
6845 uint8_t bytes[0x1000];
6847 size_t bytes_written = buffer.
GetString().size();
6849 core_file.get()->Write(buffer.
GetString().data(), bytes_written);
6850 if (
error.Success()) {
6852 for (
auto &lcnote : lc_notes) {
6853 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
6856 "Unable to seek to corefile pos "
6857 "to write '%s' LC_NOTE payload",
6858 lcnote->name.c_str());
6861 bytes_written = lcnote->payload.GetSize();
6862 error = core_file.get()->Write(lcnote->payload.GetData(),
6864 if (!
error.Success())
6869 for (
const auto &segment : segment_load_commands) {
6870 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
6872 "unable to seek to offset 0x%" PRIx64
" in '%s'",
6873 segment.fileoff, core_file_path.c_str());
6879 " bytes of data for memory region at 0x%" PRIx64
"\n",
6880 segment.vmsize, segment.vmaddr);
6881 addr_t bytes_left = segment.vmsize;
6882 addr_t addr = segment.vmaddr;
6884 while (bytes_left > 0 &&
error.Success()) {
6885 const size_t bytes_to_read =
6886 bytes_left >
sizeof(bytes) ?
sizeof(bytes) : bytes_left;
6891 const size_t bytes_read = process_sp->ReadMemoryFromInferior(
6894 if (bytes_read == bytes_to_read) {
6895 size_t bytes_written = bytes_read;
6896 error = core_file.get()->Write(bytes, bytes_written);
6897 bytes_left -= bytes_read;
6902 memset(bytes, 0, bytes_to_read);
6903 size_t bytes_written = bytes_to_read;
6904 error = core_file.get()->Write(bytes, bytes_written);
6905 bytes_left -= bytes_to_read;
6906 addr += bytes_to_read;
6923 Log *log(
GetLog(LLDBLog::Object | LLDBLog::Symbols | LLDBLog::Process |
6924 LLDBLog::DynamicLoader));
6927 for (
auto lc_note : lc_notes) {
6928 offset_t payload_offset = std::get<0>(lc_note);
6935 uint64_t entries_fileoff =
m_data.
GetU64(&payload_offset);
6940 LLDB_LOGF(log,
"LC_NOTE 'all image infos' found version %d with %d images",
6942 payload_offset = entries_fileoff;
6943 for (uint32_t i = 0; i < imgcount; i++) {
6949 uint64_t load_address =
m_data.
GetU64(&payload_offset);
6951 uint32_t segment_count =
m_data.
GetU32(&payload_offset);
6952 uint32_t currently_executing =
m_data.
GetU32(&payload_offset);
6958 image_entry.currently_executing = currently_executing;
6960 offset_t seg_vmaddrs_offset = seg_addrs_offset;
6961 for (uint32_t j = 0; j < segment_count; j++) {
6965 seg_vmaddrs_offset += 16;
6967 seg_vmaddrs_offset += 8;
6969 std::tuple<ConstString, addr_t> new_seg{
ConstString(segname), vmaddr};
6970 image_entry.segment_load_addresses.push_back(new_seg);
6972 LLDB_LOGF(log,
" image entry: %s %s 0x%" PRIx64
" %s",
6976 image_entry.currently_executing ?
"currently executing"
6977 :
"not currently executing");
6983 for (
auto lc_note : lc_notes) {
6984 offset_t payload_offset = std::get<0>(lc_note);
6990 uint64_t load_address =
m_data.
GetU64(&payload_offset);
7002 "LC_NOTE 'load binary' found, filename %s uuid %s load "
7003 "address 0x%" PRIx64
" slide 0x%" PRIx64,
7007 :
"00000000-0000-0000-0000-000000000000",
7008 load_address, slide);
7017 Log *log =
GetLog(LLDBLog::Object | LLDBLog::DynamicLoader);
7020 bool found_platform_binary =
false;
7023 ModuleSP module_sp, local_filesystem_module_sp;
7035 "ObjectFileMachO::%s binary at 0x%" PRIx64
7036 " is a platform binary, has been handled by a Platform plugin.",
7054 const bool notify =
false;
7057 const bool allow_memory_image_last_resort =
7060 &process, image.
filename, image.
uuid, value, value_is_offset,
7062 allow_memory_image_last_resort);
7068 added_modules.
Append(module_sp,
false );
7074 log->
Printf(
"ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7075 "UUID %s with section load addresses",
7076 module_sp->GetFileSpec().GetPath().c_str(),
7080 SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList();
7086 sect_sp, std::get<1>(name_vmaddr_tuple));
7093 log->
Printf(
"ObjectFileMachO::LoadCoreFileImages adding binary '%s' "
7094 "UUID %s with %s 0x%" PRIx64,
7095 module_sp->GetFileSpec().GetPath().c_str(),
7097 value_is_offset ?
"slide" :
"load address", value);
7100 module_sp->SetLoadAddress(process.
GetTarget(), value, value_is_offset,
7105 if (added_modules.
GetSize() > 0) {
7112 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.
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
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
@ 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
@ eSectionTypeLLDBFormatters
@ eSectionTypeDWARFDebugNames
DWARF v5 .debug_names.
@ eSectionTypeDWARFDebugRngLists
DWARF v5 .debug_rnglists.
@ eSectionTypeDWARFDebugStrOffsetsDwo
@ eSectionTypeDWARFDebugMacro
@ eSectionTypeDWARFAppleTypes
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugTypesDwo
@ eSectionTypeDWARFDebugRanges
@ eSectionTypeDWARFDebugRngListsDwo
@ eSectionTypeLLDBTypeSummaries
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugPubTypes
@ eSectionTypeDataObjCMessageRefs
Pointer to function pointer + selector.
@ eSectionTypeDWARFDebugTuIndex
@ eSectionTypeDWARFDebugStr
@ eSectionTypeDWARFDebugLineStr
DWARF v5 .debug_line_str.
@ eSectionTypeDWARFDebugLoc
@ eSectionTypeDWARFAppleNames
@ eSectionTypeDataCStringPointers
Pointers to C string data.
@ eSectionTypeDWARFAppleObjC
@ eSectionTypeSwiftModules
@ eSectionTypeDWARFDebugCuIndex
@ eSectionTypeDWARFDebugAranges
@ eSectionTypeDWARFDebugAbbrevDwo
@ eSectionTypeDWARFGNUDebugAltLink
@ eSectionTypeDWARFDebugStrDwo
@ eSectionTypeDWARFDebugAbbrev
@ eSectionTypeDataPointers
@ eSectionTypeDWARFDebugLocListsDwo
@ eSectionTypeDWARFDebugInfoDwo
@ eSectionTypeDWARFDebugAddr
@ eSectionTypeDataCString
Inlined C string data.
@ eSectionTypeELFSymbolTable
Elf SHT_SYMTAB section.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::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::@119 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)