6893 lines · cpp
1//===-- ObjectFileMachO.cpp -----------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/ScopeExit.h"10#include "llvm/ADT/StringRef.h"11 12#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"13#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"14#include "Plugins/Process/Utility/RegisterContextDarwin_riscv32.h"15#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"16#include "lldb/Core/Debugger.h"17#include "lldb/Core/Module.h"18#include "lldb/Core/ModuleSpec.h"19#include "lldb/Core/PluginManager.h"20#include "lldb/Core/Progress.h"21#include "lldb/Core/Section.h"22#include "lldb/Host/Host.h"23#include "lldb/Symbol/DWARFCallFrameInfo.h"24#include "lldb/Symbol/ObjectFile.h"25#include "lldb/Target/DynamicLoader.h"26#include "lldb/Target/MemoryRegionInfo.h"27#include "lldb/Target/Platform.h"28#include "lldb/Target/Process.h"29#include "lldb/Target/SectionLoadList.h"30#include "lldb/Target/Target.h"31#include "lldb/Target/Thread.h"32#include "lldb/Target/ThreadList.h"33#include "lldb/Utility/ArchSpec.h"34#include "lldb/Utility/DataBuffer.h"35#include "lldb/Utility/FileSpec.h"36#include "lldb/Utility/FileSpecList.h"37#include "lldb/Utility/LLDBLog.h"38#include "lldb/Utility/Log.h"39#include "lldb/Utility/RangeMap.h"40#include "lldb/Utility/RegisterValue.h"41#include "lldb/Utility/Status.h"42#include "lldb/Utility/StreamString.h"43#include "lldb/Utility/Timer.h"44#include "lldb/Utility/UUID.h"45 46#include "lldb/Host/SafeMachO.h"47 48#include "llvm/ADT/DenseSet.h"49#include "llvm/Support/FormatVariadic.h"50#include "llvm/Support/MemoryBuffer.h"51 52#include "ObjectFileMachO.h"53 54#if defined(__APPLE__)55#include <TargetConditionals.h>56// GetLLDBSharedCacheUUID() needs to call dlsym()57#include <dlfcn.h>58#include <mach/mach_init.h>59#include <mach/vm_map.h>60#include <lldb/Host/SafeMachO.h>61#endif62 63#ifndef __APPLE__64#include "lldb/Utility/AppleUuidCompatibility.h"65#else66#include <uuid/uuid.h>67#endif68 69#include <bitset>70#include <memory>71#include <optional>72 73// Unfortunately the signpost header pulls in the system MachO header, too.74#ifdef CPU_TYPE_ARM75#undef CPU_TYPE_ARM76#endif77#ifdef CPU_TYPE_ARM6478#undef CPU_TYPE_ARM6479#endif80#ifdef CPU_TYPE_ARM64_3281#undef CPU_TYPE_ARM64_3282#endif83#ifdef CPU_TYPE_X86_6484#undef CPU_TYPE_X86_6485#endif86#ifdef MH_DYLINKER87#undef MH_DYLINKER88#endif89#ifdef MH_OBJECT90#undef MH_OBJECT91#endif92#ifdef LC_VERSION_MIN_MACOSX93#undef LC_VERSION_MIN_MACOSX94#endif95#ifdef LC_VERSION_MIN_IPHONEOS96#undef LC_VERSION_MIN_IPHONEOS97#endif98#ifdef LC_VERSION_MIN_TVOS99#undef LC_VERSION_MIN_TVOS100#endif101#ifdef LC_VERSION_MIN_WATCHOS102#undef LC_VERSION_MIN_WATCHOS103#endif104#ifdef LC_BUILD_VERSION105#undef LC_BUILD_VERSION106#endif107#ifdef PLATFORM_MACOS108#undef PLATFORM_MACOS109#endif110#ifdef PLATFORM_MACCATALYST111#undef PLATFORM_MACCATALYST112#endif113#ifdef PLATFORM_IOS114#undef PLATFORM_IOS115#endif116#ifdef PLATFORM_IOSSIMULATOR117#undef PLATFORM_IOSSIMULATOR118#endif119#ifdef PLATFORM_TVOS120#undef PLATFORM_TVOS121#endif122#ifdef PLATFORM_TVOSSIMULATOR123#undef PLATFORM_TVOSSIMULATOR124#endif125#ifdef PLATFORM_WATCHOS126#undef PLATFORM_WATCHOS127#endif128#ifdef PLATFORM_WATCHOSSIMULATOR129#undef PLATFORM_WATCHOSSIMULATOR130#endif131 132#define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull133using namespace lldb;134using namespace lldb_private;135using namespace llvm::MachO;136 137static constexpr llvm::StringLiteral g_loader_path = "@loader_path";138static constexpr llvm::StringLiteral g_executable_path = "@executable_path";139 140LLDB_PLUGIN_DEFINE(ObjectFileMachO)141 142static void PrintRegisterValue(RegisterContext *reg_ctx, const char *name,143 const char *alt_name, size_t reg_byte_size,144 Stream &data) {145 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);146 if (reg_info == nullptr)147 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);148 if (reg_info) {149 lldb_private::RegisterValue reg_value;150 if (reg_ctx->ReadRegister(reg_info, reg_value)) {151 if (reg_info->byte_size >= reg_byte_size)152 data.Write(reg_value.GetBytes(), reg_byte_size);153 else {154 data.Write(reg_value.GetBytes(), reg_info->byte_size);155 for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n; ++i)156 data.PutChar(0);157 }158 return;159 }160 }161 // Just write zeros if all else fails162 for (size_t i = 0; i < reg_byte_size; ++i)163 data.PutChar(0);164}165 166class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 {167public:168 RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread,169 const DataExtractor &data)170 : RegisterContextDarwin_x86_64(thread, 0) {171 SetRegisterDataFrom_LC_THREAD(data);172 }173 174 void InvalidateAllRegisters() override {175 // Do nothing... registers are always valid...176 }177 178 void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {179 lldb::offset_t offset = 0;180 SetError(GPRRegSet, Read, -1);181 SetError(FPURegSet, Read, -1);182 SetError(EXCRegSet, Read, -1);183 184 while (offset < data.GetByteSize()) {185 int flavor = data.GetU32(&offset);186 if (flavor == 0)187 break;188 uint32_t count = data.GetU32(&offset);189 switch (flavor) {190 case GPRRegSet: {191 uint32_t *gpr_data = reinterpret_cast<uint32_t *>(&gpr.rax);192 for (uint32_t i = 0; i < count && offset < data.GetByteSize(); ++i)193 gpr_data[i] = data.GetU32(&offset);194 SetError(GPRRegSet, Read, 0);195 } break;196 case FPURegSet:197 // TODO: fill in FPU regs....198 SetError(FPURegSet, Read, -1);199 break;200 case EXCRegSet:201 exc.trapno = data.GetU32(&offset);202 exc.err = data.GetU32(&offset);203 exc.faultvaddr = data.GetU64(&offset);204 SetError(EXCRegSet, Read, 0);205 break;206 default:207 offset += count * 4;208 break;209 }210 }211 }212 213 static bool Create_LC_THREAD(Thread *thread, Stream &data) {214 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());215 if (reg_ctx_sp) {216 RegisterContext *reg_ctx = reg_ctx_sp.get();217 218 data.PutHex32(GPRRegSet); // Flavor219 data.PutHex32(GPRWordCount);220 PrintRegisterValue(reg_ctx, "rax", nullptr, 8, data);221 PrintRegisterValue(reg_ctx, "rbx", nullptr, 8, data);222 PrintRegisterValue(reg_ctx, "rcx", nullptr, 8, data);223 PrintRegisterValue(reg_ctx, "rdx", nullptr, 8, data);224 PrintRegisterValue(reg_ctx, "rdi", nullptr, 8, data);225 PrintRegisterValue(reg_ctx, "rsi", nullptr, 8, data);226 PrintRegisterValue(reg_ctx, "rbp", nullptr, 8, data);227 PrintRegisterValue(reg_ctx, "rsp", nullptr, 8, data);228 PrintRegisterValue(reg_ctx, "r8", nullptr, 8, data);229 PrintRegisterValue(reg_ctx, "r9", nullptr, 8, data);230 PrintRegisterValue(reg_ctx, "r10", nullptr, 8, data);231 PrintRegisterValue(reg_ctx, "r11", nullptr, 8, data);232 PrintRegisterValue(reg_ctx, "r12", nullptr, 8, data);233 PrintRegisterValue(reg_ctx, "r13", nullptr, 8, data);234 PrintRegisterValue(reg_ctx, "r14", nullptr, 8, data);235 PrintRegisterValue(reg_ctx, "r15", nullptr, 8, data);236 PrintRegisterValue(reg_ctx, "rip", nullptr, 8, data);237 PrintRegisterValue(reg_ctx, "rflags", nullptr, 8, data);238 PrintRegisterValue(reg_ctx, "cs", nullptr, 8, data);239 PrintRegisterValue(reg_ctx, "fs", nullptr, 8, data);240 PrintRegisterValue(reg_ctx, "gs", nullptr, 8, data);241 242 // // Write out the FPU registers243 // const size_t fpu_byte_size = sizeof(FPU);244 // size_t bytes_written = 0;245 // data.PutHex32 (FPURegSet);246 // data.PutHex32 (fpu_byte_size/sizeof(uint64_t));247 // bytes_written += data.PutHex32(0); // uint32_t pad[0]248 // bytes_written += data.PutHex32(0); // uint32_t pad[1]249 // bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2,250 // data); // uint16_t fcw; // "fctrl"251 // bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2,252 // data); // uint16_t fsw; // "fstat"253 // bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1,254 // data); // uint8_t ftw; // "ftag"255 // bytes_written += data.PutHex8 (0); // uint8_t pad1;256 // bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2,257 // data); // uint16_t fop; // "fop"258 // bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4,259 // data); // uint32_t ip; // "fioff"260 // bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2,261 // data); // uint16_t cs; // "fiseg"262 // bytes_written += data.PutHex16 (0); // uint16_t pad2;263 // bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4,264 // data); // uint32_t dp; // "fooff"265 // bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2,266 // data); // uint16_t ds; // "foseg"267 // bytes_written += data.PutHex16 (0); // uint16_t pad3;268 // bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4,269 // data); // uint32_t mxcsr;270 // bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL,271 // 4, data);// uint32_t mxcsrmask;272 // bytes_written += WriteRegister (reg_ctx, "stmm0", NULL,273 // sizeof(MMSReg), data);274 // bytes_written += WriteRegister (reg_ctx, "stmm1", NULL,275 // sizeof(MMSReg), data);276 // bytes_written += WriteRegister (reg_ctx, "stmm2", NULL,277 // sizeof(MMSReg), data);278 // bytes_written += WriteRegister (reg_ctx, "stmm3", NULL,279 // sizeof(MMSReg), data);280 // bytes_written += WriteRegister (reg_ctx, "stmm4", NULL,281 // sizeof(MMSReg), data);282 // bytes_written += WriteRegister (reg_ctx, "stmm5", NULL,283 // sizeof(MMSReg), data);284 // bytes_written += WriteRegister (reg_ctx, "stmm6", NULL,285 // sizeof(MMSReg), data);286 // bytes_written += WriteRegister (reg_ctx, "stmm7", NULL,287 // sizeof(MMSReg), data);288 // bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL,289 // sizeof(XMMReg), data);290 // bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL,291 // sizeof(XMMReg), data);292 // bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL,293 // sizeof(XMMReg), data);294 // bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL,295 // sizeof(XMMReg), data);296 // bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL,297 // sizeof(XMMReg), data);298 // bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL,299 // sizeof(XMMReg), data);300 // bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL,301 // sizeof(XMMReg), data);302 // bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL,303 // sizeof(XMMReg), data);304 // bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL,305 // sizeof(XMMReg), data);306 // bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL,307 // sizeof(XMMReg), data);308 // bytes_written += WriteRegister (reg_ctx, "xmm10", NULL,309 // sizeof(XMMReg), data);310 // bytes_written += WriteRegister (reg_ctx, "xmm11", NULL,311 // sizeof(XMMReg), data);312 // bytes_written += WriteRegister (reg_ctx, "xmm12", NULL,313 // sizeof(XMMReg), data);314 // bytes_written += WriteRegister (reg_ctx, "xmm13", NULL,315 // sizeof(XMMReg), data);316 // bytes_written += WriteRegister (reg_ctx, "xmm14", NULL,317 // sizeof(XMMReg), data);318 // bytes_written += WriteRegister (reg_ctx, "xmm15", NULL,319 // sizeof(XMMReg), data);320 //321 // // Fill rest with zeros322 // for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++323 // i)324 // data.PutChar(0);325 326 // Write out the EXC registers327 data.PutHex32(EXCRegSet);328 data.PutHex32(EXCWordCount);329 PrintRegisterValue(reg_ctx, "trapno", nullptr, 4, data);330 PrintRegisterValue(reg_ctx, "err", nullptr, 4, data);331 PrintRegisterValue(reg_ctx, "faultvaddr", nullptr, 8, data);332 return true;333 }334 return false;335 }336 337protected:338 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }339 340 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }341 342 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }343 344 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {345 return 0;346 }347 348 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {349 return 0;350 }351 352 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {353 return 0;354 }355};356 357class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm {358public:359 RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread,360 const DataExtractor &data)361 : RegisterContextDarwin_arm(thread, 0) {362 SetRegisterDataFrom_LC_THREAD(data);363 }364 365 void InvalidateAllRegisters() override {366 // Do nothing... registers are always valid...367 }368 369 void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {370 lldb::offset_t offset = 0;371 SetError(GPRRegSet, Read, -1);372 SetError(FPURegSet, Read, -1);373 SetError(EXCRegSet, Read, -1);374 375 while (offset < data.GetByteSize()) {376 int flavor = data.GetU32(&offset);377 uint32_t count = data.GetU32(&offset);378 offset_t next_thread_state = offset + (count * 4);379 switch (flavor) {380 case GPRAltRegSet:381 case GPRRegSet: {382 // r0-r15, plus CPSR383 uint32_t gpr_buf_count = (sizeof(gpr.r) / sizeof(gpr.r[0])) + 1;384 if (count == gpr_buf_count) {385 for (uint32_t i = 0; i < (count - 1); ++i) {386 gpr.r[i] = data.GetU32(&offset);387 }388 gpr.cpsr = data.GetU32(&offset);389 390 SetError(GPRRegSet, Read, 0);391 }392 } break;393 394 case FPURegSet: {395 uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats;396 const int fpu_reg_buf_size = sizeof(fpu.floats);397 if (data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,398 fpu_reg_buf) == fpu_reg_buf_size) {399 offset += fpu_reg_buf_size;400 fpu.fpscr = data.GetU32(&offset);401 SetError(FPURegSet, Read, 0);402 }403 } break;404 405 case EXCRegSet:406 if (count == 3) {407 exc.exception = data.GetU32(&offset);408 exc.fsr = data.GetU32(&offset);409 exc.far = data.GetU32(&offset);410 SetError(EXCRegSet, Read, 0);411 }412 break;413 }414 offset = next_thread_state;415 }416 }417 418 static bool Create_LC_THREAD(Thread *thread, Stream &data) {419 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());420 if (reg_ctx_sp) {421 RegisterContext *reg_ctx = reg_ctx_sp.get();422 423 data.PutHex32(GPRRegSet); // Flavor424 data.PutHex32(GPRWordCount);425 PrintRegisterValue(reg_ctx, "r0", nullptr, 4, data);426 PrintRegisterValue(reg_ctx, "r1", nullptr, 4, data);427 PrintRegisterValue(reg_ctx, "r2", nullptr, 4, data);428 PrintRegisterValue(reg_ctx, "r3", nullptr, 4, data);429 PrintRegisterValue(reg_ctx, "r4", nullptr, 4, data);430 PrintRegisterValue(reg_ctx, "r5", nullptr, 4, data);431 PrintRegisterValue(reg_ctx, "r6", nullptr, 4, data);432 PrintRegisterValue(reg_ctx, "r7", nullptr, 4, data);433 PrintRegisterValue(reg_ctx, "r8", nullptr, 4, data);434 PrintRegisterValue(reg_ctx, "r9", nullptr, 4, data);435 PrintRegisterValue(reg_ctx, "r10", nullptr, 4, data);436 PrintRegisterValue(reg_ctx, "r11", nullptr, 4, data);437 PrintRegisterValue(reg_ctx, "r12", nullptr, 4, data);438 PrintRegisterValue(reg_ctx, "sp", nullptr, 4, data);439 PrintRegisterValue(reg_ctx, "lr", nullptr, 4, data);440 PrintRegisterValue(reg_ctx, "pc", nullptr, 4, data);441 PrintRegisterValue(reg_ctx, "cpsr", nullptr, 4, data);442 443 // Write out the EXC registers444 // data.PutHex32 (EXCRegSet);445 // data.PutHex32 (EXCWordCount);446 // WriteRegister (reg_ctx, "exception", NULL, 4, data);447 // WriteRegister (reg_ctx, "fsr", NULL, 4, data);448 // WriteRegister (reg_ctx, "far", NULL, 4, data);449 return true;450 }451 return false;452 }453 454protected:455 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }456 457 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }458 459 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }460 461 int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }462 463 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {464 return 0;465 }466 467 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {468 return 0;469 }470 471 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {472 return 0;473 }474 475 int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {476 return -1;477 }478};479 480class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 {481public:482 RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread,483 const DataExtractor &data)484 : RegisterContextDarwin_arm64(thread, 0) {485 SetRegisterDataFrom_LC_THREAD(data);486 }487 488 void InvalidateAllRegisters() override {489 // Do nothing... registers are always valid...490 }491 492 void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {493 lldb::offset_t offset = 0;494 SetError(GPRRegSet, Read, -1);495 SetError(FPURegSet, Read, -1);496 SetError(EXCRegSet, Read, -1);497 while (offset < data.GetByteSize()) {498 int flavor = data.GetU32(&offset);499 uint32_t count = data.GetU32(&offset);500 offset_t next_thread_state = offset + (count * 4);501 switch (flavor) {502 case GPRRegSet:503 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1504 // 32-bit register)505 if (count >= (33 * 2) + 1) {506 for (uint32_t i = 0; i < 29; ++i)507 gpr.x[i] = data.GetU64(&offset);508 gpr.fp = data.GetU64(&offset);509 gpr.lr = data.GetU64(&offset);510 gpr.sp = data.GetU64(&offset);511 gpr.pc = data.GetU64(&offset);512 gpr.cpsr = data.GetU32(&offset);513 SetError(GPRRegSet, Read, 0);514 }515 break;516 case FPURegSet: {517 uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];518 const int fpu_reg_buf_size = sizeof(fpu);519 if (fpu_reg_buf_size == count * sizeof(uint32_t) &&520 data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,521 fpu_reg_buf) == fpu_reg_buf_size) {522 SetError(FPURegSet, Read, 0);523 }524 } break;525 case EXCRegSet:526 if (count == 4) {527 exc.far = data.GetU64(&offset);528 exc.esr = data.GetU32(&offset);529 exc.exception = data.GetU32(&offset);530 SetError(EXCRegSet, Read, 0);531 }532 break;533 }534 offset = next_thread_state;535 }536 }537 538 static bool Create_LC_THREAD(Thread *thread, Stream &data) {539 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());540 if (reg_ctx_sp) {541 RegisterContext *reg_ctx = reg_ctx_sp.get();542 543 data.PutHex32(GPRRegSet); // Flavor544 data.PutHex32(GPRWordCount);545 PrintRegisterValue(reg_ctx, "x0", nullptr, 8, data);546 PrintRegisterValue(reg_ctx, "x1", nullptr, 8, data);547 PrintRegisterValue(reg_ctx, "x2", nullptr, 8, data);548 PrintRegisterValue(reg_ctx, "x3", nullptr, 8, data);549 PrintRegisterValue(reg_ctx, "x4", nullptr, 8, data);550 PrintRegisterValue(reg_ctx, "x5", nullptr, 8, data);551 PrintRegisterValue(reg_ctx, "x6", nullptr, 8, data);552 PrintRegisterValue(reg_ctx, "x7", nullptr, 8, data);553 PrintRegisterValue(reg_ctx, "x8", nullptr, 8, data);554 PrintRegisterValue(reg_ctx, "x9", nullptr, 8, data);555 PrintRegisterValue(reg_ctx, "x10", nullptr, 8, data);556 PrintRegisterValue(reg_ctx, "x11", nullptr, 8, data);557 PrintRegisterValue(reg_ctx, "x12", nullptr, 8, data);558 PrintRegisterValue(reg_ctx, "x13", nullptr, 8, data);559 PrintRegisterValue(reg_ctx, "x14", nullptr, 8, data);560 PrintRegisterValue(reg_ctx, "x15", nullptr, 8, data);561 PrintRegisterValue(reg_ctx, "x16", nullptr, 8, data);562 PrintRegisterValue(reg_ctx, "x17", nullptr, 8, data);563 PrintRegisterValue(reg_ctx, "x18", nullptr, 8, data);564 PrintRegisterValue(reg_ctx, "x19", nullptr, 8, data);565 PrintRegisterValue(reg_ctx, "x20", nullptr, 8, data);566 PrintRegisterValue(reg_ctx, "x21", nullptr, 8, data);567 PrintRegisterValue(reg_ctx, "x22", nullptr, 8, data);568 PrintRegisterValue(reg_ctx, "x23", nullptr, 8, data);569 PrintRegisterValue(reg_ctx, "x24", nullptr, 8, data);570 PrintRegisterValue(reg_ctx, "x25", nullptr, 8, data);571 PrintRegisterValue(reg_ctx, "x26", nullptr, 8, data);572 PrintRegisterValue(reg_ctx, "x27", nullptr, 8, data);573 PrintRegisterValue(reg_ctx, "x28", nullptr, 8, data);574 PrintRegisterValue(reg_ctx, "fp", nullptr, 8, data);575 PrintRegisterValue(reg_ctx, "lr", nullptr, 8, data);576 PrintRegisterValue(reg_ctx, "sp", nullptr, 8, data);577 PrintRegisterValue(reg_ctx, "pc", nullptr, 8, data);578 PrintRegisterValue(reg_ctx, "cpsr", nullptr, 4, data);579 data.PutHex32(0); // uint32_t pad at the end580 581 // Write out the EXC registers582 data.PutHex32(EXCRegSet);583 data.PutHex32(EXCWordCount);584 PrintRegisterValue(reg_ctx, "far", nullptr, 8, data);585 PrintRegisterValue(reg_ctx, "esr", nullptr, 4, data);586 PrintRegisterValue(reg_ctx, "exception", nullptr, 4, data);587 return true;588 }589 return false;590 }591 592protected:593 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }594 595 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }596 597 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }598 599 int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }600 601 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {602 return 0;603 }604 605 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {606 return 0;607 }608 609 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {610 return 0;611 }612 613 int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {614 return -1;615 }616};617 618class RegisterContextDarwin_riscv32_Mach619 : public RegisterContextDarwin_riscv32 {620public:621 RegisterContextDarwin_riscv32_Mach(lldb_private::Thread &thread,622 const DataExtractor &data)623 : RegisterContextDarwin_riscv32(thread, 0) {624 SetRegisterDataFrom_LC_THREAD(data);625 }626 627 void InvalidateAllRegisters() override {628 // Do nothing... registers are always valid...629 }630 631 void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {632 lldb::offset_t offset = 0;633 SetError(GPRRegSet, Read, -1);634 SetError(FPURegSet, Read, -1);635 SetError(EXCRegSet, Read, -1);636 SetError(CSRRegSet, Read, -1);637 while (offset < data.GetByteSize()) {638 int flavor = data.GetU32(&offset);639 uint32_t count = data.GetU32(&offset);640 offset_t next_thread_state = offset + (count * 4);641 switch (flavor) {642 case GPRRegSet:643 // x0-x31 + pc644 if (count >= 32) {645 for (uint32_t i = 0; i < 32; ++i)646 ((uint32_t *)&gpr.x0)[i] = data.GetU32(&offset);647 gpr.pc = data.GetU32(&offset);648 SetError(GPRRegSet, Read, 0);649 }650 break;651 case FPURegSet: {652 // f0-f31 + fcsr653 if (count >= 32) {654 for (uint32_t i = 0; i < 32; ++i)655 ((uint32_t *)&fpr.f0)[i] = data.GetU32(&offset);656 fpr.fcsr = data.GetU32(&offset);657 SetError(FPURegSet, Read, 0);658 }659 } break;660 case EXCRegSet:661 if (count == 3) {662 exc.exception = data.GetU32(&offset);663 exc.fsr = data.GetU32(&offset);664 exc.far = data.GetU32(&offset);665 SetError(EXCRegSet, Read, 0);666 }667 break;668 }669 offset = next_thread_state;670 }671 }672 673 static bool Create_LC_THREAD(Thread *thread, Stream &data) {674 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());675 if (reg_ctx_sp) {676 RegisterContext *reg_ctx = reg_ctx_sp.get();677 678 data.PutHex32(GPRRegSet); // Flavor679 data.PutHex32(GPRWordCount);680 PrintRegisterValue(reg_ctx, "x0", nullptr, 4, data);681 PrintRegisterValue(reg_ctx, "x1", nullptr, 4, data);682 PrintRegisterValue(reg_ctx, "x2", nullptr, 4, data);683 PrintRegisterValue(reg_ctx, "x3", nullptr, 4, data);684 PrintRegisterValue(reg_ctx, "x4", nullptr, 4, data);685 PrintRegisterValue(reg_ctx, "x5", nullptr, 4, data);686 PrintRegisterValue(reg_ctx, "x6", nullptr, 4, data);687 PrintRegisterValue(reg_ctx, "x7", nullptr, 4, data);688 PrintRegisterValue(reg_ctx, "x8", nullptr, 4, data);689 PrintRegisterValue(reg_ctx, "x9", nullptr, 4, data);690 PrintRegisterValue(reg_ctx, "x10", nullptr, 4, data);691 PrintRegisterValue(reg_ctx, "x11", nullptr, 4, data);692 PrintRegisterValue(reg_ctx, "x12", nullptr, 4, data);693 PrintRegisterValue(reg_ctx, "x13", nullptr, 4, data);694 PrintRegisterValue(reg_ctx, "x14", nullptr, 4, data);695 PrintRegisterValue(reg_ctx, "x15", nullptr, 4, data);696 PrintRegisterValue(reg_ctx, "x16", nullptr, 4, data);697 PrintRegisterValue(reg_ctx, "x17", nullptr, 4, data);698 PrintRegisterValue(reg_ctx, "x18", nullptr, 4, data);699 PrintRegisterValue(reg_ctx, "x19", nullptr, 4, data);700 PrintRegisterValue(reg_ctx, "x20", nullptr, 4, data);701 PrintRegisterValue(reg_ctx, "x21", nullptr, 4, data);702 PrintRegisterValue(reg_ctx, "x22", nullptr, 4, data);703 PrintRegisterValue(reg_ctx, "x23", nullptr, 4, data);704 PrintRegisterValue(reg_ctx, "x24", nullptr, 4, data);705 PrintRegisterValue(reg_ctx, "x25", nullptr, 4, data);706 PrintRegisterValue(reg_ctx, "x26", nullptr, 4, data);707 PrintRegisterValue(reg_ctx, "x27", nullptr, 4, data);708 PrintRegisterValue(reg_ctx, "x28", nullptr, 4, data);709 PrintRegisterValue(reg_ctx, "x29", nullptr, 4, data);710 PrintRegisterValue(reg_ctx, "x30", nullptr, 4, data);711 PrintRegisterValue(reg_ctx, "x31", nullptr, 4, data);712 PrintRegisterValue(reg_ctx, "pc", nullptr, 4, data);713 data.PutHex32(0); // uint32_t pad at the end714 715 // Write out the EXC registers716 data.PutHex32(EXCRegSet);717 data.PutHex32(EXCWordCount);718 PrintRegisterValue(reg_ctx, "exception", nullptr, 4, data);719 PrintRegisterValue(reg_ctx, "fsr", nullptr, 4, data);720 PrintRegisterValue(reg_ctx, "far", nullptr, 4, data);721 return true;722 }723 return false;724 }725 726protected:727 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }728 729 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }730 731 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }732 733 int DoReadCSR(lldb::tid_t tid, int flavor, CSR &csr) override { return -1; }734 735 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {736 return 0;737 }738 739 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {740 return 0;741 }742 743 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {744 return 0;745 }746 747 int DoWriteCSR(lldb::tid_t tid, int flavor, const CSR &csr) override {748 return 0;749 }750};751 752static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {753 switch (magic) {754 case MH_MAGIC:755 case MH_CIGAM:756 return sizeof(struct llvm::MachO::mach_header);757 758 case MH_MAGIC_64:759 case MH_CIGAM_64:760 return sizeof(struct llvm::MachO::mach_header_64);761 break;762 763 default:764 break;765 }766 return 0;767}768 769#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008770 771char ObjectFileMachO::ID;772 773void ObjectFileMachO::Initialize() {774 PluginManager::RegisterPlugin(775 GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,776 CreateMemoryInstance, GetModuleSpecifications, SaveCore);777}778 779void ObjectFileMachO::Terminate() {780 PluginManager::UnregisterPlugin(CreateInstance);781}782 783ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp,784 DataBufferSP data_sp,785 lldb::offset_t data_offset,786 const FileSpec *file,787 lldb::offset_t file_offset,788 lldb::offset_t length) {789 if (!data_sp) {790 data_sp = MapFileData(*file, length, file_offset);791 if (!data_sp)792 return nullptr;793 data_offset = 0;794 }795 796 if (!ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))797 return nullptr;798 799 // Update the data to contain the entire file if it doesn't already800 if (data_sp->GetByteSize() < length) {801 data_sp = MapFileData(*file, length, file_offset);802 if (!data_sp)803 return nullptr;804 data_offset = 0;805 }806 auto objfile_up = std::make_unique<ObjectFileMachO>(807 module_sp, data_sp, data_offset, file, file_offset, length);808 if (!objfile_up || !objfile_up->ParseHeader())809 return nullptr;810 811 return objfile_up.release();812}813 814ObjectFile *ObjectFileMachO::CreateMemoryInstance(815 const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,816 const ProcessSP &process_sp, lldb::addr_t header_addr) {817 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {818 std::unique_ptr<ObjectFile> objfile_up(819 new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr));820 if (objfile_up.get() && objfile_up->ParseHeader())821 return objfile_up.release();822 }823 return nullptr;824}825 826size_t ObjectFileMachO::GetModuleSpecifications(827 const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,828 lldb::offset_t data_offset, lldb::offset_t file_offset,829 lldb::offset_t length, lldb_private::ModuleSpecList &specs) {830 const size_t initial_count = specs.GetSize();831 832 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {833 DataExtractor data;834 data.SetData(data_sp);835 llvm::MachO::mach_header header;836 if (ParseHeader(data, &data_offset, header)) {837 size_t header_and_load_cmds =838 header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);839 if (header_and_load_cmds >= data_sp->GetByteSize()) {840 data_sp = MapFileData(file, header_and_load_cmds, file_offset);841 data.SetData(data_sp);842 data_offset = MachHeaderSizeFromMagic(header.magic);843 }844 if (data_sp) {845 ModuleSpec base_spec;846 base_spec.GetFileSpec() = file;847 base_spec.SetObjectOffset(file_offset);848 base_spec.SetObjectSize(length);849 GetAllArchSpecs(header, data, data_offset, base_spec, specs);850 }851 }852 }853 return specs.GetSize() - initial_count;854}855 856ConstString ObjectFileMachO::GetSegmentNameTEXT() {857 static ConstString g_segment_name_TEXT("__TEXT");858 return g_segment_name_TEXT;859}860 861ConstString ObjectFileMachO::GetSegmentNameDATA() {862 static ConstString g_segment_name_DATA("__DATA");863 return g_segment_name_DATA;864}865 866ConstString ObjectFileMachO::GetSegmentNameDATA_DIRTY() {867 static ConstString g_segment_name("__DATA_DIRTY");868 return g_segment_name;869}870 871ConstString ObjectFileMachO::GetSegmentNameDATA_CONST() {872 static ConstString g_segment_name("__DATA_CONST");873 return g_segment_name;874}875 876ConstString ObjectFileMachO::GetSegmentNameOBJC() {877 static ConstString g_segment_name_OBJC("__OBJC");878 return g_segment_name_OBJC;879}880 881ConstString ObjectFileMachO::GetSegmentNameLINKEDIT() {882 static ConstString g_section_name_LINKEDIT("__LINKEDIT");883 return g_section_name_LINKEDIT;884}885 886ConstString ObjectFileMachO::GetSegmentNameDWARF() {887 static ConstString g_section_name("__DWARF");888 return g_section_name;889}890 891ConstString ObjectFileMachO::GetSegmentNameLLVM_COV() {892 static ConstString g_section_name("__LLVM_COV");893 return g_section_name;894}895 896ConstString ObjectFileMachO::GetSectionNameEHFrame() {897 static ConstString g_section_name_eh_frame("__eh_frame");898 return g_section_name_eh_frame;899}900 901ConstString ObjectFileMachO::GetSectionNameLLDBNoNlist() {902 static ConstString g_section_name_lldb_no_nlist("__lldb_no_nlist");903 return g_section_name_lldb_no_nlist;904}905 906bool ObjectFileMachO::MagicBytesMatch(DataBufferSP data_sp,907 lldb::addr_t data_offset,908 lldb::addr_t data_length) {909 DataExtractor data;910 data.SetData(data_sp, data_offset, data_length);911 lldb::offset_t offset = 0;912 uint32_t magic = data.GetU32(&offset);913 914 offset += 4; // cputype915 offset += 4; // cpusubtype916 uint32_t filetype = data.GetU32(&offset);917 918 // A fileset has a Mach-O header but is not an919 // individual file and must be handled via an920 // ObjectContainer plugin.921 if (filetype == llvm::MachO::MH_FILESET)922 return false;923 924 return MachHeaderSizeFromMagic(magic) != 0;925}926 927ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,928 DataBufferSP data_sp,929 lldb::offset_t data_offset,930 const FileSpec *file,931 lldb::offset_t file_offset,932 lldb::offset_t length)933 : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),934 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),935 m_thread_context_offsets_valid(false), m_reexported_dylibs(),936 m_allow_assembly_emulation_unwind_plans(true) {937 ::memset(&m_header, 0, sizeof(m_header));938 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));939}940 941ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,942 lldb::WritableDataBufferSP header_data_sp,943 const lldb::ProcessSP &process_sp,944 lldb::addr_t header_addr)945 : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),946 m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(),947 m_thread_context_offsets_valid(false), m_reexported_dylibs(),948 m_allow_assembly_emulation_unwind_plans(true) {949 ::memset(&m_header, 0, sizeof(m_header));950 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));951}952 953bool ObjectFileMachO::ParseHeader(DataExtractor &data,954 lldb::offset_t *data_offset_ptr,955 llvm::MachO::mach_header &header) {956 data.SetByteOrder(endian::InlHostByteOrder());957 // Leave magic in the original byte order958 header.magic = data.GetU32(data_offset_ptr);959 bool can_parse = false;960 bool is_64_bit = false;961 switch (header.magic) {962 case MH_MAGIC:963 data.SetByteOrder(endian::InlHostByteOrder());964 data.SetAddressByteSize(4);965 can_parse = true;966 break;967 968 case MH_MAGIC_64:969 data.SetByteOrder(endian::InlHostByteOrder());970 data.SetAddressByteSize(8);971 can_parse = true;972 is_64_bit = true;973 break;974 975 case MH_CIGAM:976 data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig977 ? eByteOrderLittle978 : eByteOrderBig);979 data.SetAddressByteSize(4);980 can_parse = true;981 break;982 983 case MH_CIGAM_64:984 data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig985 ? eByteOrderLittle986 : eByteOrderBig);987 data.SetAddressByteSize(8);988 is_64_bit = true;989 can_parse = true;990 break;991 992 default:993 break;994 }995 996 if (can_parse) {997 data.GetU32(data_offset_ptr, &header.cputype, 6);998 if (is_64_bit)999 *data_offset_ptr += 4;1000 return true;1001 } else {1002 memset(&header, 0, sizeof(header));1003 }1004 return false;1005}1006 1007bool ObjectFileMachO::ParseHeader() {1008 ModuleSP module_sp(GetModule());1009 if (!module_sp)1010 return false;1011 1012 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());1013 bool can_parse = false;1014 lldb::offset_t offset = 0;1015 m_data.SetByteOrder(endian::InlHostByteOrder());1016 // Leave magic in the original byte order1017 m_header.magic = m_data.GetU32(&offset);1018 switch (m_header.magic) {1019 case MH_MAGIC:1020 m_data.SetByteOrder(endian::InlHostByteOrder());1021 m_data.SetAddressByteSize(4);1022 can_parse = true;1023 break;1024 1025 case MH_MAGIC_64:1026 m_data.SetByteOrder(endian::InlHostByteOrder());1027 m_data.SetAddressByteSize(8);1028 can_parse = true;1029 break;1030 1031 case MH_CIGAM:1032 m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig1033 ? eByteOrderLittle1034 : eByteOrderBig);1035 m_data.SetAddressByteSize(4);1036 can_parse = true;1037 break;1038 1039 case MH_CIGAM_64:1040 m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig1041 ? eByteOrderLittle1042 : eByteOrderBig);1043 m_data.SetAddressByteSize(8);1044 can_parse = true;1045 break;1046 1047 default:1048 break;1049 }1050 1051 if (can_parse) {1052 m_data.GetU32(&offset, &m_header.cputype, 6);1053 1054 ModuleSpecList all_specs;1055 ModuleSpec base_spec;1056 GetAllArchSpecs(m_header, m_data, MachHeaderSizeFromMagic(m_header.magic),1057 base_spec, all_specs);1058 1059 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {1060 ArchSpec mach_arch =1061 all_specs.GetModuleSpecRefAtIndex(i).GetArchitecture();1062 1063 // Check if the module has a required architecture1064 const ArchSpec &module_arch = module_sp->GetArchitecture();1065 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))1066 continue;1067 1068 if (SetModulesArchitecture(mach_arch)) {1069 const size_t header_and_lc_size =1070 m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);1071 if (m_data.GetByteSize() < header_and_lc_size) {1072 DataBufferSP data_sp;1073 ProcessSP process_sp(m_process_wp.lock());1074 if (process_sp) {1075 data_sp = ReadMemory(process_sp, m_memory_addr, header_and_lc_size);1076 } else {1077 // Read in all only the load command data from the file on disk1078 data_sp = MapFileData(m_file, header_and_lc_size, m_file_offset);1079 if (data_sp->GetByteSize() != header_and_lc_size)1080 continue;1081 }1082 if (data_sp)1083 m_data.SetData(data_sp);1084 }1085 }1086 return true;1087 }1088 // None found.1089 return false;1090 } else {1091 memset(&m_header, 0, sizeof(struct llvm::MachO::mach_header));1092 }1093 return false;1094}1095 1096ByteOrder ObjectFileMachO::GetByteOrder() const {1097 return m_data.GetByteOrder();1098}1099 1100bool ObjectFileMachO::IsExecutable() const {1101 return m_header.filetype == MH_EXECUTE;1102}1103 1104bool ObjectFileMachO::IsDynamicLoader() const {1105 return m_header.filetype == MH_DYLINKER;1106}1107 1108bool ObjectFileMachO::IsSharedCacheBinary() const {1109 return m_header.flags & MH_DYLIB_IN_CACHE;1110}1111 1112bool ObjectFileMachO::IsKext() const {1113 return m_header.filetype == MH_KEXT_BUNDLE;1114}1115 1116uint32_t ObjectFileMachO::GetAddressByteSize() const {1117 return m_data.GetAddressByteSize();1118}1119 1120AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {1121 Symtab *symtab = GetSymtab();1122 if (!symtab)1123 return AddressClass::eUnknown;1124 1125 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);1126 if (symbol) {1127 if (symbol->ValueIsAddress()) {1128 SectionSP section_sp(symbol->GetAddressRef().GetSection());1129 if (section_sp) {1130 const lldb::SectionType section_type = section_sp->GetType();1131 switch (section_type) {1132 case eSectionTypeInvalid:1133 return AddressClass::eUnknown;1134 1135 case eSectionTypeCode:1136 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {1137 // For ARM we have a bit in the n_desc field of the symbol that1138 // tells us ARM/Thumb which is bit 0x0008.1139 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)1140 return AddressClass::eCodeAlternateISA;1141 }1142 return AddressClass::eCode;1143 1144 case eSectionTypeContainer:1145 return AddressClass::eUnknown;1146 1147 case eSectionTypeData:1148 case eSectionTypeDataCString:1149 case eSectionTypeDataCStringPointers:1150 case eSectionTypeDataSymbolAddress:1151 case eSectionTypeData4:1152 case eSectionTypeData8:1153 case eSectionTypeData16:1154 case eSectionTypeDataPointers:1155 case eSectionTypeZeroFill:1156 case eSectionTypeDataObjCMessageRefs:1157 case eSectionTypeDataObjCCFStrings:1158 case eSectionTypeGoSymtab:1159 case eSectionTypeWasmName:1160 return AddressClass::eData;1161 1162 case eSectionTypeDebug:1163 case eSectionTypeDWARFDebugAbbrev:1164 case eSectionTypeDWARFDebugAbbrevDwo:1165 case eSectionTypeDWARFDebugAddr:1166 case eSectionTypeDWARFDebugAranges:1167 case eSectionTypeDWARFDebugCuIndex:1168 case eSectionTypeDWARFDebugFrame:1169 case eSectionTypeDWARFDebugInfo:1170 case eSectionTypeDWARFDebugInfoDwo:1171 case eSectionTypeDWARFDebugLine:1172 case eSectionTypeDWARFDebugLineStr:1173 case eSectionTypeDWARFDebugLoc:1174 case eSectionTypeDWARFDebugLocDwo:1175 case eSectionTypeDWARFDebugLocLists:1176 case eSectionTypeDWARFDebugLocListsDwo:1177 case eSectionTypeDWARFDebugMacInfo:1178 case eSectionTypeDWARFDebugMacro:1179 case eSectionTypeDWARFDebugNames:1180 case eSectionTypeDWARFDebugPubNames:1181 case eSectionTypeDWARFDebugPubTypes:1182 case eSectionTypeDWARFDebugRanges:1183 case eSectionTypeDWARFDebugRngLists:1184 case eSectionTypeDWARFDebugRngListsDwo:1185 case eSectionTypeDWARFDebugStr:1186 case eSectionTypeDWARFDebugStrDwo:1187 case eSectionTypeDWARFDebugStrOffsets:1188 case eSectionTypeDWARFDebugStrOffsetsDwo:1189 case eSectionTypeDWARFDebugTuIndex:1190 case eSectionTypeDWARFDebugTypes:1191 case eSectionTypeDWARFDebugTypesDwo:1192 case eSectionTypeDWARFAppleNames:1193 case eSectionTypeDWARFAppleTypes:1194 case eSectionTypeDWARFAppleNamespaces:1195 case eSectionTypeDWARFAppleObjC:1196 case eSectionTypeDWARFGNUDebugAltLink:1197 case eSectionTypeCTF:1198 case eSectionTypeLLDBTypeSummaries:1199 case eSectionTypeLLDBFormatters:1200 case eSectionTypeSwiftModules:1201 return AddressClass::eDebug;1202 1203 case eSectionTypeEHFrame:1204 case eSectionTypeARMexidx:1205 case eSectionTypeARMextab:1206 case eSectionTypeCompactUnwind:1207 return AddressClass::eRuntime;1208 1209 case eSectionTypeAbsoluteAddress:1210 case eSectionTypeELFSymbolTable:1211 case eSectionTypeELFDynamicSymbols:1212 case eSectionTypeELFRelocationEntries:1213 case eSectionTypeELFDynamicLinkInfo:1214 case eSectionTypeOther:1215 return AddressClass::eUnknown;1216 }1217 }1218 }1219 1220 const SymbolType symbol_type = symbol->GetType();1221 switch (symbol_type) {1222 case eSymbolTypeAny:1223 return AddressClass::eUnknown;1224 case eSymbolTypeAbsolute:1225 return AddressClass::eUnknown;1226 1227 case eSymbolTypeCode:1228 case eSymbolTypeTrampoline:1229 case eSymbolTypeResolver:1230 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {1231 // For ARM we have a bit in the n_desc field of the symbol that tells1232 // us ARM/Thumb which is bit 0x0008.1233 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)1234 return AddressClass::eCodeAlternateISA;1235 }1236 return AddressClass::eCode;1237 1238 case eSymbolTypeData:1239 return AddressClass::eData;1240 case eSymbolTypeRuntime:1241 return AddressClass::eRuntime;1242 case eSymbolTypeException:1243 return AddressClass::eRuntime;1244 case eSymbolTypeSourceFile:1245 return AddressClass::eDebug;1246 case eSymbolTypeHeaderFile:1247 return AddressClass::eDebug;1248 case eSymbolTypeObjectFile:1249 return AddressClass::eDebug;1250 case eSymbolTypeCommonBlock:1251 return AddressClass::eDebug;1252 case eSymbolTypeBlock:1253 return AddressClass::eDebug;1254 case eSymbolTypeLocal:1255 return AddressClass::eData;1256 case eSymbolTypeParam:1257 return AddressClass::eData;1258 case eSymbolTypeVariable:1259 return AddressClass::eData;1260 case eSymbolTypeVariableType:1261 return AddressClass::eDebug;1262 case eSymbolTypeLineEntry:1263 return AddressClass::eDebug;1264 case eSymbolTypeLineHeader:1265 return AddressClass::eDebug;1266 case eSymbolTypeScopeBegin:1267 return AddressClass::eDebug;1268 case eSymbolTypeScopeEnd:1269 return AddressClass::eDebug;1270 case eSymbolTypeAdditional:1271 return AddressClass::eUnknown;1272 case eSymbolTypeCompiler:1273 return AddressClass::eDebug;1274 case eSymbolTypeInstrumentation:1275 return AddressClass::eDebug;1276 case eSymbolTypeUndefined:1277 return AddressClass::eUnknown;1278 case eSymbolTypeObjCClass:1279 return AddressClass::eRuntime;1280 case eSymbolTypeObjCMetaClass:1281 return AddressClass::eRuntime;1282 case eSymbolTypeObjCIVar:1283 return AddressClass::eRuntime;1284 case eSymbolTypeReExported:1285 return AddressClass::eRuntime;1286 }1287 }1288 return AddressClass::eUnknown;1289}1290 1291bool ObjectFileMachO::IsStripped() {1292 if (m_dysymtab.cmd == 0) {1293 ModuleSP module_sp(GetModule());1294 if (module_sp) {1295 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);1296 for (uint32_t i = 0; i < m_header.ncmds; ++i) {1297 const lldb::offset_t load_cmd_offset = offset;1298 1299 llvm::MachO::load_command lc = {};1300 if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)1301 break;1302 if (lc.cmd == LC_DYSYMTAB) {1303 m_dysymtab.cmd = lc.cmd;1304 m_dysymtab.cmdsize = lc.cmdsize;1305 if (m_data.GetU32(&offset, &m_dysymtab.ilocalsym,1306 (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) ==1307 nullptr) {1308 // Clear m_dysymtab if we were unable to read all items from the1309 // load command1310 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));1311 }1312 }1313 offset = load_cmd_offset + lc.cmdsize;1314 }1315 }1316 }1317 if (m_dysymtab.cmd)1318 return m_dysymtab.nlocalsym <= 1;1319 return false;1320}1321 1322ObjectFileMachO::EncryptedFileRanges ObjectFileMachO::GetEncryptedFileRanges() {1323 EncryptedFileRanges result;1324 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);1325 1326 llvm::MachO::encryption_info_command encryption_cmd;1327 for (uint32_t i = 0; i < m_header.ncmds; ++i) {1328 const lldb::offset_t load_cmd_offset = offset;1329 if (m_data.GetU32(&offset, &encryption_cmd, 2) == nullptr)1330 break;1331 1332 // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for the1333 // 3 fields we care about, so treat them the same.1334 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||1335 encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {1336 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) {1337 if (encryption_cmd.cryptid != 0) {1338 EncryptedFileRanges::Entry entry;1339 entry.SetRangeBase(encryption_cmd.cryptoff);1340 entry.SetByteSize(encryption_cmd.cryptsize);1341 result.Append(entry);1342 }1343 }1344 }1345 offset = load_cmd_offset + encryption_cmd.cmdsize;1346 }1347 1348 return result;1349}1350 1351void ObjectFileMachO::SanitizeSegmentCommand(1352 llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx) {1353 if (m_length == 0 || seg_cmd.filesize == 0)1354 return;1355 1356 if (IsSharedCacheBinary() && !IsInMemory()) {1357 // In shared cache images, the load commands are relative to the1358 // shared cache file, and not the specific image we are1359 // examining. Let's fix this up so that it looks like a normal1360 // image.1361 if (strncmp(seg_cmd.segname, GetSegmentNameTEXT().GetCString(),1362 sizeof(seg_cmd.segname)) == 0)1363 m_text_address = seg_cmd.vmaddr;1364 if (strncmp(seg_cmd.segname, GetSegmentNameLINKEDIT().GetCString(),1365 sizeof(seg_cmd.segname)) == 0)1366 m_linkedit_original_offset = seg_cmd.fileoff;1367 1368 seg_cmd.fileoff = seg_cmd.vmaddr - m_text_address;1369 }1370 1371 if (seg_cmd.fileoff > m_length) {1372 // We have a load command that says it extends past the end of the file.1373 // This is likely a corrupt file. We don't have any way to return an error1374 // condition here (this method was likely invoked from something like1375 // ObjectFile::GetSectionList()), so we just null out the section contents,1376 // and dump a message to stdout. The most common case here is core file1377 // debugging with a truncated file.1378 const char *lc_segment_name =1379 seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";1380 GetModule()->ReportWarning(1381 "load command {0} {1} has a fileoff ({2:x16}) that extends beyond "1382 "the end of the file ({3:x16}), ignoring this section",1383 cmd_idx, lc_segment_name, seg_cmd.fileoff, m_length);1384 1385 seg_cmd.fileoff = 0;1386 seg_cmd.filesize = 0;1387 }1388 1389 if (seg_cmd.fileoff + seg_cmd.filesize > m_length) {1390 // We have a load command that says it extends past the end of the file.1391 // This is likely a corrupt file. We don't have any way to return an error1392 // condition here (this method was likely invoked from something like1393 // ObjectFile::GetSectionList()), so we just null out the section contents,1394 // and dump a message to stdout. The most common case here is core file1395 // debugging with a truncated file.1396 const char *lc_segment_name =1397 seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";1398 GetModule()->ReportWarning(1399 "load command {0} {1} has a fileoff + filesize ({2:x16}) that "1400 "extends beyond the end of the file ({3:x16}), the segment will be "1401 "truncated to match",1402 cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize, m_length);1403 1404 // Truncate the length1405 seg_cmd.filesize = m_length - seg_cmd.fileoff;1406 }1407}1408 1409static uint32_t1410GetSegmentPermissions(const llvm::MachO::segment_command_64 &seg_cmd) {1411 uint32_t result = 0;1412 if (seg_cmd.initprot & VM_PROT_READ)1413 result |= ePermissionsReadable;1414 if (seg_cmd.initprot & VM_PROT_WRITE)1415 result |= ePermissionsWritable;1416 if (seg_cmd.initprot & VM_PROT_EXECUTE)1417 result |= ePermissionsExecutable;1418 return result;1419}1420 1421static lldb::SectionType GetSectionType(uint32_t flags,1422 ConstString section_name) {1423 1424 if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))1425 return eSectionTypeCode;1426 1427 uint32_t mach_sect_type = flags & SECTION_TYPE;1428 static ConstString g_sect_name_objc_data("__objc_data");1429 static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs");1430 static ConstString g_sect_name_objc_selrefs("__objc_selrefs");1431 static ConstString g_sect_name_objc_classrefs("__objc_classrefs");1432 static ConstString g_sect_name_objc_superrefs("__objc_superrefs");1433 static ConstString g_sect_name_objc_const("__objc_const");1434 static ConstString g_sect_name_objc_classlist("__objc_classlist");1435 static ConstString g_sect_name_cfstring("__cfstring");1436 1437 static ConstString g_sect_name_dwarf_debug_str_offs("__debug_str_offs");1438 static ConstString g_sect_name_dwarf_debug_str_offs_dwo("__debug_str_offs.dwo");1439 static ConstString g_sect_name_dwarf_apple_names("__apple_names");1440 static ConstString g_sect_name_dwarf_apple_types("__apple_types");1441 static ConstString g_sect_name_dwarf_apple_namespaces("__apple_namespac");1442 static ConstString g_sect_name_dwarf_apple_objc("__apple_objc");1443 static ConstString g_sect_name_eh_frame("__eh_frame");1444 static ConstString g_sect_name_compact_unwind("__unwind_info");1445 static ConstString g_sect_name_text("__text");1446 static ConstString g_sect_name_data("__data");1447 static ConstString g_sect_name_go_symtab("__gosymtab");1448 static ConstString g_sect_name_ctf("__ctf");1449 static ConstString g_sect_name_lldb_summaries("__lldbsummaries");1450 static ConstString g_sect_name_lldb_formatters("__lldbformatters");1451 static ConstString g_sect_name_swift_ast("__swift_ast");1452 1453 if (section_name == g_sect_name_dwarf_debug_str_offs)1454 return eSectionTypeDWARFDebugStrOffsets;1455 if (section_name == g_sect_name_dwarf_debug_str_offs_dwo)1456 return eSectionTypeDWARFDebugStrOffsetsDwo;1457 1458 llvm::StringRef stripped_name = section_name.GetStringRef();1459 if (stripped_name.consume_front("__debug_"))1460 return ObjectFile::GetDWARFSectionTypeFromName(stripped_name);1461 1462 if (section_name == g_sect_name_dwarf_apple_names)1463 return eSectionTypeDWARFAppleNames;1464 if (section_name == g_sect_name_dwarf_apple_types)1465 return eSectionTypeDWARFAppleTypes;1466 if (section_name == g_sect_name_dwarf_apple_namespaces)1467 return eSectionTypeDWARFAppleNamespaces;1468 if (section_name == g_sect_name_dwarf_apple_objc)1469 return eSectionTypeDWARFAppleObjC;1470 if (section_name == g_sect_name_objc_selrefs)1471 return eSectionTypeDataCStringPointers;1472 if (section_name == g_sect_name_objc_msgrefs)1473 return eSectionTypeDataObjCMessageRefs;1474 if (section_name == g_sect_name_eh_frame)1475 return eSectionTypeEHFrame;1476 if (section_name == g_sect_name_compact_unwind)1477 return eSectionTypeCompactUnwind;1478 if (section_name == g_sect_name_cfstring)1479 return eSectionTypeDataObjCCFStrings;1480 if (section_name == g_sect_name_go_symtab)1481 return eSectionTypeGoSymtab;1482 if (section_name == g_sect_name_ctf)1483 return eSectionTypeCTF;1484 if (section_name == g_sect_name_lldb_summaries)1485 return lldb::eSectionTypeLLDBTypeSummaries;1486 if (section_name == g_sect_name_lldb_formatters)1487 return lldb::eSectionTypeLLDBFormatters;1488 if (section_name == g_sect_name_swift_ast)1489 return eSectionTypeSwiftModules;1490 if (section_name == g_sect_name_objc_data ||1491 section_name == g_sect_name_objc_classrefs ||1492 section_name == g_sect_name_objc_superrefs ||1493 section_name == g_sect_name_objc_const ||1494 section_name == g_sect_name_objc_classlist) {1495 return eSectionTypeDataPointers;1496 }1497 1498 switch (mach_sect_type) {1499 // TODO: categorize sections by other flags for regular sections1500 case S_REGULAR:1501 if (section_name == g_sect_name_text)1502 return eSectionTypeCode;1503 if (section_name == g_sect_name_data)1504 return eSectionTypeData;1505 return eSectionTypeOther;1506 case S_ZEROFILL:1507 return eSectionTypeZeroFill;1508 case S_CSTRING_LITERALS: // section with only literal C strings1509 return eSectionTypeDataCString;1510 case S_4BYTE_LITERALS: // section with only 4 byte literals1511 return eSectionTypeData4;1512 case S_8BYTE_LITERALS: // section with only 8 byte literals1513 return eSectionTypeData8;1514 case S_LITERAL_POINTERS: // section with only pointers to literals1515 return eSectionTypeDataPointers;1516 case S_NON_LAZY_SYMBOL_POINTERS: // section with only non-lazy symbol pointers1517 return eSectionTypeDataPointers;1518 case S_LAZY_SYMBOL_POINTERS: // section with only lazy symbol pointers1519 return eSectionTypeDataPointers;1520 case S_SYMBOL_STUBS: // section with only symbol stubs, byte size of stub in1521 // the reserved2 field1522 return eSectionTypeCode;1523 case S_MOD_INIT_FUNC_POINTERS: // section with only function pointers for1524 // initialization1525 return eSectionTypeDataPointers;1526 case S_MOD_TERM_FUNC_POINTERS: // section with only function pointers for1527 // termination1528 return eSectionTypeDataPointers;1529 case S_COALESCED:1530 return eSectionTypeOther;1531 case S_GB_ZEROFILL:1532 return eSectionTypeZeroFill;1533 case S_INTERPOSING: // section with only pairs of function pointers for1534 // interposing1535 return eSectionTypeCode;1536 case S_16BYTE_LITERALS: // section with only 16 byte literals1537 return eSectionTypeData16;1538 case S_DTRACE_DOF:1539 return eSectionTypeDebug;1540 case S_LAZY_DYLIB_SYMBOL_POINTERS:1541 return eSectionTypeDataPointers;1542 default:1543 return eSectionTypeOther;1544 }1545}1546 1547struct ObjectFileMachO::SegmentParsingContext {1548 const EncryptedFileRanges EncryptedRanges;1549 lldb_private::SectionList &UnifiedList;1550 uint32_t NextSegmentIdx = 0;1551 uint32_t NextSectionIdx = 0;1552 bool FileAddressesChanged = false;1553 1554 SegmentParsingContext(EncryptedFileRanges EncryptedRanges,1555 lldb_private::SectionList &UnifiedList)1556 : EncryptedRanges(std::move(EncryptedRanges)), UnifiedList(UnifiedList) {}1557};1558 1559void ObjectFileMachO::ProcessSegmentCommand(1560 const llvm::MachO::load_command &load_cmd_, lldb::offset_t offset,1561 uint32_t cmd_idx, SegmentParsingContext &context) {1562 llvm::MachO::segment_command_64 load_cmd;1563 memcpy(&load_cmd, &load_cmd_, sizeof(load_cmd_));1564 1565 if (!m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16))1566 return;1567 1568 ModuleSP module_sp = GetModule();1569 const bool is_core = GetType() == eTypeCoreFile;1570 const bool is_dsym = (m_header.filetype == MH_DSYM);1571 bool add_section = true;1572 bool add_to_unified = true;1573 ConstString const_segname(1574 load_cmd.segname, strnlen(load_cmd.segname, sizeof(load_cmd.segname)));1575 1576 SectionSP unified_section_sp(1577 context.UnifiedList.FindSectionByName(const_segname));1578 if (is_dsym && unified_section_sp) {1579 if (const_segname == GetSegmentNameLINKEDIT()) {1580 // We need to keep the __LINKEDIT segment private to this object file1581 // only1582 add_to_unified = false;1583 } else {1584 // This is the dSYM file and this section has already been created by the1585 // object file, no need to create it.1586 add_section = false;1587 }1588 }1589 load_cmd.vmaddr = m_data.GetAddress(&offset);1590 load_cmd.vmsize = m_data.GetAddress(&offset);1591 load_cmd.fileoff = m_data.GetAddress(&offset);1592 load_cmd.filesize = m_data.GetAddress(&offset);1593 if (!m_data.GetU32(&offset, &load_cmd.maxprot, 4))1594 return;1595 1596 SanitizeSegmentCommand(load_cmd, cmd_idx);1597 1598 const uint32_t segment_permissions = GetSegmentPermissions(load_cmd);1599 const bool segment_is_encrypted =1600 (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;1601 1602 // Use a segment ID of the segment index shifted left by 8 so they never1603 // conflict with any of the sections.1604 SectionSP segment_sp;1605 if (add_section && (const_segname || is_core)) {1606 segment_sp = std::make_shared<Section>(1607 module_sp, // Module to which this section belongs1608 this, // Object file to which this sections belongs1609 ++context.NextSegmentIdx1610 << 8, // Section ID is the 1 based segment index1611 // shifted right by 8 bits as not to collide with any of the 2561612 // section IDs that are possible1613 const_segname, // Name of this section1614 eSectionTypeContainer, // This section is a container of other1615 // sections.1616 load_cmd.vmaddr, // File VM address == addresses as they are1617 // found in the object file1618 load_cmd.vmsize, // VM size in bytes of this section1619 load_cmd.fileoff, // Offset to the data for this section in1620 // the file1621 load_cmd.filesize, // Size in bytes of this section as found1622 // in the file1623 0, // Segments have no alignment information1624 load_cmd.flags); // Flags for this section1625 1626 segment_sp->SetIsEncrypted(segment_is_encrypted);1627 m_sections_up->AddSection(segment_sp);1628 segment_sp->SetPermissions(segment_permissions);1629 if (add_to_unified)1630 context.UnifiedList.AddSection(segment_sp);1631 } else if (unified_section_sp) {1632 // If this is a dSYM and the file addresses in the dSYM differ from the1633 // file addresses in the ObjectFile, we must use the file base address for1634 // the Section from the dSYM for the DWARF to resolve correctly.1635 // This only happens with binaries in the shared cache in practice;1636 // normally a mismatch like this would give a binary & dSYM that do not1637 // match UUIDs. When a binary is included in the shared cache, its1638 // segments are rearranged to optimize the shared cache, so its file1639 // addresses will differ from what the ObjectFile had originally,1640 // and what the dSYM has.1641 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {1642 Log *log = GetLog(LLDBLog::Symbols);1643 if (log) {1644 log->Printf(1645 "Installing dSYM's %s segment file address over ObjectFile's "1646 "so symbol table/debug info resolves correctly for %s",1647 const_segname.AsCString(),1648 module_sp->GetFileSpec().GetFilename().AsCString());1649 }1650 1651 // Make sure we've parsed the symbol table from the ObjectFile before1652 // we go around changing its Sections.1653 module_sp->GetObjectFile()->GetSymtab();1654 // eh_frame would present the same problems but we parse that on a per-1655 // function basis as-needed so it's more difficult to remove its use of1656 // the Sections. Realistically, the environments where this code path1657 // will be taken will not have eh_frame sections.1658 1659 unified_section_sp->SetFileAddress(load_cmd.vmaddr);1660 1661 // Notify the module that the section addresses have been changed once1662 // we're done so any file-address caches can be updated.1663 context.FileAddressesChanged = true;1664 }1665 m_sections_up->AddSection(unified_section_sp);1666 }1667 1668 llvm::MachO::section_64 sect64;1669 ::memset(§64, 0, sizeof(sect64));1670 // Push a section into our mach sections for the section at index zero1671 // (NO_SECT) if we don't have any mach sections yet...1672 if (m_mach_sections.empty())1673 m_mach_sections.push_back(sect64);1674 uint32_t segment_sect_idx;1675 const lldb::user_id_t first_segment_sectID = context.NextSectionIdx + 1;1676 1677 // 64 bit mach-o files have sections with 32 bit file offsets. If any section1678 // data end will exceed UINT32_MAX, then we need to do some bookkeeping to1679 // ensure we can access this data correctly.1680 uint64_t section_offset_adjust = 0;1681 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;1682 for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;1683 ++segment_sect_idx) {1684 if (m_data.GetU8(&offset, (uint8_t *)sect64.sectname,1685 sizeof(sect64.sectname)) == nullptr)1686 break;1687 if (m_data.GetU8(&offset, (uint8_t *)sect64.segname,1688 sizeof(sect64.segname)) == nullptr)1689 break;1690 sect64.addr = m_data.GetAddress(&offset);1691 sect64.size = m_data.GetAddress(&offset);1692 1693 if (m_data.GetU32(&offset, §64.offset, num_u32s) == nullptr)1694 break;1695 1696 if (IsSharedCacheBinary() && !IsInMemory()) {1697 sect64.offset = sect64.addr - m_text_address;1698 }1699 1700 // Keep a list of mach sections around in case we need to get at data that1701 // isn't stored in the abstracted Sections.1702 m_mach_sections.push_back(sect64);1703 1704 // Make sure we can load sections in mach-o files where some sections cross1705 // a 4GB boundary. llvm::MachO::section_64 have only 32 bit file offsets1706 // for the file offset of the section contents, so we need to track and1707 // sections that overflow and adjust the offsets accordingly.1708 const uint64_t section_file_offset =1709 (uint64_t)sect64.offset + section_offset_adjust;1710 const uint64_t end_section_offset = (uint64_t)sect64.offset + sect64.size;1711 if (end_section_offset >= UINT32_MAX)1712 section_offset_adjust += end_section_offset & 0xFFFFFFFF00000000ull;1713 1714 if (add_section) {1715 ConstString section_name(1716 sect64.sectname, strnlen(sect64.sectname, sizeof(sect64.sectname)));1717 if (!const_segname) {1718 // We have a segment with no name so we need to conjure up segments1719 // that correspond to the section's segname if there isn't already such1720 // a section. If there is such a section, we resize the section so that1721 // it spans all sections. We also mark these sections as fake so1722 // address matches don't hit if they land in the gaps between the child1723 // sections.1724 const_segname.SetTrimmedCStringWithLength(sect64.segname,1725 sizeof(sect64.segname));1726 segment_sp = context.UnifiedList.FindSectionByName(const_segname);1727 if (segment_sp.get()) {1728 Section *segment = segment_sp.get();1729 // Grow the section size as needed.1730 const lldb::addr_t sect64_min_addr = sect64.addr;1731 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;1732 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();1733 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();1734 const lldb::addr_t curr_seg_max_addr =1735 curr_seg_min_addr + curr_seg_byte_size;1736 if (sect64_min_addr >= curr_seg_min_addr) {1737 const lldb::addr_t new_seg_byte_size =1738 sect64_max_addr - curr_seg_min_addr;1739 // Only grow the section size if needed1740 if (new_seg_byte_size > curr_seg_byte_size)1741 segment->SetByteSize(new_seg_byte_size);1742 } else {1743 // We need to change the base address of the segment and adjust the1744 // child section offsets for all existing children.1745 const lldb::addr_t slide_amount =1746 sect64_min_addr - curr_seg_min_addr;1747 segment->Slide(slide_amount, false);1748 segment->GetChildren().Slide(-slide_amount, false);1749 segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);1750 }1751 1752 // Grow the section size as needed.1753 if (section_file_offset) {1754 const lldb::addr_t segment_min_file_offset =1755 segment->GetFileOffset();1756 const lldb::addr_t segment_max_file_offset =1757 segment_min_file_offset + segment->GetFileSize();1758 1759 const lldb::addr_t section_min_file_offset = section_file_offset;1760 const lldb::addr_t section_max_file_offset =1761 section_min_file_offset + sect64.size;1762 const lldb::addr_t new_file_offset =1763 std::min(section_min_file_offset, segment_min_file_offset);1764 const lldb::addr_t new_file_size =1765 std::max(section_max_file_offset, segment_max_file_offset) -1766 new_file_offset;1767 segment->SetFileOffset(new_file_offset);1768 segment->SetFileSize(new_file_size);1769 }1770 } else {1771 // Create a fake section for the section's named segment1772 segment_sp = std::make_shared<Section>(1773 segment_sp, // Parent section1774 module_sp, // Module to which this section belongs1775 this, // Object file to which this section belongs1776 ++context.NextSegmentIdx1777 << 8, // Section ID is the 1 based segment index1778 // shifted right by 8 bits as not to1779 // collide with any of the 256 section IDs1780 // that are possible1781 const_segname, // Name of this section1782 eSectionTypeContainer, // This section is a container of1783 // other sections.1784 sect64.addr, // File VM address == addresses as they are1785 // found in the object file1786 sect64.size, // VM size in bytes of this section1787 section_file_offset, // Offset to the data for this section in1788 // the file1789 section_file_offset ? sect64.size : 0, // Size in bytes of1790 // this section as1791 // found in the file1792 sect64.align,1793 load_cmd.flags); // Flags for this section1794 segment_sp->SetIsFake(true);1795 segment_sp->SetPermissions(segment_permissions);1796 m_sections_up->AddSection(segment_sp);1797 if (add_to_unified)1798 context.UnifiedList.AddSection(segment_sp);1799 segment_sp->SetIsEncrypted(segment_is_encrypted);1800 }1801 }1802 assert(segment_sp.get());1803 1804 lldb::SectionType sect_type = GetSectionType(sect64.flags, section_name);1805 1806 SectionSP section_sp(new Section(1807 segment_sp, module_sp, this, ++context.NextSectionIdx, section_name,1808 sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,1809 section_file_offset, section_file_offset == 0 ? 0 : sect64.size,1810 sect64.align, sect64.flags));1811 // Set the section to be encrypted to match the segment1812 1813 bool section_is_encrypted = false;1814 if (!segment_is_encrypted && load_cmd.filesize != 0)1815 section_is_encrypted = context.EncryptedRanges.FindEntryThatContains(1816 section_file_offset) != nullptr;1817 1818 section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);1819 section_sp->SetPermissions(segment_permissions);1820 segment_sp->GetChildren().AddSection(section_sp);1821 1822 if (segment_sp->IsFake()) {1823 segment_sp.reset();1824 const_segname.Clear();1825 }1826 }1827 }1828 if (segment_sp && is_dsym) {1829 if (first_segment_sectID <= context.NextSectionIdx) {1830 lldb::user_id_t sect_uid;1831 for (sect_uid = first_segment_sectID; sect_uid <= context.NextSectionIdx;1832 ++sect_uid) {1833 SectionSP curr_section_sp(1834 segment_sp->GetChildren().FindSectionByID(sect_uid));1835 SectionSP next_section_sp;1836 if (sect_uid + 1 <= context.NextSectionIdx)1837 next_section_sp =1838 segment_sp->GetChildren().FindSectionByID(sect_uid + 1);1839 1840 if (curr_section_sp.get()) {1841 if (curr_section_sp->GetByteSize() == 0) {1842 if (next_section_sp.get() != nullptr)1843 curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -1844 curr_section_sp->GetFileAddress());1845 else1846 curr_section_sp->SetByteSize(load_cmd.vmsize);1847 }1848 }1849 }1850 }1851 }1852}1853 1854void ObjectFileMachO::ProcessDysymtabCommand(1855 const llvm::MachO::load_command &load_cmd, lldb::offset_t offset) {1856 m_dysymtab.cmd = load_cmd.cmd;1857 m_dysymtab.cmdsize = load_cmd.cmdsize;1858 m_data.GetU32(&offset, &m_dysymtab.ilocalsym,1859 (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);1860}1861 1862void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {1863 if (m_sections_up)1864 return;1865 1866 m_sections_up = std::make_unique<SectionList>();1867 1868 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);1869 // bool dump_sections = false;1870 ModuleSP module_sp(GetModule());1871 1872 offset = MachHeaderSizeFromMagic(m_header.magic);1873 1874 SegmentParsingContext context(GetEncryptedFileRanges(), unified_section_list);1875 llvm::MachO::load_command load_cmd;1876 for (uint32_t i = 0; i < m_header.ncmds; ++i) {1877 const lldb::offset_t load_cmd_offset = offset;1878 if (m_data.GetU32(&offset, &load_cmd, 2) == nullptr)1879 break;1880 1881 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)1882 ProcessSegmentCommand(load_cmd, offset, i, context);1883 else if (load_cmd.cmd == LC_DYSYMTAB)1884 ProcessDysymtabCommand(load_cmd, offset);1885 1886 offset = load_cmd_offset + load_cmd.cmdsize;1887 }1888 1889 if (context.FileAddressesChanged && module_sp)1890 module_sp->SectionFileAddressesChanged();1891}1892 1893class MachSymtabSectionInfo {1894public:1895 MachSymtabSectionInfo(SectionList *section_list)1896 : m_section_list(section_list), m_section_infos() {1897 // Get the number of sections down to a depth of 1 to include all segments1898 // and their sections, but no other sections that may be added for debug1899 // map or1900 m_section_infos.resize(section_list->GetNumSections(1));1901 }1902 1903 SectionSP GetSection(uint8_t n_sect, addr_t file_addr) {1904 if (n_sect == 0)1905 return SectionSP();1906 if (n_sect < m_section_infos.size()) {1907 if (!m_section_infos[n_sect].section_sp) {1908 SectionSP section_sp(m_section_list->FindSectionByID(n_sect));1909 m_section_infos[n_sect].section_sp = section_sp;1910 if (section_sp) {1911 m_section_infos[n_sect].vm_range.SetBaseAddress(1912 section_sp->GetFileAddress());1913 m_section_infos[n_sect].vm_range.SetByteSize(1914 section_sp->GetByteSize());1915 } else {1916 std::string filename = "<unknown>";1917 SectionSP first_section_sp(m_section_list->GetSectionAtIndex(0));1918 if (first_section_sp)1919 filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();1920 1921 Debugger::ReportError(1922 llvm::formatv("unable to find section {0} for a symbol in "1923 "{1}, corrupt file?",1924 n_sect, filename));1925 }1926 }1927 if (m_section_infos[n_sect].vm_range.Contains(file_addr)) {1928 // Symbol is in section.1929 return m_section_infos[n_sect].section_sp;1930 } else if (m_section_infos[n_sect].vm_range.GetByteSize() == 0 &&1931 m_section_infos[n_sect].vm_range.GetBaseAddress() ==1932 file_addr) {1933 // Symbol is in section with zero size, but has the same start address1934 // as the section. This can happen with linker symbols (symbols that1935 // start with the letter 'l' or 'L'.1936 return m_section_infos[n_sect].section_sp;1937 }1938 }1939 return m_section_list->FindSectionContainingFileAddress(file_addr);1940 }1941 1942protected:1943 struct SectionInfo {1944 SectionInfo() : vm_range(), section_sp() {}1945 1946 VMRange vm_range;1947 SectionSP section_sp;1948 };1949 SectionList *m_section_list;1950 std::vector<SectionInfo> m_section_infos;1951};1952 1953#define TRIE_SYMBOL_IS_THUMB (1ULL << 63)1954struct TrieEntry {1955 void Dump() const {1956 printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",1957 static_cast<unsigned long long>(address),1958 static_cast<unsigned long long>(flags),1959 static_cast<unsigned long long>(other), name.GetCString());1960 if (import_name)1961 printf(" -> \"%s\"\n", import_name.GetCString());1962 else1963 printf("\n");1964 }1965 ConstString name;1966 uint64_t address = LLDB_INVALID_ADDRESS;1967 uint64_t flags =1968 0; // EXPORT_SYMBOL_FLAGS_REEXPORT, EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER,1969 // TRIE_SYMBOL_IS_THUMB1970 uint64_t other = 0;1971 ConstString import_name;1972};1973 1974struct TrieEntryWithOffset {1975 lldb::offset_t nodeOffset;1976 TrieEntry entry;1977 1978 TrieEntryWithOffset(lldb::offset_t offset) : nodeOffset(offset), entry() {}1979 1980 void Dump(uint32_t idx) const {1981 printf("[%3u] 0x%16.16llx: ", idx,1982 static_cast<unsigned long long>(nodeOffset));1983 entry.Dump();1984 }1985 1986 bool operator<(const TrieEntryWithOffset &other) const {1987 return (nodeOffset < other.nodeOffset);1988 }1989};1990 1991static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset,1992 const bool is_arm, addr_t text_seg_base_addr,1993 std::vector<llvm::StringRef> &nameSlices,1994 std::set<lldb::addr_t> &resolver_addresses,1995 std::vector<TrieEntryWithOffset> &reexports,1996 std::vector<TrieEntryWithOffset> &ext_symbols) {1997 if (!data.ValidOffset(offset))1998 return true;1999 2000 // Terminal node -- end of a branch, possibly add this to2001 // the symbol table or resolver table.2002 const uint64_t terminalSize = data.GetULEB128(&offset);2003 lldb::offset_t children_offset = offset + terminalSize;2004 if (terminalSize != 0) {2005 TrieEntryWithOffset e(offset);2006 e.entry.flags = data.GetULEB128(&offset);2007 const char *import_name = nullptr;2008 if (e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {2009 e.entry.address = 0;2010 e.entry.other = data.GetULEB128(&offset); // dylib ordinal2011 import_name = data.GetCStr(&offset);2012 } else {2013 e.entry.address = data.GetULEB128(&offset);2014 if (text_seg_base_addr != LLDB_INVALID_ADDRESS)2015 e.entry.address += text_seg_base_addr;2016 if (e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {2017 e.entry.other = data.GetULEB128(&offset);2018 uint64_t resolver_addr = e.entry.other;2019 if (text_seg_base_addr != LLDB_INVALID_ADDRESS)2020 resolver_addr += text_seg_base_addr;2021 if (is_arm)2022 resolver_addr &= THUMB_ADDRESS_BIT_MASK;2023 resolver_addresses.insert(resolver_addr);2024 } else2025 e.entry.other = 0;2026 }2027 bool add_this_entry = false;2028 if (Flags(e.entry.flags).Test(EXPORT_SYMBOL_FLAGS_REEXPORT) &&2029 import_name && import_name[0]) {2030 // add symbols that are reexport symbols with a valid import name.2031 add_this_entry = true;2032 } else if (e.entry.flags == 0 &&2033 (import_name == nullptr || import_name[0] == '\0')) {2034 // add externally visible symbols, in case the nlist record has2035 // been stripped/omitted.2036 add_this_entry = true;2037 }2038 if (add_this_entry) {2039 std::string name;2040 if (!nameSlices.empty()) {2041 for (auto name_slice : nameSlices)2042 name.append(name_slice.data(), name_slice.size());2043 }2044 if (name.size() > 1) {2045 // Skip the leading '_'2046 e.entry.name.SetCStringWithLength(name.c_str() + 1, name.size() - 1);2047 }2048 if (import_name) {2049 // Skip the leading '_'2050 e.entry.import_name.SetCString(import_name + 1);2051 }2052 if (Flags(e.entry.flags).Test(EXPORT_SYMBOL_FLAGS_REEXPORT)) {2053 reexports.push_back(e);2054 } else {2055 if (is_arm && (e.entry.address & 1)) {2056 e.entry.flags |= TRIE_SYMBOL_IS_THUMB;2057 e.entry.address &= THUMB_ADDRESS_BIT_MASK;2058 }2059 ext_symbols.push_back(e);2060 }2061 }2062 }2063 2064 const uint8_t childrenCount = data.GetU8(&children_offset);2065 for (uint8_t i = 0; i < childrenCount; ++i) {2066 const char *cstr = data.GetCStr(&children_offset);2067 if (cstr)2068 nameSlices.push_back(llvm::StringRef(cstr));2069 else2070 return false; // Corrupt data2071 lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);2072 if (childNodeOffset) {2073 if (!ParseTrieEntries(data, childNodeOffset, is_arm, text_seg_base_addr,2074 nameSlices, resolver_addresses, reexports,2075 ext_symbols)) {2076 return false;2077 }2078 }2079 nameSlices.pop_back();2080 }2081 return true;2082}2083 2084static bool2085TryParseV2ObjCMetadataSymbol(const char *&symbol_name,2086 const char *&symbol_name_non_abi_mangled,2087 SymbolType &type) {2088 static constexpr llvm::StringLiteral g_objc_v2_prefix_class("_OBJC_CLASS_$_");2089 static constexpr llvm::StringLiteral g_objc_v2_prefix_metaclass(2090 "_OBJC_METACLASS_$_");2091 static constexpr llvm::StringLiteral g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");2092 2093 llvm::StringRef symbol_name_ref(symbol_name);2094 if (symbol_name_ref.empty())2095 return false;2096 2097 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {2098 symbol_name_non_abi_mangled = symbol_name + 1;2099 symbol_name = symbol_name + g_objc_v2_prefix_class.size();2100 type = eSymbolTypeObjCClass;2101 return true;2102 }2103 2104 if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {2105 symbol_name_non_abi_mangled = symbol_name + 1;2106 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();2107 type = eSymbolTypeObjCMetaClass;2108 return true;2109 }2110 2111 if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {2112 symbol_name_non_abi_mangled = symbol_name + 1;2113 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();2114 type = eSymbolTypeObjCIVar;2115 return true;2116 }2117 2118 return false;2119}2120 2121static SymbolType GetSymbolType(const char *&symbol_name,2122 bool &demangled_is_synthesized,2123 const SectionSP &text_section_sp,2124 const SectionSP &data_section_sp,2125 const SectionSP &data_dirty_section_sp,2126 const SectionSP &data_const_section_sp,2127 const SectionSP &symbol_section) {2128 SymbolType type = eSymbolTypeInvalid;2129 2130 const char *symbol_sect_name = symbol_section->GetName().AsCString();2131 if (symbol_section->IsDescendant(text_section_sp.get())) {2132 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |2133 S_ATTR_SELF_MODIFYING_CODE |2134 S_ATTR_SOME_INSTRUCTIONS))2135 type = eSymbolTypeData;2136 else2137 type = eSymbolTypeCode;2138 } else if (symbol_section->IsDescendant(data_section_sp.get()) ||2139 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||2140 symbol_section->IsDescendant(data_const_section_sp.get())) {2141 if (symbol_sect_name &&2142 ::strstr(symbol_sect_name, "__objc") == symbol_sect_name) {2143 type = eSymbolTypeRuntime;2144 2145 if (symbol_name) {2146 llvm::StringRef symbol_name_ref(symbol_name);2147 if (symbol_name_ref.starts_with("OBJC_")) {2148 static const llvm::StringRef g_objc_v2_prefix_class("OBJC_CLASS_$_");2149 static const llvm::StringRef g_objc_v2_prefix_metaclass(2150 "OBJC_METACLASS_$_");2151 static const llvm::StringRef g_objc_v2_prefix_ivar("OBJC_IVAR_$_");2152 if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {2153 symbol_name = symbol_name + g_objc_v2_prefix_class.size();2154 type = eSymbolTypeObjCClass;2155 demangled_is_synthesized = true;2156 } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {2157 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();2158 type = eSymbolTypeObjCMetaClass;2159 demangled_is_synthesized = true;2160 } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {2161 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();2162 type = eSymbolTypeObjCIVar;2163 demangled_is_synthesized = true;2164 }2165 }2166 }2167 } else if (symbol_sect_name &&2168 ::strstr(symbol_sect_name, "__gcc_except_tab") ==2169 symbol_sect_name) {2170 type = eSymbolTypeException;2171 } else {2172 type = eSymbolTypeData;2173 }2174 } else if (symbol_sect_name &&2175 ::strstr(symbol_sect_name, "__IMPORT") == symbol_sect_name) {2176 type = eSymbolTypeTrampoline;2177 }2178 return type;2179}2180 2181static std::optional<struct nlist_64>2182ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset,2183 size_t nlist_byte_size) {2184 struct nlist_64 nlist;2185 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))2186 return {};2187 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);2188 nlist.n_type = nlist_data.GetU8_unchecked(&nlist_data_offset);2189 nlist.n_sect = nlist_data.GetU8_unchecked(&nlist_data_offset);2190 nlist.n_desc = nlist_data.GetU16_unchecked(&nlist_data_offset);2191 nlist.n_value = nlist_data.GetAddress_unchecked(&nlist_data_offset);2192 return nlist;2193}2194 2195enum { DebugSymbols = true, NonDebugSymbols = false };2196 2197void ObjectFileMachO::ParseSymtab(Symtab &symtab) {2198 ModuleSP module_sp(GetModule());2199 if (!module_sp)2200 return;2201 2202 Log *log = GetLog(LLDBLog::Symbols);2203 2204 const FileSpec &file = m_file ? m_file : module_sp->GetFileSpec();2205 const char *file_name = file.GetFilename().AsCString("<Unknown>");2206 LLDB_SCOPED_TIMERF("ObjectFileMachO::ParseSymtab () module = %s", file_name);2207 LLDB_LOG(log, "Parsing symbol table for {0}", file_name);2208 Progress progress("Parsing symbol table", file_name);2209 2210 LinkeditDataCommandLargeOffsets function_starts_load_command;2211 LinkeditDataCommandLargeOffsets exports_trie_load_command;2212 DyldInfoCommandLargeOffsets dyld_info;2213 DysymtabCommandLargeOffsets dysymtab(m_dysymtab);2214 SymtabCommandLargeOffsets symtab_load_command;2215 // The data element of type bool indicates that this entry is thumb2216 // code.2217 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;2218 2219 // Record the address of every function/data that we add to the symtab.2220 // We add symbols to the table in the order of most information (nlist2221 // records) to least (function starts), and avoid duplicating symbols2222 // via this set.2223 llvm::DenseSet<addr_t> symbols_added;2224 2225 // We are using a llvm::DenseSet for "symbols_added" so we must be sure we2226 // do not add the tombstone or empty keys to the set.2227 auto add_symbol_addr = [&symbols_added](lldb::addr_t file_addr) {2228 // Don't add the tombstone or empty keys.2229 if (file_addr == UINT64_MAX || file_addr == UINT64_MAX - 1)2230 return;2231 symbols_added.insert(file_addr);2232 };2233 FunctionStarts function_starts;2234 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);2235 uint32_t i;2236 FileSpecList dylib_files;2237 UUID image_uuid;2238 2239 for (i = 0; i < m_header.ncmds; ++i) {2240 const lldb::offset_t cmd_offset = offset;2241 // Read in the load command and load command size2242 llvm::MachO::load_command lc;2243 if (m_data.GetU32(&offset, &lc, 2) == nullptr)2244 break;2245 // Watch for the symbol table load command2246 switch (lc.cmd) {2247 case LC_SYMTAB: {2248 llvm::MachO::symtab_command lc_obj;2249 if (m_data.GetU32(&offset, &lc_obj.symoff, 4)) {2250 lc_obj.cmd = lc.cmd;2251 lc_obj.cmdsize = lc.cmdsize;2252 symtab_load_command = lc_obj;2253 }2254 } break;2255 2256 case LC_DYLD_INFO:2257 case LC_DYLD_INFO_ONLY: {2258 llvm::MachO::dyld_info_command lc_obj;2259 if (m_data.GetU32(&offset, &lc_obj.rebase_off, 10)) {2260 lc_obj.cmd = lc.cmd;2261 lc_obj.cmdsize = lc.cmdsize;2262 dyld_info = lc_obj;2263 }2264 } break;2265 2266 case LC_LOAD_DYLIB:2267 case LC_LOAD_WEAK_DYLIB:2268 case LC_REEXPORT_DYLIB:2269 case LC_LOADFVMLIB:2270 case LC_LOAD_UPWARD_DYLIB: {2271 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);2272 const char *path = m_data.PeekCStr(name_offset);2273 if (path) {2274 FileSpec file_spec(path);2275 // Strip the path if there is @rpath, @executable, etc so we just use2276 // the basename2277 if (path[0] == '@')2278 file_spec.ClearDirectory();2279 2280 if (lc.cmd == LC_REEXPORT_DYLIB) {2281 m_reexported_dylibs.AppendIfUnique(file_spec);2282 }2283 2284 dylib_files.Append(file_spec);2285 }2286 } break;2287 2288 case LC_DYLD_EXPORTS_TRIE: {2289 llvm::MachO::linkedit_data_command lc_obj;2290 lc_obj.cmd = lc.cmd;2291 lc_obj.cmdsize = lc.cmdsize;2292 if (m_data.GetU32(&offset, &lc_obj.dataoff, 2))2293 exports_trie_load_command = lc_obj;2294 } break;2295 case LC_FUNCTION_STARTS: {2296 llvm::MachO::linkedit_data_command lc_obj;2297 lc_obj.cmd = lc.cmd;2298 lc_obj.cmdsize = lc.cmdsize;2299 if (m_data.GetU32(&offset, &lc_obj.dataoff, 2))2300 function_starts_load_command = lc_obj;2301 } break;2302 2303 case LC_UUID: {2304 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);2305 2306 if (uuid_bytes)2307 image_uuid = UUID(uuid_bytes, 16);2308 break;2309 }2310 2311 default:2312 break;2313 }2314 offset = cmd_offset + lc.cmdsize;2315 }2316 2317 if (!symtab_load_command.cmd)2318 return;2319 2320 SectionList *section_list = GetSectionList();2321 if (section_list == nullptr)2322 return;2323 2324 const uint32_t addr_byte_size = m_data.GetAddressByteSize();2325 const ByteOrder byte_order = m_data.GetByteOrder();2326 bool bit_width_32 = addr_byte_size == 4;2327 const size_t nlist_byte_size =2328 bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);2329 2330 DataExtractor nlist_data(nullptr, 0, byte_order, addr_byte_size);2331 DataExtractor strtab_data(nullptr, 0, byte_order, addr_byte_size);2332 DataExtractor function_starts_data(nullptr, 0, byte_order, addr_byte_size);2333 DataExtractor indirect_symbol_index_data(nullptr, 0, byte_order,2334 addr_byte_size);2335 DataExtractor dyld_trie_data(nullptr, 0, byte_order, addr_byte_size);2336 2337 const addr_t nlist_data_byte_size =2338 symtab_load_command.nsyms * nlist_byte_size;2339 const addr_t strtab_data_byte_size = symtab_load_command.strsize;2340 addr_t strtab_addr = LLDB_INVALID_ADDRESS;2341 2342 ProcessSP process_sp(m_process_wp.lock());2343 Process *process = process_sp.get();2344 2345 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;2346 bool is_shared_cache_image = IsSharedCacheBinary();2347 bool is_local_shared_cache_image = is_shared_cache_image && !IsInMemory();2348 2349 ConstString g_segment_name_TEXT = GetSegmentNameTEXT();2350 ConstString g_segment_name_DATA = GetSegmentNameDATA();2351 ConstString g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();2352 ConstString g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();2353 ConstString g_segment_name_OBJC = GetSegmentNameOBJC();2354 ConstString g_section_name_eh_frame = GetSectionNameEHFrame();2355 ConstString g_section_name_lldb_no_nlist = GetSectionNameLLDBNoNlist();2356 SectionSP text_section_sp(2357 section_list->FindSectionByName(g_segment_name_TEXT));2358 SectionSP data_section_sp(2359 section_list->FindSectionByName(g_segment_name_DATA));2360 SectionSP linkedit_section_sp(2361 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));2362 SectionSP data_dirty_section_sp(2363 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));2364 SectionSP data_const_section_sp(2365 section_list->FindSectionByName(g_segment_name_DATA_CONST));2366 SectionSP objc_section_sp(2367 section_list->FindSectionByName(g_segment_name_OBJC));2368 SectionSP eh_frame_section_sp;2369 SectionSP lldb_no_nlist_section_sp;2370 if (text_section_sp.get()) {2371 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(2372 g_section_name_eh_frame);2373 lldb_no_nlist_section_sp = text_section_sp->GetChildren().FindSectionByName(2374 g_section_name_lldb_no_nlist);2375 } else {2376 eh_frame_section_sp =2377 section_list->FindSectionByName(g_section_name_eh_frame);2378 lldb_no_nlist_section_sp =2379 section_list->FindSectionByName(g_section_name_lldb_no_nlist);2380 }2381 2382 if (process && m_header.filetype != llvm::MachO::MH_OBJECT &&2383 !is_local_shared_cache_image) {2384 Target &target = process->GetTarget();2385 2386 memory_module_load_level = target.GetMemoryModuleLoadLevel();2387 2388 // If __TEXT,__lldb_no_nlist section is present in this binary,2389 // and we're reading it out of memory, do not read any of the2390 // nlist entries. They are not needed in lldb and it may be2391 // expensive to load these. This is to handle a dylib consisting2392 // of only metadata, no code, but it has many nlist entries.2393 if (lldb_no_nlist_section_sp)2394 memory_module_load_level = eMemoryModuleLoadLevelMinimal;2395 2396 // Reading mach file from memory in a process or core file...2397 2398 if (linkedit_section_sp) {2399 addr_t linkedit_load_addr =2400 linkedit_section_sp->GetLoadBaseAddress(&target);2401 if (linkedit_load_addr == LLDB_INVALID_ADDRESS) {2402 // We might be trying to access the symbol table before the2403 // __LINKEDIT's load address has been set in the target. We can't2404 // fail to read the symbol table, so calculate the right address2405 // manually2406 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(2407 m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());2408 }2409 2410 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();2411 const addr_t symoff_addr = linkedit_load_addr +2412 symtab_load_command.symoff -2413 linkedit_file_offset;2414 strtab_addr = linkedit_load_addr + symtab_load_command.stroff -2415 linkedit_file_offset;2416 2417 // Always load dyld - the dynamic linker - from memory if we didn't2418 // find a binary anywhere else. lldb will not register2419 // dylib/framework/bundle loads/unloads if we don't have the dyld2420 // symbols, we force dyld to load from memory despite the user's2421 // target.memory-module-load-level setting.2422 if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||2423 m_header.filetype == llvm::MachO::MH_DYLINKER) {2424 DataBufferSP nlist_data_sp(2425 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));2426 if (nlist_data_sp)2427 nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());2428 if (dysymtab.nindirectsyms != 0) {2429 const addr_t indirect_syms_addr = linkedit_load_addr +2430 dysymtab.indirectsymoff -2431 linkedit_file_offset;2432 DataBufferSP indirect_syms_data_sp(ReadMemory(2433 process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));2434 if (indirect_syms_data_sp)2435 indirect_symbol_index_data.SetData(2436 indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());2437 // If this binary is outside the shared cache,2438 // cache the string table.2439 // Binaries in the shared cache all share a giant string table,2440 // and we can't share the string tables across multiple2441 // ObjectFileMachO's, so we'd end up re-reading this mega-strtab2442 // for every binary in the shared cache - it would be a big perf2443 // problem. For binaries outside the shared cache, it's faster to2444 // read the entire strtab at once instead of piece-by-piece as we2445 // process the nlist records.2446 if (!is_shared_cache_image) {2447 DataBufferSP strtab_data_sp(2448 ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));2449 if (strtab_data_sp) {2450 strtab_data.SetData(strtab_data_sp, 0,2451 strtab_data_sp->GetByteSize());2452 }2453 }2454 }2455 if (memory_module_load_level >= eMemoryModuleLoadLevelPartial) {2456 if (function_starts_load_command.cmd) {2457 const addr_t func_start_addr =2458 linkedit_load_addr + function_starts_load_command.dataoff -2459 linkedit_file_offset;2460 DataBufferSP func_start_data_sp(2461 ReadMemory(process_sp, func_start_addr,2462 function_starts_load_command.datasize));2463 if (func_start_data_sp)2464 function_starts_data.SetData(func_start_data_sp, 0,2465 func_start_data_sp->GetByteSize());2466 }2467 }2468 }2469 }2470 } else {2471 if (is_local_shared_cache_image) {2472 // The load commands in shared cache images are relative to the2473 // beginning of the shared cache, not the library image. The2474 // data we get handed when creating the ObjectFileMachO starts2475 // at the beginning of a specific library and spans to the end2476 // of the cache to be able to reach the shared LINKEDIT2477 // segments. We need to convert the load command offsets to be2478 // relative to the beginning of our specific image.2479 lldb::addr_t linkedit_offset = linkedit_section_sp->GetFileOffset();2480 lldb::offset_t linkedit_slide =2481 linkedit_offset - m_linkedit_original_offset;2482 symtab_load_command.symoff += linkedit_slide;2483 symtab_load_command.stroff += linkedit_slide;2484 dyld_info.export_off += linkedit_slide;2485 dysymtab.indirectsymoff += linkedit_slide;2486 function_starts_load_command.dataoff += linkedit_slide;2487 exports_trie_load_command.dataoff += linkedit_slide;2488 }2489 2490 nlist_data.SetData(m_data, symtab_load_command.symoff,2491 nlist_data_byte_size);2492 strtab_data.SetData(m_data, symtab_load_command.stroff,2493 strtab_data_byte_size);2494 2495 // We shouldn't have exports data from both the LC_DYLD_INFO command2496 // AND the LC_DYLD_EXPORTS_TRIE command in the same binary:2497 lldbassert(!((dyld_info.export_size > 0)2498 && (exports_trie_load_command.datasize > 0)));2499 if (dyld_info.export_size > 0) {2500 dyld_trie_data.SetData(m_data, dyld_info.export_off,2501 dyld_info.export_size);2502 } else if (exports_trie_load_command.datasize > 0) {2503 dyld_trie_data.SetData(m_data, exports_trie_load_command.dataoff,2504 exports_trie_load_command.datasize);2505 }2506 2507 if (dysymtab.nindirectsyms != 0) {2508 indirect_symbol_index_data.SetData(m_data, dysymtab.indirectsymoff,2509 dysymtab.nindirectsyms * 4);2510 }2511 if (function_starts_load_command.cmd) {2512 function_starts_data.SetData(m_data, function_starts_load_command.dataoff,2513 function_starts_load_command.datasize);2514 }2515 }2516 2517 const bool have_strtab_data = strtab_data.GetByteSize() > 0;2518 2519 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);2520 const bool always_thumb = GetArchitecture().IsAlwaysThumbInstructions();2521 2522 // lldb works best if it knows the start address of all functions in a2523 // module. Linker symbols or debug info are normally the best source of2524 // information for start addr / size but they may be stripped in a released2525 // binary. Two additional sources of information exist in Mach-O binaries:2526 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each2527 // function's start address in the2528 // binary, relative to the text section.2529 // eh_frame - the eh_frame FDEs have the start addr & size of2530 // each function2531 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on2532 // all modern binaries.2533 // Binaries built to run on older releases may need to use eh_frame2534 // information.2535 2536 if (text_section_sp && function_starts_data.GetByteSize()) {2537 FunctionStarts::Entry function_start_entry;2538 function_start_entry.data = false;2539 lldb::offset_t function_start_offset = 0;2540 function_start_entry.addr = text_section_sp->GetFileAddress();2541 uint64_t delta;2542 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >2543 0) {2544 // Now append the current entry2545 function_start_entry.addr += delta;2546 if (is_arm) {2547 if (function_start_entry.addr & 1) {2548 function_start_entry.addr &= THUMB_ADDRESS_BIT_MASK;2549 function_start_entry.data = true;2550 } else if (always_thumb) {2551 function_start_entry.data = true;2552 }2553 }2554 function_starts.Append(function_start_entry);2555 }2556 } else {2557 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the2558 // load command claiming an eh_frame but it doesn't actually have the2559 // eh_frame content. And if we have a dSYM, we don't need to do any of2560 // this fill-in-the-missing-symbols works anyway - the debug info should2561 // give us all the functions in the module.2562 if (text_section_sp.get() && eh_frame_section_sp.get() &&2563 m_type != eTypeDebugInfo) {2564 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp,2565 DWARFCallFrameInfo::EH);2566 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;2567 eh_frame.GetFunctionAddressAndSizeVector(functions);2568 addr_t text_base_addr = text_section_sp->GetFileAddress();2569 size_t count = functions.GetSize();2570 for (size_t i = 0; i < count; ++i) {2571 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func =2572 functions.GetEntryAtIndex(i);2573 if (func) {2574 FunctionStarts::Entry function_start_entry;2575 function_start_entry.addr = func->base - text_base_addr;2576 if (is_arm) {2577 if (function_start_entry.addr & 1) {2578 function_start_entry.addr &= THUMB_ADDRESS_BIT_MASK;2579 function_start_entry.data = true;2580 } else if (always_thumb) {2581 function_start_entry.data = true;2582 }2583 }2584 function_starts.Append(function_start_entry);2585 }2586 }2587 }2588 }2589 2590 const size_t function_starts_count = function_starts.GetSize();2591 2592 // For user process binaries (executables, dylibs, frameworks, bundles), if2593 // we don't have LC_FUNCTION_STARTS/eh_frame section in this binary, we're2594 // going to assume the binary has been stripped. Don't allow assembly2595 // language instruction emulation because we don't know proper function2596 // start boundaries.2597 //2598 // For all other types of binaries (kernels, stand-alone bare board2599 // binaries, kexts), they may not have LC_FUNCTION_STARTS / eh_frame2600 // sections - we should not make any assumptions about them based on that.2601 if (function_starts_count == 0 && CalculateStrata() == eStrataUser) {2602 m_allow_assembly_emulation_unwind_plans = false;2603 Log *unwind_or_symbol_log(GetLog(LLDBLog::Symbols | LLDBLog::Unwind));2604 2605 if (unwind_or_symbol_log)2606 module_sp->LogMessage(2607 unwind_or_symbol_log,2608 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");2609 }2610 2611 const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get()2612 ? eh_frame_section_sp->GetID()2613 : static_cast<user_id_t>(NO_SECT);2614 2615 uint32_t N_SO_index = UINT32_MAX;2616 2617 MachSymtabSectionInfo section_info(section_list);2618 std::vector<uint32_t> N_FUN_indexes;2619 std::vector<uint32_t> N_NSYM_indexes;2620 std::vector<uint32_t> N_INCL_indexes;2621 std::vector<uint32_t> N_BRAC_indexes;2622 std::vector<uint32_t> N_COMM_indexes;2623 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;2624 typedef llvm::DenseMap<uint32_t, uint32_t> NListIndexToSymbolIndexMap;2625 typedef llvm::DenseMap<const char *, uint32_t> ConstNameToSymbolIndexMap;2626 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;2627 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;2628 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;2629 // Any symbols that get merged into another will get an entry in this map2630 // so we know2631 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;2632 uint32_t nlist_idx = 0;2633 Symbol *symbol_ptr = nullptr;2634 2635 uint32_t sym_idx = 0;2636 Symbol *sym = nullptr;2637 size_t num_syms = 0;2638 std::string memory_symbol_name;2639 uint32_t unmapped_local_symbols_found = 0;2640 2641 std::vector<TrieEntryWithOffset> reexport_trie_entries;2642 std::vector<TrieEntryWithOffset> external_sym_trie_entries;2643 std::set<lldb::addr_t> resolver_addresses;2644 2645 const size_t dyld_trie_data_size = dyld_trie_data.GetByteSize();2646 if (dyld_trie_data_size > 0) {2647 LLDB_LOG(log, "Parsing {0} bytes of dyld trie data", dyld_trie_data_size);2648 SectionSP text_segment_sp =2649 GetSectionList()->FindSectionByName(GetSegmentNameTEXT());2650 lldb::addr_t text_segment_file_addr = LLDB_INVALID_ADDRESS;2651 if (text_segment_sp)2652 text_segment_file_addr = text_segment_sp->GetFileAddress();2653 std::vector<llvm::StringRef> nameSlices;2654 ParseTrieEntries(dyld_trie_data, 0, is_arm, text_segment_file_addr,2655 nameSlices, resolver_addresses, reexport_trie_entries,2656 external_sym_trie_entries);2657 }2658 2659 typedef std::set<ConstString> IndirectSymbols;2660 IndirectSymbols indirect_symbol_names;2661 2662#if TARGET_OS_IPHONE2663 2664 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been2665 // optimized by moving LOCAL symbols out of the memory mapped portion of2666 // the DSC. The symbol information has all been retained, but it isn't2667 // available in the normal nlist data. However, there *are* duplicate2668 // entries of *some*2669 // LOCAL symbols in the normal nlist data. To handle this situation2670 // correctly, we must first attempt2671 // to parse any DSC unmapped symbol information. If we find any, we set a2672 // flag that tells the normal nlist parser to ignore all LOCAL symbols.2673 2674 if (IsSharedCacheBinary()) {2675 // Before we can start mapping the DSC, we need to make certain the2676 // target process is actually using the cache we can find.2677 2678 // Next we need to determine the correct path for the dyld shared cache.2679 2680 ArchSpec header_arch = GetArchitecture();2681 2682 UUID dsc_uuid;2683 UUID process_shared_cache_uuid;2684 addr_t process_shared_cache_base_addr;2685 2686 if (process) {2687 GetProcessSharedCacheUUID(process, process_shared_cache_base_addr,2688 process_shared_cache_uuid);2689 }2690 2691 __block bool found_image = false;2692 __block void *nlist_buffer = nullptr;2693 __block unsigned nlist_count = 0;2694 __block char *string_table = nullptr;2695 __block vm_offset_t vm_nlist_memory = 0;2696 __block mach_msg_type_number_t vm_nlist_bytes_read = 0;2697 __block vm_offset_t vm_string_memory = 0;2698 __block mach_msg_type_number_t vm_string_bytes_read = 0;2699 2700 auto _ = llvm::make_scope_exit(^{2701 if (vm_nlist_memory)2702 vm_deallocate(mach_task_self(), vm_nlist_memory, vm_nlist_bytes_read);2703 if (vm_string_memory)2704 vm_deallocate(mach_task_self(), vm_string_memory, vm_string_bytes_read);2705 });2706 2707 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;2708 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;2709 UndefinedNameToDescMap undefined_name_to_desc;2710 SymbolIndexToName reexport_shlib_needs_fixup;2711 2712 dyld_for_each_installed_shared_cache(^(dyld_shared_cache_t shared_cache) {2713 uuid_t cache_uuid;2714 dyld_shared_cache_copy_uuid(shared_cache, &cache_uuid);2715 if (found_image)2716 return;2717 2718 if (process_shared_cache_uuid.IsValid() &&2719 process_shared_cache_uuid != UUID(&cache_uuid, 16))2720 return;2721 2722 dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {2723 uuid_t dsc_image_uuid;2724 if (found_image)2725 return;2726 2727 dyld_image_copy_uuid(image, &dsc_image_uuid);2728 if (image_uuid != UUID(dsc_image_uuid, 16))2729 return;2730 2731 found_image = true;2732 2733 // Compute the size of the string table. We need to ask dyld for a2734 // new SPI to avoid this step.2735 dyld_image_local_nlist_content_4Symbolication(2736 image, ^(const void *nlistStart, uint64_t nlistCount,2737 const char *stringTable) {2738 if (!nlistStart || !nlistCount)2739 return;2740 2741 // The buffers passed here are valid only inside the block.2742 // Use vm_read to make a cheap copy of them available for our2743 // processing later.2744 kern_return_t ret =2745 vm_read(mach_task_self(), (vm_address_t)nlistStart,2746 nlist_byte_size * nlistCount, &vm_nlist_memory,2747 &vm_nlist_bytes_read);2748 if (ret != KERN_SUCCESS)2749 return;2750 assert(vm_nlist_bytes_read == nlist_byte_size * nlistCount);2751 2752 // We don't know the size of the string table. It's cheaper2753 // to map the whole VM region than to determine the size by2754 // parsing all the nlist entries.2755 vm_address_t string_address = (vm_address_t)stringTable;2756 vm_size_t region_size;2757 mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;2758 vm_region_basic_info_data_t info;2759 memory_object_name_t object;2760 ret = vm_region_64(mach_task_self(), &string_address,2761 ®ion_size, VM_REGION_BASIC_INFO_64,2762 (vm_region_info_t)&info, &info_count, &object);2763 if (ret != KERN_SUCCESS)2764 return;2765 2766 ret = vm_read(mach_task_self(), (vm_address_t)stringTable,2767 region_size -2768 ((vm_address_t)stringTable - string_address),2769 &vm_string_memory, &vm_string_bytes_read);2770 if (ret != KERN_SUCCESS)2771 return;2772 2773 nlist_buffer = (void *)vm_nlist_memory;2774 string_table = (char *)vm_string_memory;2775 nlist_count = nlistCount;2776 });2777 });2778 });2779 if (nlist_buffer) {2780 DataExtractor dsc_local_symbols_data(nlist_buffer,2781 nlist_count * nlist_byte_size,2782 byte_order, addr_byte_size);2783 unmapped_local_symbols_found = nlist_count;2784 2785 // The normal nlist code cannot correctly size the Symbols2786 // array, we need to allocate it here.2787 sym = symtab.Resize(2788 symtab_load_command.nsyms + m_dysymtab.nindirectsyms +2789 unmapped_local_symbols_found - m_dysymtab.nlocalsym);2790 num_syms = symtab.GetNumSymbols();2791 2792 lldb::offset_t nlist_data_offset = 0;2793 2794 for (uint32_t nlist_index = 0;2795 nlist_index < nlist_count;2796 nlist_index++) {2797 /////////////////////////////2798 {2799 std::optional<struct nlist_64> nlist_maybe =2800 ParseNList(dsc_local_symbols_data, nlist_data_offset,2801 nlist_byte_size);2802 if (!nlist_maybe)2803 break;2804 struct nlist_64 nlist = *nlist_maybe;2805 2806 SymbolType type = eSymbolTypeInvalid;2807 const char *symbol_name = string_table + nlist.n_strx;2808 2809 if (symbol_name == NULL) {2810 // No symbol should be NULL, even the symbols with no2811 // string values should have an offset zero which2812 // points to an empty C-string2813 Debugger::ReportError(llvm::formatv(2814 "DSC unmapped local symbol[{0}] has invalid "2815 "string table offset {1:x} in {2}, ignoring symbol",2816 nlist_index, nlist.n_strx,2817 module_sp->GetFileSpec().GetPath()));2818 continue;2819 }2820 if (symbol_name[0] == '\0')2821 symbol_name = NULL;2822 2823 const char *symbol_name_non_abi_mangled = NULL;2824 2825 SectionSP symbol_section;2826 bool add_nlist = true;2827 bool is_debug = ((nlist.n_type & N_STAB) != 0);2828 bool demangled_is_synthesized = false;2829 bool is_gsym = false;2830 bool set_value = true;2831 2832 assert(sym_idx < num_syms);2833 2834 sym[sym_idx].SetDebug(is_debug);2835 2836 if (is_debug) {2837 switch (nlist.n_type) {2838 case N_GSYM:2839 // global symbol: name,,NO_SECT,type,02840 // Sometimes the N_GSYM value contains the address.2841 2842 // FIXME: In the .o files, we have a GSYM and a debug2843 // symbol for all the ObjC data. They2844 // have the same address, but we want to ensure that2845 // we always find only the real symbol, 'cause we2846 // don't currently correctly attribute the2847 // GSYM one to the ObjCClass/Ivar/MetaClass2848 // symbol type. This is a temporary hack to make2849 // sure the ObjectiveC symbols get treated correctly.2850 // To do this right, we should coalesce all the GSYM2851 // & global symbols that have the same address.2852 2853 is_gsym = true;2854 sym[sym_idx].SetExternal(true);2855 2856 if (TryParseV2ObjCMetadataSymbol(2857 symbol_name, symbol_name_non_abi_mangled,2858 type)) {2859 demangled_is_synthesized = true;2860 } else {2861 if (nlist.n_value != 0)2862 symbol_section = section_info.GetSection(2863 nlist.n_sect, nlist.n_value);2864 2865 type = eSymbolTypeData;2866 }2867 break;2868 2869 case N_FNAME:2870 // procedure name (f77 kludge): name,,NO_SECT,0,02871 type = eSymbolTypeCompiler;2872 break;2873 2874 case N_FUN:2875 // procedure: name,,n_sect,linenumber,address2876 if (symbol_name) {2877 type = eSymbolTypeCode;2878 symbol_section = section_info.GetSection(2879 nlist.n_sect, nlist.n_value);2880 2881 N_FUN_addr_to_sym_idx.insert(2882 std::make_pair(nlist.n_value, sym_idx));2883 // We use the current number of symbols in the2884 // symbol table in lieu of using nlist_idx in case2885 // we ever start trimming entries out2886 N_FUN_indexes.push_back(sym_idx);2887 } else {2888 type = eSymbolTypeCompiler;2889 2890 if (!N_FUN_indexes.empty()) {2891 // Copy the size of the function into the2892 // original2893 // STAB entry so we don't have2894 // to hunt for it later2895 symtab.SymbolAtIndex(N_FUN_indexes.back())2896 ->SetByteSize(nlist.n_value);2897 N_FUN_indexes.pop_back();2898 // We don't really need the end function STAB as2899 // it contains the size which we already placed2900 // with the original symbol, so don't add it if2901 // we want a minimal symbol table2902 add_nlist = false;2903 }2904 }2905 break;2906 2907 case N_STSYM:2908 // static symbol: name,,n_sect,type,address2909 N_STSYM_addr_to_sym_idx.insert(2910 std::make_pair(nlist.n_value, sym_idx));2911 symbol_section = section_info.GetSection(nlist.n_sect,2912 nlist.n_value);2913 if (symbol_name && symbol_name[0]) {2914 type = ObjectFile::GetSymbolTypeFromName(2915 symbol_name + 1, eSymbolTypeData);2916 }2917 break;2918 2919 case N_LCSYM:2920 // .lcomm symbol: name,,n_sect,type,address2921 symbol_section = section_info.GetSection(nlist.n_sect,2922 nlist.n_value);2923 type = eSymbolTypeCommonBlock;2924 break;2925 2926 case N_BNSYM:2927 // We use the current number of symbols in the symbol2928 // table in lieu of using nlist_idx in case we ever2929 // start trimming entries out Skip these if we want2930 // minimal symbol tables2931 add_nlist = false;2932 break;2933 2934 case N_ENSYM:2935 // Set the size of the N_BNSYM to the terminating2936 // index of this N_ENSYM so that we can always skip2937 // the entire symbol if we need to navigate more2938 // quickly at the source level when parsing STABS2939 // Skip these if we want minimal symbol tables2940 add_nlist = false;2941 break;2942 2943 case N_OPT:2944 // emitted with gcc2_compiled and in gcc source2945 type = eSymbolTypeCompiler;2946 break;2947 2948 case N_RSYM:2949 // register sym: name,,NO_SECT,type,register2950 type = eSymbolTypeVariable;2951 break;2952 2953 case N_SLINE:2954 // src line: 0,,n_sect,linenumber,address2955 symbol_section = section_info.GetSection(nlist.n_sect,2956 nlist.n_value);2957 type = eSymbolTypeLineEntry;2958 break;2959 2960 case N_SSYM:2961 // structure elt: name,,NO_SECT,type,struct_offset2962 type = eSymbolTypeVariableType;2963 break;2964 2965 case N_SO:2966 // source file name2967 type = eSymbolTypeSourceFile;2968 if (symbol_name == NULL) {2969 add_nlist = false;2970 if (N_SO_index != UINT32_MAX) {2971 // Set the size of the N_SO to the terminating2972 // index of this N_SO so that we can always skip2973 // the entire N_SO if we need to navigate more2974 // quickly at the source level when parsing STABS2975 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);2976 symbol_ptr->SetByteSize(sym_idx);2977 symbol_ptr->SetSizeIsSibling(true);2978 }2979 N_NSYM_indexes.clear();2980 N_INCL_indexes.clear();2981 N_BRAC_indexes.clear();2982 N_COMM_indexes.clear();2983 N_FUN_indexes.clear();2984 N_SO_index = UINT32_MAX;2985 } else {2986 // We use the current number of symbols in the2987 // symbol table in lieu of using nlist_idx in case2988 // we ever start trimming entries out2989 const bool N_SO_has_full_path = symbol_name[0] == '/';2990 if (N_SO_has_full_path) {2991 if ((N_SO_index == sym_idx - 1) &&2992 ((sym_idx - 1) < num_syms)) {2993 // We have two consecutive N_SO entries where2994 // the first contains a directory and the2995 // second contains a full path.2996 sym[sym_idx - 1].GetMangled().SetValue(2997 ConstString(symbol_name));2998 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;2999 add_nlist = false;3000 } else {3001 // This is the first entry in a N_SO that3002 // contains a directory or3003 // a full path to the source file3004 N_SO_index = sym_idx;3005 }3006 } else if ((N_SO_index == sym_idx - 1) &&3007 ((sym_idx - 1) < num_syms)) {3008 // This is usually the second N_SO entry that3009 // contains just the filename, so here we combine3010 // it with the first one if we are minimizing the3011 // symbol table3012 const char *so_path = sym[sym_idx - 1]3013 .GetMangled()3014 .GetDemangledName()3015 .AsCString();3016 if (so_path && so_path[0]) {3017 std::string full_so_path(so_path);3018 const size_t double_slash_pos =3019 full_so_path.find("//");3020 if (double_slash_pos != std::string::npos) {3021 // The linker has been generating bad N_SO3022 // entries with doubled up paths3023 // in the format "%s%s" where the first3024 // string in the DW_AT_comp_dir, and the3025 // second is the directory for the source3026 // file so you end up with a path that looks3027 // like "/tmp/src//tmp/src/"3028 FileSpec so_dir(so_path);3029 if (!FileSystem::Instance().Exists(so_dir)) {3030 so_dir.SetFile(3031 &full_so_path[double_slash_pos + 1],3032 FileSpec::Style::native);3033 if (FileSystem::Instance().Exists(so_dir)) {3034 // Trim off the incorrect path3035 full_so_path.erase(0, double_slash_pos + 1);3036 }3037 }3038 }3039 if (*full_so_path.rbegin() != '/')3040 full_so_path += '/';3041 full_so_path += symbol_name;3042 sym[sym_idx - 1].GetMangled().SetValue(3043 ConstString(full_so_path.c_str()));3044 add_nlist = false;3045 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;3046 }3047 } else {3048 // This could be a relative path to a N_SO3049 N_SO_index = sym_idx;3050 }3051 }3052 break;3053 3054 case N_OSO:3055 // object file name: name,,0,0,st_mtime3056 type = eSymbolTypeObjectFile;3057 break;3058 3059 case N_LSYM:3060 // local sym: name,,NO_SECT,type,offset3061 type = eSymbolTypeLocal;3062 break;3063 3064 // INCL scopes3065 case N_BINCL:3066 // include file beginning: name,,NO_SECT,0,sum We use3067 // the current number of symbols in the symbol table3068 // in lieu of using nlist_idx in case we ever start3069 // trimming entries out3070 N_INCL_indexes.push_back(sym_idx);3071 type = eSymbolTypeScopeBegin;3072 break;3073 3074 case N_EINCL:3075 // include file end: name,,NO_SECT,0,03076 // Set the size of the N_BINCL to the terminating3077 // index of this N_EINCL so that we can always skip3078 // the entire symbol if we need to navigate more3079 // quickly at the source level when parsing STABS3080 if (!N_INCL_indexes.empty()) {3081 symbol_ptr =3082 symtab.SymbolAtIndex(N_INCL_indexes.back());3083 symbol_ptr->SetByteSize(sym_idx + 1);3084 symbol_ptr->SetSizeIsSibling(true);3085 N_INCL_indexes.pop_back();3086 }3087 type = eSymbolTypeScopeEnd;3088 break;3089 3090 case N_SOL:3091 // #included file name: name,,n_sect,0,address3092 type = eSymbolTypeHeaderFile;3093 3094 // We currently don't use the header files on darwin3095 add_nlist = false;3096 break;3097 3098 case N_PARAMS:3099 // compiler parameters: name,,NO_SECT,0,03100 type = eSymbolTypeCompiler;3101 break;3102 3103 case N_VERSION:3104 // compiler version: name,,NO_SECT,0,03105 type = eSymbolTypeCompiler;3106 break;3107 3108 case N_OLEVEL:3109 // compiler -O level: name,,NO_SECT,0,03110 type = eSymbolTypeCompiler;3111 break;3112 3113 case N_PSYM:3114 // parameter: name,,NO_SECT,type,offset3115 type = eSymbolTypeVariable;3116 break;3117 3118 case N_ENTRY:3119 // alternate entry: name,,n_sect,linenumber,address3120 symbol_section = section_info.GetSection(nlist.n_sect,3121 nlist.n_value);3122 type = eSymbolTypeLineEntry;3123 break;3124 3125 // Left and Right Braces3126 case N_LBRAC:3127 // left bracket: 0,,NO_SECT,nesting level,address We3128 // use the current number of symbols in the symbol3129 // table in lieu of using nlist_idx in case we ever3130 // start trimming entries out3131 symbol_section = section_info.GetSection(nlist.n_sect,3132 nlist.n_value);3133 N_BRAC_indexes.push_back(sym_idx);3134 type = eSymbolTypeScopeBegin;3135 break;3136 3137 case N_RBRAC:3138 // right bracket: 0,,NO_SECT,nesting level,address3139 // Set the size of the N_LBRAC to the terminating3140 // index of this N_RBRAC so that we can always skip3141 // the entire symbol if we need to navigate more3142 // quickly at the source level when parsing STABS3143 symbol_section = section_info.GetSection(nlist.n_sect,3144 nlist.n_value);3145 if (!N_BRAC_indexes.empty()) {3146 symbol_ptr =3147 symtab.SymbolAtIndex(N_BRAC_indexes.back());3148 symbol_ptr->SetByteSize(sym_idx + 1);3149 symbol_ptr->SetSizeIsSibling(true);3150 N_BRAC_indexes.pop_back();3151 }3152 type = eSymbolTypeScopeEnd;3153 break;3154 3155 case N_EXCL:3156 // deleted include file: name,,NO_SECT,0,sum3157 type = eSymbolTypeHeaderFile;3158 break;3159 3160 // COMM scopes3161 case N_BCOMM:3162 // begin common: name,,NO_SECT,0,03163 // We use the current number of symbols in the symbol3164 // table in lieu of using nlist_idx in case we ever3165 // start trimming entries out3166 type = eSymbolTypeScopeBegin;3167 N_COMM_indexes.push_back(sym_idx);3168 break;3169 3170 case N_ECOML:3171 // end common (local name): 0,,n_sect,0,address3172 symbol_section = section_info.GetSection(nlist.n_sect,3173 nlist.n_value);3174 // Fall through3175 3176 case N_ECOMM:3177 // end common: name,,n_sect,0,03178 // Set the size of the N_BCOMM to the terminating3179 // index of this N_ECOMM/N_ECOML so that we can3180 // always skip the entire symbol if we need to3181 // navigate more quickly at the source level when3182 // parsing STABS3183 if (!N_COMM_indexes.empty()) {3184 symbol_ptr =3185 symtab.SymbolAtIndex(N_COMM_indexes.back());3186 symbol_ptr->SetByteSize(sym_idx + 1);3187 symbol_ptr->SetSizeIsSibling(true);3188 N_COMM_indexes.pop_back();3189 }3190 type = eSymbolTypeScopeEnd;3191 break;3192 3193 case N_LENG:3194 // second stab entry with length information3195 type = eSymbolTypeAdditional;3196 break;3197 3198 default:3199 break;3200 }3201 } else {3202 // uint8_t n_pext = N_PEXT & nlist.n_type;3203 uint8_t n_type = N_TYPE & nlist.n_type;3204 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);3205 3206 switch (n_type) {3207 case N_INDR: {3208 const char *reexport_name_cstr =3209 strtab_data.PeekCStr(nlist.n_value);3210 if (reexport_name_cstr && reexport_name_cstr[0]) {3211 type = eSymbolTypeReExported;3212 ConstString reexport_name(3213 reexport_name_cstr +3214 ((reexport_name_cstr[0] == '_') ? 1 : 0));3215 sym[sym_idx].SetReExportedSymbolName(reexport_name);3216 set_value = false;3217 reexport_shlib_needs_fixup[sym_idx] = reexport_name;3218 indirect_symbol_names.insert(ConstString(3219 symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));3220 } else3221 type = eSymbolTypeUndefined;3222 } break;3223 3224 case N_UNDF:3225 if (symbol_name && symbol_name[0]) {3226 ConstString undefined_name(3227 symbol_name + ((symbol_name[0] == '_') ? 1 : 0));3228 undefined_name_to_desc[undefined_name] = nlist.n_desc;3229 }3230 // Fall through3231 case N_PBUD:3232 type = eSymbolTypeUndefined;3233 break;3234 3235 case N_ABS:3236 type = eSymbolTypeAbsolute;3237 break;3238 3239 case N_SECT: {3240 symbol_section = section_info.GetSection(nlist.n_sect,3241 nlist.n_value);3242 3243 if (symbol_section == NULL) {3244 // TODO: warn about this?3245 add_nlist = false;3246 break;3247 }3248 3249 if (TEXT_eh_frame_sectID == nlist.n_sect) {3250 type = eSymbolTypeException;3251 } else {3252 uint32_t section_type =3253 symbol_section->Get() & SECTION_TYPE;3254 3255 switch (section_type) {3256 case S_CSTRING_LITERALS:3257 type = eSymbolTypeData;3258 break; // section with only literal C strings3259 case S_4BYTE_LITERALS:3260 type = eSymbolTypeData;3261 break; // section with only 4 byte literals3262 case S_8BYTE_LITERALS:3263 type = eSymbolTypeData;3264 break; // section with only 8 byte literals3265 case S_LITERAL_POINTERS:3266 type = eSymbolTypeTrampoline;3267 break; // section with only pointers to literals3268 case S_NON_LAZY_SYMBOL_POINTERS:3269 type = eSymbolTypeTrampoline;3270 break; // section with only non-lazy symbol3271 // pointers3272 case S_LAZY_SYMBOL_POINTERS:3273 type = eSymbolTypeTrampoline;3274 break; // section with only lazy symbol pointers3275 case S_SYMBOL_STUBS:3276 type = eSymbolTypeTrampoline;3277 break; // section with only symbol stubs, byte3278 // size of stub in the reserved2 field3279 case S_MOD_INIT_FUNC_POINTERS:3280 type = eSymbolTypeCode;3281 break; // section with only function pointers for3282 // initialization3283 case S_MOD_TERM_FUNC_POINTERS:3284 type = eSymbolTypeCode;3285 break; // section with only function pointers for3286 // termination3287 case S_INTERPOSING:3288 type = eSymbolTypeTrampoline;3289 break; // section with only pairs of function3290 // pointers for interposing3291 case S_16BYTE_LITERALS:3292 type = eSymbolTypeData;3293 break; // section with only 16 byte literals3294 case S_DTRACE_DOF:3295 type = eSymbolTypeInstrumentation;3296 break;3297 case S_LAZY_DYLIB_SYMBOL_POINTERS:3298 type = eSymbolTypeTrampoline;3299 break;3300 default:3301 switch (symbol_section->GetType()) {3302 case lldb::eSectionTypeCode:3303 type = eSymbolTypeCode;3304 break;3305 case eSectionTypeData:3306 case eSectionTypeDataCString: // Inlined C string3307 // data3308 case eSectionTypeDataCStringPointers: // Pointers3309 // to C3310 // string3311 // data3312 case eSectionTypeDataSymbolAddress: // Address of3313 // a symbol in3314 // the symbol3315 // table3316 case eSectionTypeData4:3317 case eSectionTypeData8:3318 case eSectionTypeData16:3319 type = eSymbolTypeData;3320 break;3321 default:3322 break;3323 }3324 break;3325 }3326 3327 if (type == eSymbolTypeInvalid) {3328 const char *symbol_sect_name =3329 symbol_section->GetName().AsCString();3330 if (symbol_section->IsDescendant(3331 text_section_sp.get())) {3332 if (symbol_section->IsClear(3333 S_ATTR_PURE_INSTRUCTIONS |3334 S_ATTR_SELF_MODIFYING_CODE |3335 S_ATTR_SOME_INSTRUCTIONS))3336 type = eSymbolTypeData;3337 else3338 type = eSymbolTypeCode;3339 } else if (symbol_section->IsDescendant(3340 data_section_sp.get()) ||3341 symbol_section->IsDescendant(3342 data_dirty_section_sp.get()) ||3343 symbol_section->IsDescendant(3344 data_const_section_sp.get())) {3345 if (symbol_sect_name &&3346 ::strstr(symbol_sect_name, "__objc") ==3347 symbol_sect_name) {3348 type = eSymbolTypeRuntime;3349 3350 if (TryParseV2ObjCMetadataSymbol(3351 symbol_name,3352 symbol_name_non_abi_mangled, type))3353 demangled_is_synthesized = true;3354 } else if (symbol_sect_name &&3355 ::strstr(symbol_sect_name,3356 "__gcc_except_tab") ==3357 symbol_sect_name) {3358 type = eSymbolTypeException;3359 } else {3360 type = eSymbolTypeData;3361 }3362 } else if (symbol_sect_name &&3363 ::strstr(symbol_sect_name, "__IMPORT") ==3364 symbol_sect_name) {3365 type = eSymbolTypeTrampoline;3366 } else if (symbol_section->IsDescendant(3367 objc_section_sp.get())) {3368 type = eSymbolTypeRuntime;3369 if (symbol_name && symbol_name[0] == '.') {3370 llvm::StringRef symbol_name_ref(symbol_name);3371 llvm::StringRef3372 g_objc_v1_prefix_class(".objc_class_name_");3373 if (symbol_name_ref.starts_with(3374 g_objc_v1_prefix_class)) {3375 symbol_name_non_abi_mangled = symbol_name;3376 symbol_name = symbol_name +3377 g_objc_v1_prefix_class.size();3378 type = eSymbolTypeObjCClass;3379 demangled_is_synthesized = true;3380 }3381 }3382 }3383 }3384 }3385 } break;3386 }3387 }3388 3389 if (add_nlist) {3390 uint64_t symbol_value = nlist.n_value;3391 if (symbol_name_non_abi_mangled) {3392 sym[sym_idx].GetMangled().SetMangledName(3393 ConstString(symbol_name_non_abi_mangled));3394 sym[sym_idx].GetMangled().SetDemangledName(3395 ConstString(symbol_name));3396 } else {3397 if (symbol_name && symbol_name[0] == '_') {3398 symbol_name++; // Skip the leading underscore3399 }3400 3401 if (symbol_name) {3402 ConstString const_symbol_name(symbol_name);3403 sym[sym_idx].GetMangled().SetValue(const_symbol_name);3404 if (is_gsym && is_debug) {3405 const char *gsym_name =3406 sym[sym_idx]3407 .GetMangled()3408 .GetName(Mangled::ePreferMangled)3409 .GetCString();3410 if (gsym_name)3411 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;3412 }3413 }3414 }3415 if (symbol_section) {3416 const addr_t section_file_addr =3417 symbol_section->GetFileAddress();3418 symbol_value -= section_file_addr;3419 }3420 3421 if (is_debug == false) {3422 if (type == eSymbolTypeCode) {3423 // See if we can find a N_FUN entry for any code3424 // symbols. If we do find a match, and the name3425 // matches, then we can merge the two into just the3426 // function symbol to avoid duplicate entries in3427 // the symbol table3428 auto range =3429 N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);3430 if (range.first != range.second) {3431 bool found_it = false;3432 for (auto pos = range.first; pos != range.second;3433 ++pos) {3434 if (sym[sym_idx].GetMangled().GetName(3435 Mangled::ePreferMangled) ==3436 sym[pos->second].GetMangled().GetName(3437 Mangled::ePreferMangled)) {3438 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;3439 // We just need the flags from the linker3440 // symbol, so put these flags3441 // into the N_FUN flags to avoid duplicate3442 // symbols in the symbol table3443 sym[pos->second].SetExternal(3444 sym[sym_idx].IsExternal());3445 sym[pos->second].SetFlags(nlist.n_type << 16 |3446 nlist.n_desc);3447 if (resolver_addresses.find(nlist.n_value) !=3448 resolver_addresses.end())3449 sym[pos->second].SetType(eSymbolTypeResolver);3450 sym[sym_idx].Clear();3451 found_it = true;3452 break;3453 }3454 }3455 if (found_it)3456 continue;3457 } else {3458 if (resolver_addresses.find(nlist.n_value) !=3459 resolver_addresses.end())3460 type = eSymbolTypeResolver;3461 }3462 } else if (type == eSymbolTypeData ||3463 type == eSymbolTypeObjCClass ||3464 type == eSymbolTypeObjCMetaClass ||3465 type == eSymbolTypeObjCIVar) {3466 // See if we can find a N_STSYM entry for any data3467 // symbols. If we do find a match, and the name3468 // matches, then we can merge the two into just the3469 // Static symbol to avoid duplicate entries in the3470 // symbol table3471 auto range = N_STSYM_addr_to_sym_idx.equal_range(3472 nlist.n_value);3473 if (range.first != range.second) {3474 bool found_it = false;3475 for (auto pos = range.first; pos != range.second;3476 ++pos) {3477 if (sym[sym_idx].GetMangled().GetName(3478 Mangled::ePreferMangled) ==3479 sym[pos->second].GetMangled().GetName(3480 Mangled::ePreferMangled)) {3481 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;3482 // We just need the flags from the linker3483 // symbol, so put these flags3484 // into the N_STSYM flags to avoid duplicate3485 // symbols in the symbol table3486 sym[pos->second].SetExternal(3487 sym[sym_idx].IsExternal());3488 sym[pos->second].SetFlags(nlist.n_type << 16 |3489 nlist.n_desc);3490 sym[sym_idx].Clear();3491 found_it = true;3492 break;3493 }3494 }3495 if (found_it)3496 continue;3497 } else {3498 const char *gsym_name =3499 sym[sym_idx]3500 .GetMangled()3501 .GetName(Mangled::ePreferMangled)3502 .GetCString();3503 if (gsym_name) {3504 // Combine N_GSYM stab entries with the non3505 // stab symbol3506 ConstNameToSymbolIndexMap::const_iterator pos =3507 N_GSYM_name_to_sym_idx.find(gsym_name);3508 if (pos != N_GSYM_name_to_sym_idx.end()) {3509 const uint32_t GSYM_sym_idx = pos->second;3510 m_nlist_idx_to_sym_idx[nlist_idx] =3511 GSYM_sym_idx;3512 // Copy the address, because often the N_GSYM3513 // address has an invalid address of zero3514 // when the global is a common symbol3515 sym[GSYM_sym_idx].GetAddressRef().SetSection(3516 symbol_section);3517 sym[GSYM_sym_idx].GetAddressRef().SetOffset(3518 symbol_value);3519 add_symbol_addr(sym[GSYM_sym_idx]3520 .GetAddress()3521 .GetFileAddress());3522 // We just need the flags from the linker3523 // symbol, so put these flags3524 // into the N_GSYM flags to avoid duplicate3525 // symbols in the symbol table3526 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |3527 nlist.n_desc);3528 sym[sym_idx].Clear();3529 continue;3530 }3531 }3532 }3533 }3534 }3535 3536 sym[sym_idx].SetID(nlist_idx);3537 sym[sym_idx].SetType(type);3538 if (set_value) {3539 sym[sym_idx].GetAddressRef().SetSection(symbol_section);3540 sym[sym_idx].GetAddressRef().SetOffset(symbol_value);3541 add_symbol_addr(3542 sym[sym_idx].GetAddress().GetFileAddress());3543 }3544 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);3545 3546 if (demangled_is_synthesized)3547 sym[sym_idx].SetDemangledNameIsSynthesized(true);3548 ++sym_idx;3549 } else {3550 sym[sym_idx].Clear();3551 }3552 }3553 /////////////////////////////3554 }3555 }3556 3557 for (const auto &pos : reexport_shlib_needs_fixup) {3558 const auto undef_pos = undefined_name_to_desc.find(pos.second);3559 if (undef_pos != undefined_name_to_desc.end()) {3560 const uint8_t dylib_ordinal =3561 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);3562 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())3563 sym[pos.first].SetReExportedSymbolSharedLibrary(3564 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));3565 }3566 }3567 }3568 3569#endif3570 lldb::offset_t nlist_data_offset = 0;3571 3572 if (nlist_data.GetByteSize() > 0) {3573 3574 // If the sym array was not created while parsing the DSC unmapped3575 // symbols, create it now.3576 if (sym == nullptr) {3577 sym =3578 symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);3579 num_syms = symtab.GetNumSymbols();3580 }3581 3582 if (unmapped_local_symbols_found) {3583 assert(m_dysymtab.ilocalsym == 0);3584 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);3585 nlist_idx = m_dysymtab.nlocalsym;3586 } else {3587 nlist_idx = 0;3588 }3589 3590 typedef llvm::DenseMap<ConstString, uint16_t> UndefinedNameToDescMap;3591 typedef llvm::DenseMap<uint32_t, ConstString> SymbolIndexToName;3592 UndefinedNameToDescMap undefined_name_to_desc;3593 SymbolIndexToName reexport_shlib_needs_fixup;3594 3595 // Symtab parsing is a huge mess. Everything is entangled and the code3596 // requires access to a ridiculous amount of variables. LLDB depends3597 // heavily on the proper merging of symbols and to get that right we need3598 // to make sure we have parsed all the debug symbols first. Therefore we3599 // invoke the lambda twice, once to parse only the debug symbols and then3600 // once more to parse the remaining symbols.3601 auto ParseSymbolLambda = [&](struct nlist_64 &nlist, uint32_t nlist_idx,3602 bool debug_only) {3603 const bool is_debug = ((nlist.n_type & N_STAB) != 0);3604 if (is_debug != debug_only)3605 return true;3606 3607 const char *symbol_name_non_abi_mangled = nullptr;3608 const char *symbol_name = nullptr;3609 3610 if (have_strtab_data) {3611 symbol_name = strtab_data.PeekCStr(nlist.n_strx);3612 3613 if (symbol_name == nullptr) {3614 // No symbol should be NULL, even the symbols with no string values3615 // should have an offset zero which points to an empty C-string3616 Debugger::ReportError(llvm::formatv(3617 "symbol[{0}] has invalid string table offset {1:x} in {2}, "3618 "ignoring symbol",3619 nlist_idx, nlist.n_strx, module_sp->GetFileSpec().GetPath()));3620 return true;3621 }3622 if (symbol_name[0] == '\0')3623 symbol_name = nullptr;3624 } else {3625 const addr_t str_addr = strtab_addr + nlist.n_strx;3626 Status str_error;3627 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,3628 str_error))3629 symbol_name = memory_symbol_name.c_str();3630 }3631 3632 SymbolType type = eSymbolTypeInvalid;3633 SectionSP symbol_section;3634 bool add_nlist = true;3635 bool is_gsym = false;3636 bool demangled_is_synthesized = false;3637 bool set_value = true;3638 3639 assert(sym_idx < num_syms);3640 sym[sym_idx].SetDebug(is_debug);3641 3642 if (is_debug) {3643 switch (nlist.n_type) {3644 case N_GSYM: {3645 // global symbol: name,,NO_SECT,type,03646 // Sometimes the N_GSYM value contains the address.3647 3648 // FIXME: In the .o files, we have a GSYM and a debug symbol for all3649 // the ObjC data. They3650 // have the same address, but we want to ensure that we always find3651 // only the real symbol, 'cause we don't currently correctly3652 // attribute the GSYM one to the ObjCClass/Ivar/MetaClass symbol3653 // type. This is a temporary hack to make sure the ObjectiveC3654 // symbols get treated correctly. To do this right, we should3655 // coalesce all the GSYM & global symbols that have the same3656 // address.3657 is_gsym = true;3658 sym[sym_idx].SetExternal(true);3659 3660 if (TryParseV2ObjCMetadataSymbol(symbol_name,3661 symbol_name_non_abi_mangled, type)) {3662 demangled_is_synthesized = true;3663 } else {3664 if (nlist.n_value != 0)3665 symbol_section =3666 section_info.GetSection(nlist.n_sect, nlist.n_value);3667 3668 type = eSymbolTypeData;3669 }3670 } break;3671 3672 case N_FNAME:3673 // procedure name (f77 kludge): name,,NO_SECT,0,03674 type = eSymbolTypeCompiler;3675 break;3676 3677 case N_FUN:3678 // procedure: name,,n_sect,linenumber,address3679 if (symbol_name) {3680 type = eSymbolTypeCode;3681 symbol_section =3682 section_info.GetSection(nlist.n_sect, nlist.n_value);3683 3684 N_FUN_addr_to_sym_idx.insert(3685 std::make_pair(nlist.n_value, sym_idx));3686 // We use the current number of symbols in the symbol table in3687 // lieu of using nlist_idx in case we ever start trimming entries3688 // out3689 N_FUN_indexes.push_back(sym_idx);3690 } else {3691 type = eSymbolTypeCompiler;3692 3693 if (!N_FUN_indexes.empty()) {3694 // Copy the size of the function into the original STAB entry3695 // so we don't have to hunt for it later3696 symtab.SymbolAtIndex(N_FUN_indexes.back())3697 ->SetByteSize(nlist.n_value);3698 N_FUN_indexes.pop_back();3699 // We don't really need the end function STAB as it contains3700 // the size which we already placed with the original symbol,3701 // so don't add it if we want a minimal symbol table3702 add_nlist = false;3703 }3704 }3705 break;3706 3707 case N_STSYM:3708 // static symbol: name,,n_sect,type,address3709 N_STSYM_addr_to_sym_idx.insert(3710 std::make_pair(nlist.n_value, sym_idx));3711 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);3712 if (symbol_name && symbol_name[0]) {3713 type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,3714 eSymbolTypeData);3715 }3716 break;3717 3718 case N_LCSYM:3719 // .lcomm symbol: name,,n_sect,type,address3720 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);3721 type = eSymbolTypeCommonBlock;3722 break;3723 3724 case N_BNSYM:3725 // We use the current number of symbols in the symbol table in lieu3726 // of using nlist_idx in case we ever start trimming entries out3727 // Skip these if we want minimal symbol tables3728 add_nlist = false;3729 break;3730 3731 case N_ENSYM:3732 // Set the size of the N_BNSYM to the terminating index of this3733 // N_ENSYM so that we can always skip the entire symbol if we need3734 // to navigate more quickly at the source level when parsing STABS3735 // Skip these if we want minimal symbol tables3736 add_nlist = false;3737 break;3738 3739 case N_OPT:3740 // emitted with gcc2_compiled and in gcc source3741 type = eSymbolTypeCompiler;3742 break;3743 3744 case N_RSYM:3745 // register sym: name,,NO_SECT,type,register3746 type = eSymbolTypeVariable;3747 break;3748 3749 case N_SLINE:3750 // src line: 0,,n_sect,linenumber,address3751 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);3752 type = eSymbolTypeLineEntry;3753 break;3754 3755 case N_SSYM:3756 // structure elt: name,,NO_SECT,type,struct_offset3757 type = eSymbolTypeVariableType;3758 break;3759 3760 case N_SO:3761 // source file name3762 type = eSymbolTypeSourceFile;3763 if (symbol_name == nullptr) {3764 add_nlist = false;3765 if (N_SO_index != UINT32_MAX) {3766 // Set the size of the N_SO to the terminating index of this3767 // N_SO so that we can always skip the entire N_SO if we need3768 // to navigate more quickly at the source level when parsing3769 // STABS3770 symbol_ptr = symtab.SymbolAtIndex(N_SO_index);3771 symbol_ptr->SetByteSize(sym_idx);3772 symbol_ptr->SetSizeIsSibling(true);3773 }3774 N_NSYM_indexes.clear();3775 N_INCL_indexes.clear();3776 N_BRAC_indexes.clear();3777 N_COMM_indexes.clear();3778 N_FUN_indexes.clear();3779 N_SO_index = UINT32_MAX;3780 } else {3781 // We use the current number of symbols in the symbol table in3782 // lieu of using nlist_idx in case we ever start trimming entries3783 // out3784 const bool N_SO_has_full_path = symbol_name[0] == '/';3785 if (N_SO_has_full_path) {3786 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {3787 // We have two consecutive N_SO entries where the first3788 // contains a directory and the second contains a full path.3789 sym[sym_idx - 1].GetMangled().SetValue(3790 ConstString(symbol_name));3791 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;3792 add_nlist = false;3793 } else {3794 // This is the first entry in a N_SO that contains a3795 // directory or a full path to the source file3796 N_SO_index = sym_idx;3797 }3798 } else if ((N_SO_index == sym_idx - 1) &&3799 ((sym_idx - 1) < num_syms)) {3800 // This is usually the second N_SO entry that contains just the3801 // filename, so here we combine it with the first one if we are3802 // minimizing the symbol table3803 const char *so_path =3804 sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();3805 if (so_path && so_path[0]) {3806 std::string full_so_path(so_path);3807 const size_t double_slash_pos = full_so_path.find("//");3808 if (double_slash_pos != std::string::npos) {3809 // The linker has been generating bad N_SO entries with3810 // doubled up paths in the format "%s%s" where the first3811 // string in the DW_AT_comp_dir, and the second is the3812 // directory for the source file so you end up with a path3813 // that looks like "/tmp/src//tmp/src/"3814 FileSpec so_dir(so_path);3815 if (!FileSystem::Instance().Exists(so_dir)) {3816 so_dir.SetFile(&full_so_path[double_slash_pos + 1],3817 FileSpec::Style::native);3818 if (FileSystem::Instance().Exists(so_dir)) {3819 // Trim off the incorrect path3820 full_so_path.erase(0, double_slash_pos + 1);3821 }3822 }3823 }3824 if (*full_so_path.rbegin() != '/')3825 full_so_path += '/';3826 full_so_path += symbol_name;3827 sym[sym_idx - 1].GetMangled().SetValue(3828 ConstString(full_so_path.c_str()));3829 add_nlist = false;3830 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;3831 }3832 } else {3833 // This could be a relative path to a N_SO3834 N_SO_index = sym_idx;3835 }3836 }3837 break;3838 3839 case N_OSO:3840 // object file name: name,,0,0,st_mtime3841 type = eSymbolTypeObjectFile;3842 break;3843 3844 case N_LSYM:3845 // local sym: name,,NO_SECT,type,offset3846 type = eSymbolTypeLocal;3847 break;3848 3849 // INCL scopes3850 case N_BINCL:3851 // include file beginning: name,,NO_SECT,0,sum We use the current3852 // number of symbols in the symbol table in lieu of using nlist_idx3853 // in case we ever start trimming entries out3854 N_INCL_indexes.push_back(sym_idx);3855 type = eSymbolTypeScopeBegin;3856 break;3857 3858 case N_EINCL:3859 // include file end: name,,NO_SECT,0,03860 // Set the size of the N_BINCL to the terminating index of this3861 // N_EINCL so that we can always skip the entire symbol if we need3862 // to navigate more quickly at the source level when parsing STABS3863 if (!N_INCL_indexes.empty()) {3864 symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());3865 symbol_ptr->SetByteSize(sym_idx + 1);3866 symbol_ptr->SetSizeIsSibling(true);3867 N_INCL_indexes.pop_back();3868 }3869 type = eSymbolTypeScopeEnd;3870 break;3871 3872 case N_SOL:3873 // #included file name: name,,n_sect,0,address3874 type = eSymbolTypeHeaderFile;3875 3876 // We currently don't use the header files on darwin3877 add_nlist = false;3878 break;3879 3880 case N_PARAMS:3881 // compiler parameters: name,,NO_SECT,0,03882 type = eSymbolTypeCompiler;3883 break;3884 3885 case N_VERSION:3886 // compiler version: name,,NO_SECT,0,03887 type = eSymbolTypeCompiler;3888 break;3889 3890 case N_OLEVEL:3891 // compiler -O level: name,,NO_SECT,0,03892 type = eSymbolTypeCompiler;3893 break;3894 3895 case N_PSYM:3896 // parameter: name,,NO_SECT,type,offset3897 type = eSymbolTypeVariable;3898 break;3899 3900 case N_ENTRY:3901 // alternate entry: name,,n_sect,linenumber,address3902 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);3903 type = eSymbolTypeLineEntry;3904 break;3905 3906 // Left and Right Braces3907 case N_LBRAC:3908 // left bracket: 0,,NO_SECT,nesting level,address We use the3909 // current number of symbols in the symbol table in lieu of using3910 // nlist_idx in case we ever start trimming entries out3911 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);3912 N_BRAC_indexes.push_back(sym_idx);3913 type = eSymbolTypeScopeBegin;3914 break;3915 3916 case N_RBRAC:3917 // right bracket: 0,,NO_SECT,nesting level,address Set the size of3918 // the N_LBRAC to the terminating index of this N_RBRAC so that we3919 // can always skip the entire symbol if we need to navigate more3920 // quickly at the source level when parsing STABS3921 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);3922 if (!N_BRAC_indexes.empty()) {3923 symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());3924 symbol_ptr->SetByteSize(sym_idx + 1);3925 symbol_ptr->SetSizeIsSibling(true);3926 N_BRAC_indexes.pop_back();3927 }3928 type = eSymbolTypeScopeEnd;3929 break;3930 3931 case N_EXCL:3932 // deleted include file: name,,NO_SECT,0,sum3933 type = eSymbolTypeHeaderFile;3934 break;3935 3936 // COMM scopes3937 case N_BCOMM:3938 // begin common: name,,NO_SECT,0,03939 // We use the current number of symbols in the symbol table in lieu3940 // of using nlist_idx in case we ever start trimming entries out3941 type = eSymbolTypeScopeBegin;3942 N_COMM_indexes.push_back(sym_idx);3943 break;3944 3945 case N_ECOML:3946 // end common (local name): 0,,n_sect,0,address3947 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);3948 [[fallthrough]];3949 3950 case N_ECOMM:3951 // end common: name,,n_sect,0,03952 // Set the size of the N_BCOMM to the terminating index of this3953 // N_ECOMM/N_ECOML so that we can always skip the entire symbol if3954 // we need to navigate more quickly at the source level when3955 // parsing STABS3956 if (!N_COMM_indexes.empty()) {3957 symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());3958 symbol_ptr->SetByteSize(sym_idx + 1);3959 symbol_ptr->SetSizeIsSibling(true);3960 N_COMM_indexes.pop_back();3961 }3962 type = eSymbolTypeScopeEnd;3963 break;3964 3965 case N_LENG:3966 // second stab entry with length information3967 type = eSymbolTypeAdditional;3968 break;3969 3970 default:3971 break;3972 }3973 } else {3974 uint8_t n_type = N_TYPE & nlist.n_type;3975 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);3976 3977 switch (n_type) {3978 case N_INDR: {3979 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);3980 if (reexport_name_cstr && reexport_name_cstr[0] && symbol_name) {3981 type = eSymbolTypeReExported;3982 ConstString reexport_name(reexport_name_cstr +3983 ((reexport_name_cstr[0] == '_') ? 1 : 0));3984 sym[sym_idx].SetReExportedSymbolName(reexport_name);3985 set_value = false;3986 reexport_shlib_needs_fixup[sym_idx] = reexport_name;3987 indirect_symbol_names.insert(3988 ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));3989 } else3990 type = eSymbolTypeUndefined;3991 } break;3992 3993 case N_UNDF:3994 if (symbol_name && symbol_name[0]) {3995 ConstString undefined_name(symbol_name +3996 ((symbol_name[0] == '_') ? 1 : 0));3997 undefined_name_to_desc[undefined_name] = nlist.n_desc;3998 }3999 [[fallthrough]];4000 4001 case N_PBUD:4002 type = eSymbolTypeUndefined;4003 break;4004 4005 case N_ABS:4006 type = eSymbolTypeAbsolute;4007 break;4008 4009 case N_SECT: {4010 symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);4011 4012 if (!symbol_section) {4013 // TODO: warn about this?4014 add_nlist = false;4015 break;4016 }4017 4018 if (TEXT_eh_frame_sectID == nlist.n_sect) {4019 type = eSymbolTypeException;4020 } else {4021 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;4022 4023 switch (section_type) {4024 case S_CSTRING_LITERALS:4025 type = eSymbolTypeData;4026 break; // section with only literal C strings4027 case S_4BYTE_LITERALS:4028 type = eSymbolTypeData;4029 break; // section with only 4 byte literals4030 case S_8BYTE_LITERALS:4031 type = eSymbolTypeData;4032 break; // section with only 8 byte literals4033 case S_LITERAL_POINTERS:4034 type = eSymbolTypeTrampoline;4035 break; // section with only pointers to literals4036 case S_NON_LAZY_SYMBOL_POINTERS:4037 type = eSymbolTypeTrampoline;4038 break; // section with only non-lazy symbol pointers4039 case S_LAZY_SYMBOL_POINTERS:4040 type = eSymbolTypeTrampoline;4041 break; // section with only lazy symbol pointers4042 case S_SYMBOL_STUBS:4043 type = eSymbolTypeTrampoline;4044 break; // section with only symbol stubs, byte size of stub in4045 // the reserved2 field4046 case S_MOD_INIT_FUNC_POINTERS:4047 type = eSymbolTypeCode;4048 break; // section with only function pointers for initialization4049 case S_MOD_TERM_FUNC_POINTERS:4050 type = eSymbolTypeCode;4051 break; // section with only function pointers for termination4052 case S_INTERPOSING:4053 type = eSymbolTypeTrampoline;4054 break; // section with only pairs of function pointers for4055 // interposing4056 case S_16BYTE_LITERALS:4057 type = eSymbolTypeData;4058 break; // section with only 16 byte literals4059 case S_DTRACE_DOF:4060 type = eSymbolTypeInstrumentation;4061 break;4062 case S_LAZY_DYLIB_SYMBOL_POINTERS:4063 type = eSymbolTypeTrampoline;4064 break;4065 default:4066 switch (symbol_section->GetType()) {4067 case lldb::eSectionTypeCode:4068 type = eSymbolTypeCode;4069 break;4070 case eSectionTypeData:4071 case eSectionTypeDataCString: // Inlined C string data4072 case eSectionTypeDataCStringPointers: // Pointers to C string4073 // data4074 case eSectionTypeDataSymbolAddress: // Address of a symbol in4075 // the symbol table4076 case eSectionTypeData4:4077 case eSectionTypeData8:4078 case eSectionTypeData16:4079 type = eSymbolTypeData;4080 break;4081 default:4082 break;4083 }4084 break;4085 }4086 4087 if (type == eSymbolTypeInvalid) {4088 const char *symbol_sect_name =4089 symbol_section->GetName().AsCString();4090 if (symbol_section->IsDescendant(text_section_sp.get())) {4091 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |4092 S_ATTR_SELF_MODIFYING_CODE |4093 S_ATTR_SOME_INSTRUCTIONS))4094 type = eSymbolTypeData;4095 else4096 type = eSymbolTypeCode;4097 } else if (symbol_section->IsDescendant(data_section_sp.get()) ||4098 symbol_section->IsDescendant(4099 data_dirty_section_sp.get()) ||4100 symbol_section->IsDescendant(4101 data_const_section_sp.get())) {4102 if (symbol_sect_name &&4103 ::strstr(symbol_sect_name, "__objc") == symbol_sect_name) {4104 type = eSymbolTypeRuntime;4105 4106 if (TryParseV2ObjCMetadataSymbol(4107 symbol_name, symbol_name_non_abi_mangled, type))4108 demangled_is_synthesized = true;4109 } else if (symbol_sect_name &&4110 ::strstr(symbol_sect_name, "__gcc_except_tab") ==4111 symbol_sect_name) {4112 type = eSymbolTypeException;4113 } else {4114 type = eSymbolTypeData;4115 }4116 } else if (symbol_sect_name &&4117 ::strstr(symbol_sect_name, "__IMPORT") ==4118 symbol_sect_name) {4119 type = eSymbolTypeTrampoline;4120 } else if (symbol_section->IsDescendant(objc_section_sp.get())) {4121 type = eSymbolTypeRuntime;4122 if (symbol_name && symbol_name[0] == '.') {4123 llvm::StringRef symbol_name_ref(symbol_name);4124 llvm::StringRef g_objc_v1_prefix_class(4125 ".objc_class_name_");4126 if (symbol_name_ref.starts_with(g_objc_v1_prefix_class)) {4127 symbol_name_non_abi_mangled = symbol_name;4128 symbol_name = symbol_name + g_objc_v1_prefix_class.size();4129 type = eSymbolTypeObjCClass;4130 demangled_is_synthesized = true;4131 }4132 }4133 }4134 }4135 }4136 } break;4137 }4138 }4139 4140 if (!add_nlist) {4141 sym[sym_idx].Clear();4142 return true;4143 }4144 4145 uint64_t symbol_value = nlist.n_value;4146 4147 if (symbol_name_non_abi_mangled) {4148 sym[sym_idx].GetMangled().SetMangledName(4149 ConstString(symbol_name_non_abi_mangled));4150 sym[sym_idx].GetMangled().SetDemangledName(ConstString(symbol_name));4151 } else {4152 4153 if (symbol_name && symbol_name[0] == '_') {4154 symbol_name++; // Skip the leading underscore4155 }4156 4157 if (symbol_name) {4158 ConstString const_symbol_name(symbol_name);4159 sym[sym_idx].GetMangled().SetValue(const_symbol_name);4160 }4161 }4162 4163 if (is_gsym) {4164 const char *gsym_name = sym[sym_idx]4165 .GetMangled()4166 .GetName(Mangled::ePreferMangled)4167 .GetCString();4168 if (gsym_name)4169 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;4170 }4171 4172 if (symbol_section) {4173 const addr_t section_file_addr = symbol_section->GetFileAddress();4174 symbol_value -= section_file_addr;4175 }4176 4177 if (!is_debug) {4178 if (type == eSymbolTypeCode) {4179 // See if we can find a N_FUN entry for any code symbols. If we do4180 // find a match, and the name matches, then we can merge the two into4181 // just the function symbol to avoid duplicate entries in the symbol4182 // table.4183 std::pair<ValueToSymbolIndexMap::const_iterator,4184 ValueToSymbolIndexMap::const_iterator>4185 range;4186 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);4187 if (range.first != range.second) {4188 for (ValueToSymbolIndexMap::const_iterator pos = range.first;4189 pos != range.second; ++pos) {4190 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==4191 sym[pos->second].GetMangled().GetName(4192 Mangled::ePreferMangled)) {4193 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;4194 // We just need the flags from the linker symbol, so put these4195 // flags into the N_FUN flags to avoid duplicate symbols in the4196 // symbol table.4197 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());4198 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);4199 if (resolver_addresses.find(nlist.n_value) !=4200 resolver_addresses.end())4201 sym[pos->second].SetType(eSymbolTypeResolver);4202 sym[sym_idx].Clear();4203 return true;4204 }4205 }4206 } else {4207 if (resolver_addresses.find(nlist.n_value) !=4208 resolver_addresses.end())4209 type = eSymbolTypeResolver;4210 }4211 } else if (type == eSymbolTypeData || type == eSymbolTypeObjCClass ||4212 type == eSymbolTypeObjCMetaClass ||4213 type == eSymbolTypeObjCIVar) {4214 // See if we can find a N_STSYM entry for any data symbols. If we do4215 // find a match, and the name matches, then we can merge the two into4216 // just the Static symbol to avoid duplicate entries in the symbol4217 // table.4218 std::pair<ValueToSymbolIndexMap::const_iterator,4219 ValueToSymbolIndexMap::const_iterator>4220 range;4221 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);4222 if (range.first != range.second) {4223 for (ValueToSymbolIndexMap::const_iterator pos = range.first;4224 pos != range.second; ++pos) {4225 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) ==4226 sym[pos->second].GetMangled().GetName(4227 Mangled::ePreferMangled)) {4228 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;4229 // We just need the flags from the linker symbol, so put these4230 // flags into the N_STSYM flags to avoid duplicate symbols in4231 // the symbol table.4232 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());4233 sym[pos->second].SetFlags(nlist.n_type << 16 | nlist.n_desc);4234 sym[sym_idx].Clear();4235 return true;4236 }4237 }4238 } else {4239 // Combine N_GSYM stab entries with the non stab symbol.4240 const char *gsym_name = sym[sym_idx]4241 .GetMangled()4242 .GetName(Mangled::ePreferMangled)4243 .GetCString();4244 if (gsym_name) {4245 ConstNameToSymbolIndexMap::const_iterator pos =4246 N_GSYM_name_to_sym_idx.find(gsym_name);4247 if (pos != N_GSYM_name_to_sym_idx.end()) {4248 const uint32_t GSYM_sym_idx = pos->second;4249 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;4250 // Copy the address, because often the N_GSYM address has an4251 // invalid address of zero when the global is a common symbol.4252 sym[GSYM_sym_idx].GetAddressRef().SetSection(symbol_section);4253 sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value);4254 add_symbol_addr(4255 sym[GSYM_sym_idx].GetAddress().GetFileAddress());4256 // We just need the flags from the linker symbol, so put these4257 // flags into the N_GSYM flags to avoid duplicate symbols in4258 // the symbol table.4259 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);4260 sym[sym_idx].Clear();4261 return true;4262 }4263 }4264 }4265 }4266 }4267 4268 sym[sym_idx].SetID(nlist_idx);4269 sym[sym_idx].SetType(type);4270 if (set_value) {4271 sym[sym_idx].GetAddressRef().SetSection(symbol_section);4272 sym[sym_idx].GetAddressRef().SetOffset(symbol_value);4273 if (symbol_section)4274 add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());4275 }4276 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);4277 if (nlist.n_desc & N_WEAK_REF)4278 sym[sym_idx].SetIsWeak(true);4279 4280 if (demangled_is_synthesized)4281 sym[sym_idx].SetDemangledNameIsSynthesized(true);4282 4283 ++sym_idx;4284 return true;4285 };4286 4287 // First parse all the nlists but don't process them yet. See the next4288 // comment for an explanation why.4289 std::vector<struct nlist_64> nlists;4290 nlists.reserve(symtab_load_command.nsyms);4291 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {4292 if (auto nlist =4293 ParseNList(nlist_data, nlist_data_offset, nlist_byte_size))4294 nlists.push_back(*nlist);4295 else4296 break;4297 }4298 4299 // Now parse all the debug symbols. This is needed to merge non-debug4300 // symbols in the next step. Non-debug symbols are always coalesced into4301 // the debug symbol. Doing this in one step would mean that some symbols4302 // won't be merged.4303 nlist_idx = 0;4304 for (auto &nlist : nlists) {4305 if (!ParseSymbolLambda(nlist, nlist_idx++, DebugSymbols))4306 break;4307 }4308 4309 // Finally parse all the non debug symbols.4310 nlist_idx = 0;4311 for (auto &nlist : nlists) {4312 if (!ParseSymbolLambda(nlist, nlist_idx++, NonDebugSymbols))4313 break;4314 }4315 4316 for (const auto &pos : reexport_shlib_needs_fixup) {4317 const auto undef_pos = undefined_name_to_desc.find(pos.second);4318 if (undef_pos != undefined_name_to_desc.end()) {4319 const uint8_t dylib_ordinal =4320 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);4321 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())4322 sym[pos.first].SetReExportedSymbolSharedLibrary(4323 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));4324 }4325 }4326 }4327 4328 // Count how many trie symbols we'll add to the symbol table4329 int trie_symbol_table_augment_count = 0;4330 for (auto &e : external_sym_trie_entries) {4331 if (!symbols_added.contains(e.entry.address))4332 trie_symbol_table_augment_count++;4333 }4334 4335 if (num_syms < sym_idx + trie_symbol_table_augment_count) {4336 num_syms = sym_idx + trie_symbol_table_augment_count;4337 sym = symtab.Resize(num_syms);4338 }4339 uint32_t synthetic_sym_id = symtab_load_command.nsyms;4340 4341 // Add symbols from the trie to the symbol table.4342 for (auto &e : external_sym_trie_entries) {4343 if (symbols_added.contains(e.entry.address))4344 continue;4345 4346 // Find the section that this trie address is in, use that to annotate4347 // symbol type as we add the trie address and name to the symbol table.4348 Address symbol_addr;4349 if (module_sp->ResolveFileAddress(e.entry.address, symbol_addr)) {4350 SectionSP symbol_section(symbol_addr.GetSection());4351 const char *symbol_name = e.entry.name.GetCString();4352 bool demangled_is_synthesized = false;4353 SymbolType type =4354 GetSymbolType(symbol_name, demangled_is_synthesized, text_section_sp,4355 data_section_sp, data_dirty_section_sp,4356 data_const_section_sp, symbol_section);4357 4358 sym[sym_idx].SetType(type);4359 if (symbol_section) {4360 sym[sym_idx].SetID(synthetic_sym_id++);4361 sym[sym_idx].GetMangled().SetMangledName(ConstString(symbol_name));4362 if (demangled_is_synthesized)4363 sym[sym_idx].SetDemangledNameIsSynthesized(true);4364 sym[sym_idx].SetIsSynthetic(true);4365 sym[sym_idx].SetExternal(true);4366 sym[sym_idx].GetAddressRef() = symbol_addr;4367 add_symbol_addr(symbol_addr.GetFileAddress());4368 if (e.entry.flags & TRIE_SYMBOL_IS_THUMB)4369 sym[sym_idx].SetFlags(MACHO_NLIST_ARM_SYMBOL_IS_THUMB);4370 ++sym_idx;4371 }4372 }4373 }4374 4375 if (function_starts_count > 0) {4376 uint32_t num_synthetic_function_symbols = 0;4377 for (i = 0; i < function_starts_count; ++i) {4378 if (!symbols_added.contains(function_starts.GetEntryRef(i).addr))4379 ++num_synthetic_function_symbols;4380 }4381 4382 if (num_synthetic_function_symbols > 0) {4383 if (num_syms < sym_idx + num_synthetic_function_symbols) {4384 num_syms = sym_idx + num_synthetic_function_symbols;4385 sym = symtab.Resize(num_syms);4386 }4387 for (i = 0; i < function_starts_count; ++i) {4388 const FunctionStarts::Entry *func_start_entry =4389 function_starts.GetEntryAtIndex(i);4390 if (!symbols_added.contains(func_start_entry->addr)) {4391 addr_t symbol_file_addr = func_start_entry->addr;4392 uint32_t symbol_flags = 0;4393 if (func_start_entry->data)4394 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;4395 Address symbol_addr;4396 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {4397 SectionSP symbol_section(symbol_addr.GetSection());4398 if (symbol_section) {4399 sym[sym_idx].SetID(synthetic_sym_id++);4400 // Don't set the name for any synthetic symbols, the Symbol4401 // object will generate one if needed when the name is accessed4402 // via accessors.4403 sym[sym_idx].GetMangled().SetDemangledName(ConstString());4404 sym[sym_idx].SetType(eSymbolTypeCode);4405 sym[sym_idx].SetIsSynthetic(true);4406 sym[sym_idx].GetAddressRef() = symbol_addr;4407 add_symbol_addr(symbol_addr.GetFileAddress());4408 if (symbol_flags)4409 sym[sym_idx].SetFlags(symbol_flags);4410 ++sym_idx;4411 }4412 }4413 }4414 }4415 }4416 }4417 4418 // Trim our symbols down to just what we ended up with after removing any4419 // symbols.4420 if (sym_idx < num_syms) {4421 num_syms = sym_idx;4422 sym = symtab.Resize(num_syms);4423 }4424 4425 // Now synthesize indirect symbols4426 if (m_dysymtab.nindirectsyms != 0) {4427 if (indirect_symbol_index_data.GetByteSize()) {4428 NListIndexToSymbolIndexMap::const_iterator end_index_pos =4429 m_nlist_idx_to_sym_idx.end();4430 4431 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();4432 ++sect_idx) {4433 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==4434 S_SYMBOL_STUBS) {4435 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;4436 if (symbol_stub_byte_size == 0)4437 continue;4438 4439 const uint32_t num_symbol_stubs =4440 m_mach_sections[sect_idx].size / symbol_stub_byte_size;4441 4442 if (num_symbol_stubs == 0)4443 continue;4444 4445 const uint32_t symbol_stub_index_offset =4446 m_mach_sections[sect_idx].reserved1;4447 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {4448 const uint32_t symbol_stub_index =4449 symbol_stub_index_offset + stub_idx;4450 const lldb::addr_t symbol_stub_addr =4451 m_mach_sections[sect_idx].addr +4452 (stub_idx * symbol_stub_byte_size);4453 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;4454 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(4455 symbol_stub_offset, 4)) {4456 const uint32_t stub_sym_id =4457 indirect_symbol_index_data.GetU32(&symbol_stub_offset);4458 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))4459 continue;4460 4461 NListIndexToSymbolIndexMap::const_iterator index_pos =4462 m_nlist_idx_to_sym_idx.find(stub_sym_id);4463 Symbol *stub_symbol = nullptr;4464 if (index_pos != end_index_pos) {4465 // We have a remapping from the original nlist index to a4466 // current symbol index, so just look this up by index4467 stub_symbol = symtab.SymbolAtIndex(index_pos->second);4468 } else {4469 // We need to lookup a symbol using the original nlist symbol4470 // index since this index is coming from the S_SYMBOL_STUBS4471 stub_symbol = symtab.FindSymbolByID(stub_sym_id);4472 }4473 4474 if (stub_symbol) {4475 Address so_addr(symbol_stub_addr, section_list);4476 4477 if (stub_symbol->GetType() == eSymbolTypeUndefined) {4478 // Change the external symbol into a trampoline that makes4479 // sense These symbols were N_UNDF N_EXT, and are useless4480 // to us, so we can re-use them so we don't have to make up4481 // a synthetic symbol for no good reason.4482 if (resolver_addresses.find(symbol_stub_addr) ==4483 resolver_addresses.end())4484 stub_symbol->SetType(eSymbolTypeTrampoline);4485 else4486 stub_symbol->SetType(eSymbolTypeResolver);4487 stub_symbol->SetExternal(false);4488 stub_symbol->GetAddressRef() = so_addr;4489 stub_symbol->SetByteSize(symbol_stub_byte_size);4490 } else {4491 // Make a synthetic symbol to describe the trampoline stub4492 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());4493 if (sym_idx >= num_syms) {4494 sym = symtab.Resize(++num_syms);4495 stub_symbol = nullptr; // this pointer no longer valid4496 }4497 sym[sym_idx].SetID(synthetic_sym_id++);4498 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;4499 if (resolver_addresses.find(symbol_stub_addr) ==4500 resolver_addresses.end())4501 sym[sym_idx].SetType(eSymbolTypeTrampoline);4502 else4503 sym[sym_idx].SetType(eSymbolTypeResolver);4504 sym[sym_idx].SetIsSynthetic(true);4505 sym[sym_idx].GetAddressRef() = so_addr;4506 add_symbol_addr(so_addr.GetFileAddress());4507 sym[sym_idx].SetByteSize(symbol_stub_byte_size);4508 ++sym_idx;4509 }4510 } else {4511 if (log)4512 log->Warning("symbol stub referencing symbol table symbol "4513 "%u that isn't in our minimal symbol table, "4514 "fix this!!!",4515 stub_sym_id);4516 }4517 }4518 }4519 }4520 }4521 }4522 }4523 4524 if (!reexport_trie_entries.empty()) {4525 for (const auto &e : reexport_trie_entries) {4526 if (e.entry.import_name) {4527 // Only add indirect symbols from the Trie entries if we didn't have4528 // a N_INDR nlist entry for this already4529 if (indirect_symbol_names.find(e.entry.name) ==4530 indirect_symbol_names.end()) {4531 // Make a synthetic symbol to describe re-exported symbol.4532 if (sym_idx >= num_syms)4533 sym = symtab.Resize(++num_syms);4534 sym[sym_idx].SetID(synthetic_sym_id++);4535 sym[sym_idx].GetMangled() = Mangled(e.entry.name);4536 sym[sym_idx].SetType(eSymbolTypeReExported);4537 sym[sym_idx].SetIsSynthetic(true);4538 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);4539 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {4540 sym[sym_idx].SetReExportedSymbolSharedLibrary(4541 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));4542 }4543 ++sym_idx;4544 }4545 }4546 }4547 }4548}4549 4550void ObjectFileMachO::Dump(Stream *s) {4551 ModuleSP module_sp(GetModule());4552 if (module_sp) {4553 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());4554 s->Printf("%p: ", static_cast<void *>(this));4555 s->Indent();4556 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)4557 s->PutCString("ObjectFileMachO64");4558 else4559 s->PutCString("ObjectFileMachO32");4560 4561 *s << ", file = '" << m_file;4562 ModuleSpecList all_specs;4563 ModuleSpec base_spec;4564 GetAllArchSpecs(m_header, m_data, MachHeaderSizeFromMagic(m_header.magic),4565 base_spec, all_specs);4566 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {4567 *s << "', triple";4568 if (e)4569 s->Printf("[%d]", i);4570 *s << " = ";4571 *s << all_specs.GetModuleSpecRefAtIndex(i)4572 .GetArchitecture()4573 .GetTriple()4574 .getTriple();4575 }4576 *s << "\n";4577 SectionList *sections = GetSectionList();4578 if (sections)4579 sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,4580 UINT32_MAX);4581 4582 if (m_symtab_up)4583 m_symtab_up->Dump(s, nullptr, eSortOrderNone);4584 }4585}4586 4587UUID ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,4588 const lldb_private::DataExtractor &data,4589 lldb::offset_t lc_offset) {4590 uint32_t i;4591 llvm::MachO::uuid_command load_cmd;4592 4593 lldb::offset_t offset = lc_offset;4594 for (i = 0; i < header.ncmds; ++i) {4595 const lldb::offset_t cmd_offset = offset;4596 if (data.GetU32(&offset, &load_cmd, 2) == nullptr)4597 break;4598 4599 if (load_cmd.cmd == LC_UUID) {4600 const uint8_t *uuid_bytes = data.PeekData(offset, 16);4601 4602 if (uuid_bytes) {4603 // OpenCL on Mac OS X uses the same UUID for each of its object files.4604 // We pretend these object files have no UUID to prevent crashing.4605 4606 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,4607 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,4608 0xbb, 0x14, 0xf0, 0x0d};4609 4610 if (!memcmp(uuid_bytes, opencl_uuid, 16))4611 return UUID();4612 4613 return UUID(uuid_bytes, 16);4614 }4615 return UUID();4616 }4617 offset = cmd_offset + load_cmd.cmdsize;4618 }4619 return UUID();4620}4621 4622static llvm::StringRef GetOSName(uint32_t cmd) {4623 switch (cmd) {4624 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:4625 return llvm::Triple::getOSTypeName(llvm::Triple::IOS);4626 case llvm::MachO::LC_VERSION_MIN_MACOSX:4627 return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);4628 case llvm::MachO::LC_VERSION_MIN_TVOS:4629 return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);4630 case llvm::MachO::LC_VERSION_MIN_WATCHOS:4631 return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);4632 default:4633 llvm_unreachable("unexpected LC_VERSION load command");4634 }4635}4636 4637namespace {4638struct OSEnv {4639 llvm::StringRef os_type;4640 llvm::StringRef environment;4641 OSEnv(uint32_t cmd) {4642 switch (cmd) {4643 case llvm::MachO::PLATFORM_MACOS:4644 os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);4645 return;4646 case llvm::MachO::PLATFORM_IOS:4647 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);4648 return;4649 case llvm::MachO::PLATFORM_TVOS:4650 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);4651 return;4652 case llvm::MachO::PLATFORM_WATCHOS:4653 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);4654 return;4655 case llvm::MachO::PLATFORM_BRIDGEOS:4656 os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);4657 return;4658 case llvm::MachO::PLATFORM_DRIVERKIT:4659 os_type = llvm::Triple::getOSTypeName(llvm::Triple::DriverKit);4660 return;4661 case llvm::MachO::PLATFORM_MACCATALYST:4662 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);4663 environment = llvm::Triple::getEnvironmentTypeName(llvm::Triple::MacABI);4664 return;4665 case llvm::MachO::PLATFORM_IOSSIMULATOR:4666 os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);4667 environment =4668 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);4669 return;4670 case llvm::MachO::PLATFORM_TVOSSIMULATOR:4671 os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);4672 environment =4673 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);4674 return;4675 case llvm::MachO::PLATFORM_WATCHOSSIMULATOR:4676 os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);4677 environment =4678 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);4679 return;4680 case llvm::MachO::PLATFORM_XROS:4681 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);4682 return;4683 case llvm::MachO::PLATFORM_XROS_SIMULATOR:4684 os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);4685 environment =4686 llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);4687 return;4688 default: {4689 Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));4690 LLDB_LOGF(log, "unsupported platform in LC_BUILD_VERSION");4691 }4692 }4693 }4694};4695 4696struct MinOS {4697 uint32_t major_version, minor_version, patch_version;4698 MinOS(uint32_t version)4699 : major_version(version >> 16), minor_version((version >> 8) & 0xffu),4700 patch_version(version & 0xffu) {}4701};4702} // namespace4703 4704void ObjectFileMachO::GetAllArchSpecs(const llvm::MachO::mach_header &header,4705 const lldb_private::DataExtractor &data,4706 lldb::offset_t lc_offset,4707 ModuleSpec &base_spec,4708 lldb_private::ModuleSpecList &all_specs) {4709 auto &base_arch = base_spec.GetArchitecture();4710 base_arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);4711 if (!base_arch.IsValid())4712 return;4713 4714 bool found_any = false;4715 auto add_triple = [&](const llvm::Triple &triple) {4716 auto spec = base_spec;4717 spec.GetArchitecture().GetTriple() = triple;4718 if (spec.GetArchitecture().IsValid()) {4719 spec.GetUUID() = ObjectFileMachO::GetUUID(header, data, lc_offset);4720 all_specs.Append(spec);4721 found_any = true;4722 }4723 };4724 4725 // Set OS to an unspecified unknown or a "*" so it can match any OS4726 llvm::Triple base_triple = base_arch.GetTriple();4727 base_triple.setOS(llvm::Triple::UnknownOS);4728 base_triple.setOSName(llvm::StringRef());4729 4730 if (header.filetype == MH_PRELOAD) {4731 if (header.cputype == CPU_TYPE_ARM) {4732 // If this is a 32-bit arm binary, and it's a standalone binary, force4733 // the Vendor to Apple so we don't accidentally pick up the generic4734 // armv7 ABI at runtime. Apple's armv7 ABI always uses r7 for the4735 // frame pointer register; most other armv7 ABIs use a combination of4736 // r7 and r11.4737 base_triple.setVendor(llvm::Triple::Apple);4738 } else {4739 // Set vendor to an unspecified unknown or a "*" so it can match any4740 // vendor This is required for correct behavior of EFI debugging on4741 // x86_644742 base_triple.setVendor(llvm::Triple::UnknownVendor);4743 base_triple.setVendorName(llvm::StringRef());4744 }4745 return add_triple(base_triple);4746 }4747 4748 llvm::MachO::load_command load_cmd;4749 4750 // See if there is an LC_VERSION_MIN_* load command that can give4751 // us the OS type.4752 lldb::offset_t offset = lc_offset;4753 for (uint32_t i = 0; i < header.ncmds; ++i) {4754 const lldb::offset_t cmd_offset = offset;4755 if (data.GetU32(&offset, &load_cmd, 2) == nullptr)4756 break;4757 4758 llvm::MachO::version_min_command version_min;4759 switch (load_cmd.cmd) {4760 case llvm::MachO::LC_VERSION_MIN_MACOSX:4761 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:4762 case llvm::MachO::LC_VERSION_MIN_TVOS:4763 case llvm::MachO::LC_VERSION_MIN_WATCHOS: {4764 if (load_cmd.cmdsize != sizeof(version_min))4765 break;4766 if (data.ExtractBytes(cmd_offset, sizeof(version_min),4767 data.GetByteOrder(), &version_min) == 0)4768 break;4769 MinOS min_os(version_min.version);4770 llvm::SmallString<32> os_name;4771 llvm::raw_svector_ostream os(os_name);4772 os << GetOSName(load_cmd.cmd) << min_os.major_version << '.'4773 << min_os.minor_version << '.' << min_os.patch_version;4774 4775 auto triple = base_triple;4776 triple.setOSName(os.str());4777 4778 // Disambiguate legacy simulator platforms.4779 if (load_cmd.cmd != llvm::MachO::LC_VERSION_MIN_MACOSX &&4780 (base_triple.getArch() == llvm::Triple::x86_64 ||4781 base_triple.getArch() == llvm::Triple::x86)) {4782 // The combination of legacy LC_VERSION_MIN load command and4783 // x86 architecture always indicates a simulator environment.4784 // The combination of LC_VERSION_MIN and arm architecture only4785 // appears for native binaries. Back-deploying simulator4786 // binaries on Apple Silicon Macs use the modern unambigous4787 // LC_BUILD_VERSION load commands; no special handling required.4788 triple.setEnvironment(llvm::Triple::Simulator);4789 }4790 add_triple(triple);4791 break;4792 }4793 default:4794 break;4795 }4796 4797 offset = cmd_offset + load_cmd.cmdsize;4798 }4799 4800 // See if there are LC_BUILD_VERSION load commands that can give4801 // us the OS type.4802 offset = lc_offset;4803 for (uint32_t i = 0; i < header.ncmds; ++i) {4804 const lldb::offset_t cmd_offset = offset;4805 if (data.GetU32(&offset, &load_cmd, 2) == nullptr)4806 break;4807 4808 do {4809 if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {4810 llvm::MachO::build_version_command build_version;4811 if (load_cmd.cmdsize < sizeof(build_version)) {4812 // Malformed load command.4813 break;4814 }4815 if (data.ExtractBytes(cmd_offset, sizeof(build_version),4816 data.GetByteOrder(), &build_version) == 0)4817 break;4818 MinOS min_os(build_version.minos);4819 OSEnv os_env(build_version.platform);4820 llvm::SmallString<16> os_name;4821 llvm::raw_svector_ostream os(os_name);4822 os << os_env.os_type << min_os.major_version << '.'4823 << min_os.minor_version << '.' << min_os.patch_version;4824 auto triple = base_triple;4825 triple.setOSName(os.str());4826 os_name.clear();4827 if (!os_env.environment.empty())4828 triple.setEnvironmentName(os_env.environment);4829 add_triple(triple);4830 }4831 } while (false);4832 offset = cmd_offset + load_cmd.cmdsize;4833 }4834 4835 if (!found_any) {4836 add_triple(base_triple);4837 }4838}4839 4840ArchSpec ObjectFileMachO::GetArchitecture(4841 ModuleSP module_sp, const llvm::MachO::mach_header &header,4842 const lldb_private::DataExtractor &data, lldb::offset_t lc_offset) {4843 ModuleSpecList all_specs;4844 ModuleSpec base_spec;4845 GetAllArchSpecs(header, data, MachHeaderSizeFromMagic(header.magic),4846 base_spec, all_specs);4847 4848 // If the object file offers multiple alternative load commands,4849 // pick the one that matches the module.4850 if (module_sp) {4851 const ArchSpec &module_arch = module_sp->GetArchitecture();4852 for (unsigned i = 0, e = all_specs.GetSize(); i != e; ++i) {4853 ArchSpec mach_arch =4854 all_specs.GetModuleSpecRefAtIndex(i).GetArchitecture();4855 if (module_arch.IsCompatibleMatch(mach_arch))4856 return mach_arch;4857 }4858 }4859 4860 // Return the first arch we found.4861 if (all_specs.GetSize() == 0)4862 return {};4863 return all_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();4864}4865 4866UUID ObjectFileMachO::GetUUID() {4867 ModuleSP module_sp(GetModule());4868 if (module_sp) {4869 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());4870 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);4871 return GetUUID(m_header, m_data, offset);4872 }4873 return UUID();4874}4875 4876uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {4877 ModuleSP module_sp = GetModule();4878 if (!module_sp)4879 return 0;4880 4881 uint32_t count = 0;4882 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());4883 llvm::MachO::load_command load_cmd;4884 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);4885 std::vector<std::string> rpath_paths;4886 std::vector<std::string> rpath_relative_paths;4887 std::vector<std::string> at_exec_relative_paths;4888 uint32_t i;4889 for (i = 0; i < m_header.ncmds; ++i) {4890 const uint32_t cmd_offset = offset;4891 if (m_data.GetU32(&offset, &load_cmd, 2) == nullptr)4892 break;4893 4894 switch (load_cmd.cmd) {4895 case LC_RPATH:4896 case LC_LOAD_DYLIB:4897 case LC_LOAD_WEAK_DYLIB:4898 case LC_REEXPORT_DYLIB:4899 case LC_LOAD_DYLINKER:4900 case LC_LOADFVMLIB:4901 case LC_LOAD_UPWARD_DYLIB: {4902 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);4903 // For LC_LOAD_DYLIB there is an alternate encoding4904 // which adds a uint32_t `flags` field for `DYLD_USE_*`4905 // flags. This can be detected by a timestamp field with4906 // the `DYLIB_USE_MARKER` constant value.4907 bool is_delayed_init = false;4908 uint32_t use_command_marker = m_data.GetU32(&offset);4909 if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */) {4910 offset += 4; /* uint32_t current_version */4911 offset += 4; /* uint32_t compat_version */4912 uint32_t flags = m_data.GetU32(&offset);4913 // If this LC_LOAD_DYLIB is marked delay-init,4914 // don't report it as a dependent library -- it4915 // may be loaded in the process at some point,4916 // but will most likely not be load at launch.4917 if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */)4918 is_delayed_init = true;4919 }4920 const char *path = m_data.PeekCStr(name_offset);4921 if (path && !is_delayed_init) {4922 if (load_cmd.cmd == LC_RPATH)4923 rpath_paths.push_back(path);4924 else {4925 if (path[0] == '@') {4926 if (strncmp(path, "@rpath", strlen("@rpath")) == 0)4927 rpath_relative_paths.push_back(path + strlen("@rpath"));4928 else if (strncmp(path, "@executable_path",4929 strlen("@executable_path")) == 0)4930 at_exec_relative_paths.push_back(path +4931 strlen("@executable_path"));4932 } else {4933 FileSpec file_spec(path);4934 if (files.AppendIfUnique(file_spec))4935 count++;4936 }4937 }4938 }4939 } break;4940 4941 default:4942 break;4943 }4944 offset = cmd_offset + load_cmd.cmdsize;4945 }4946 4947 FileSpec this_file_spec(m_file);4948 FileSystem::Instance().Resolve(this_file_spec);4949 4950 if (!rpath_paths.empty()) {4951 // Fixup all LC_RPATH values to be absolute paths.4952 const std::string this_directory =4953 this_file_spec.GetDirectory().GetString();4954 for (auto &rpath : rpath_paths) {4955 if (llvm::StringRef(rpath).starts_with(g_loader_path))4956 rpath = this_directory + rpath.substr(g_loader_path.size());4957 else if (llvm::StringRef(rpath).starts_with(g_executable_path))4958 rpath = this_directory + rpath.substr(g_executable_path.size());4959 }4960 4961 for (const auto &rpath_relative_path : rpath_relative_paths) {4962 for (const auto &rpath : rpath_paths) {4963 std::string path = rpath;4964 path += rpath_relative_path;4965 // It is OK to resolve this path because we must find a file on disk4966 // for us to accept it anyway if it is rpath relative.4967 FileSpec file_spec(path);4968 FileSystem::Instance().Resolve(file_spec);4969 if (FileSystem::Instance().Exists(file_spec) &&4970 files.AppendIfUnique(file_spec)) {4971 count++;4972 break;4973 }4974 }4975 }4976 }4977 4978 // We may have @executable_paths but no RPATHS. Figure those out here.4979 // Only do this if this object file is the executable. We have no way to4980 // get back to the actual executable otherwise, so we won't get the right4981 // path.4982 if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) {4983 FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent();4984 for (const auto &at_exec_relative_path : at_exec_relative_paths) {4985 FileSpec file_spec =4986 exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);4987 if (FileSystem::Instance().Exists(file_spec) &&4988 files.AppendIfUnique(file_spec))4989 count++;4990 }4991 }4992 return count;4993}4994 4995lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {4996 // If the object file is not an executable it can't hold the entry point.4997 // m_entry_point_address is initialized to an invalid address, so we can just4998 // return that. If m_entry_point_address is valid it means we've found it4999 // already, so return the cached value.5000 5001 if ((!IsExecutable() && !IsDynamicLoader()) ||5002 m_entry_point_address.IsValid()) {5003 return m_entry_point_address;5004 }5005 5006 // Otherwise, look for the UnixThread or Thread command. The data for the5007 // Thread command is given in /usr/include/mach-o.h, but it is basically:5008 //5009 // uint32_t flavor - this is the flavor argument you would pass to5010 // thread_get_state5011 // uint32_t count - this is the count of longs in the thread state data5012 // struct XXX_thread_state state - this is the structure from5013 // <machine/thread_status.h> corresponding to the flavor.5014 // <repeat this trio>5015 //5016 // So we just keep reading the various register flavors till we find the GPR5017 // one, then read the PC out of there.5018 // FIXME: We will need to have a "RegisterContext data provider" class at some5019 // point that can get all the registers5020 // out of data in this form & attach them to a given thread. That should5021 // underlie the MacOS X User process plugin, and we'll also need it for the5022 // MacOS X Core File process plugin. When we have that we can also use it5023 // here.5024 //5025 // For now we hard-code the offsets and flavors we need:5026 //5027 //5028 5029 ModuleSP module_sp(GetModule());5030 if (module_sp) {5031 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5032 llvm::MachO::load_command load_cmd;5033 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);5034 uint32_t i;5035 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;5036 bool done = false;5037 5038 for (i = 0; i < m_header.ncmds; ++i) {5039 const lldb::offset_t cmd_offset = offset;5040 if (m_data.GetU32(&offset, &load_cmd, 2) == nullptr)5041 break;5042 5043 switch (load_cmd.cmd) {5044 case LC_UNIXTHREAD:5045 case LC_THREAD: {5046 while (offset < cmd_offset + load_cmd.cmdsize) {5047 uint32_t flavor = m_data.GetU32(&offset);5048 uint32_t count = m_data.GetU32(&offset);5049 if (count == 0) {5050 // We've gotten off somehow, log and exit;5051 return m_entry_point_address;5052 }5053 5054 switch (m_header.cputype) {5055 case llvm::MachO::CPU_TYPE_ARM:5056 if (flavor == 1 ||5057 flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE325058 // from mach/arm/thread_status.h5059 {5060 offset += 60; // This is the offset of pc in the GPR thread state5061 // data structure.5062 start_address = m_data.GetU32(&offset);5063 done = true;5064 }5065 break;5066 case llvm::MachO::CPU_TYPE_ARM64:5067 case llvm::MachO::CPU_TYPE_ARM64_32:5068 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h5069 {5070 offset += 256; // This is the offset of pc in the GPR thread state5071 // data structure.5072 start_address = m_data.GetU64(&offset);5073 done = true;5074 }5075 break;5076 case llvm::MachO::CPU_TYPE_X86_64:5077 if (flavor ==5078 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h5079 {5080 offset += 16 * 8; // This is the offset of rip in the GPR thread5081 // state data structure.5082 start_address = m_data.GetU64(&offset);5083 done = true;5084 }5085 break;5086 default:5087 return m_entry_point_address;5088 }5089 // Haven't found the GPR flavor yet, skip over the data for this5090 // flavor:5091 if (done)5092 break;5093 offset += count * 4;5094 }5095 } break;5096 case LC_MAIN: {5097 uint64_t entryoffset = m_data.GetU64(&offset);5098 SectionSP text_segment_sp =5099 GetSectionList()->FindSectionByName(GetSegmentNameTEXT());5100 if (text_segment_sp) {5101 done = true;5102 start_address = text_segment_sp->GetFileAddress() + entryoffset;5103 }5104 } break;5105 5106 default:5107 break;5108 }5109 if (done)5110 break;5111 5112 // Go to the next load command:5113 offset = cmd_offset + load_cmd.cmdsize;5114 }5115 5116 if (start_address == LLDB_INVALID_ADDRESS && IsDynamicLoader()) {5117 if (GetSymtab()) {5118 Symbol *dyld_start_sym = GetSymtab()->FindFirstSymbolWithNameAndType(5119 ConstString("_dyld_start"), SymbolType::eSymbolTypeCode,5120 Symtab::eDebugAny, Symtab::eVisibilityAny);5121 if (dyld_start_sym && dyld_start_sym->GetAddress().IsValid()) {5122 start_address = dyld_start_sym->GetAddress().GetFileAddress();5123 }5124 }5125 }5126 5127 if (start_address != LLDB_INVALID_ADDRESS) {5128 // We got the start address from the load commands, so now resolve that5129 // address in the sections of this ObjectFile:5130 if (!m_entry_point_address.ResolveAddressUsingFileSections(5131 start_address, GetSectionList())) {5132 m_entry_point_address.Clear();5133 }5134 } else {5135 // We couldn't read the UnixThread load command - maybe it wasn't there.5136 // As a fallback look for the "start" symbol in the main executable.5137 5138 ModuleSP module_sp(GetModule());5139 5140 if (module_sp) {5141 SymbolContextList contexts;5142 SymbolContext context;5143 module_sp->FindSymbolsWithNameAndType(ConstString("start"),5144 eSymbolTypeCode, contexts);5145 if (contexts.GetSize()) {5146 if (contexts.GetContextAtIndex(0, context))5147 m_entry_point_address = context.symbol->GetAddress();5148 }5149 }5150 }5151 }5152 5153 return m_entry_point_address;5154}5155 5156lldb_private::Address ObjectFileMachO::GetBaseAddress() {5157 lldb_private::Address header_addr;5158 SectionList *section_list = GetSectionList();5159 if (section_list) {5160 SectionSP text_segment_sp(5161 section_list->FindSectionByName(GetSegmentNameTEXT()));5162 if (text_segment_sp) {5163 header_addr.SetSection(text_segment_sp);5164 header_addr.SetOffset(0);5165 }5166 }5167 return header_addr;5168}5169 5170uint32_t ObjectFileMachO::GetNumThreadContexts() {5171 ModuleSP module_sp(GetModule());5172 if (module_sp) {5173 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5174 if (!m_thread_context_offsets_valid) {5175 m_thread_context_offsets_valid = true;5176 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);5177 FileRangeArray::Entry file_range;5178 llvm::MachO::thread_command thread_cmd;5179 for (uint32_t i = 0; i < m_header.ncmds; ++i) {5180 const uint32_t cmd_offset = offset;5181 if (m_data.GetU32(&offset, &thread_cmd, 2) == nullptr)5182 break;5183 5184 if (thread_cmd.cmd == LC_THREAD) {5185 file_range.SetRangeBase(offset);5186 file_range.SetByteSize(thread_cmd.cmdsize - 8);5187 m_thread_context_offsets.Append(file_range);5188 }5189 offset = cmd_offset + thread_cmd.cmdsize;5190 }5191 }5192 }5193 return m_thread_context_offsets.GetSize();5194}5195 5196std::vector<std::tuple<offset_t, offset_t>>5197ObjectFileMachO::FindLC_NOTEByName(std::string name) {5198 std::vector<std::tuple<offset_t, offset_t>> results;5199 ModuleSP module_sp(GetModule());5200 if (module_sp) {5201 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5202 5203 offset_t offset = MachHeaderSizeFromMagic(m_header.magic);5204 for (uint32_t i = 0; i < m_header.ncmds; ++i) {5205 const uint32_t cmd_offset = offset;5206 llvm::MachO::load_command lc = {};5207 if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)5208 break;5209 if (lc.cmd == LC_NOTE) {5210 char data_owner[17];5211 m_data.CopyData(offset, 16, data_owner);5212 data_owner[16] = '\0';5213 offset += 16;5214 5215 if (name == data_owner) {5216 offset_t payload_offset = m_data.GetU64_unchecked(&offset);5217 offset_t payload_size = m_data.GetU64_unchecked(&offset);5218 results.push_back({payload_offset, payload_size});5219 }5220 }5221 offset = cmd_offset + lc.cmdsize;5222 }5223 }5224 return results;5225}5226 5227std::string ObjectFileMachO::GetIdentifierString() {5228 Log *log(5229 GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));5230 ModuleSP module_sp(GetModule());5231 if (module_sp) {5232 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5233 5234 auto lc_notes = FindLC_NOTEByName("kern ver str");5235 for (auto lc_note : lc_notes) {5236 offset_t payload_offset = std::get<0>(lc_note);5237 offset_t payload_size = std::get<1>(lc_note);5238 uint32_t version;5239 if (m_data.GetU32(&payload_offset, &version, 1) != nullptr) {5240 if (version == 1) {5241 uint32_t strsize = payload_size - sizeof(uint32_t);5242 std::string result(strsize, '\0');5243 m_data.CopyData(payload_offset, strsize, result.data());5244 LLDB_LOGF(log, "LC_NOTE 'kern ver str' found with text '%s'",5245 result.c_str());5246 return result;5247 }5248 }5249 }5250 5251 // Second, make a pass over the load commands looking for an obsolete5252 // LC_IDENT load command.5253 offset_t offset = MachHeaderSizeFromMagic(m_header.magic);5254 for (uint32_t i = 0; i < m_header.ncmds; ++i) {5255 const uint32_t cmd_offset = offset;5256 llvm::MachO::ident_command ident_command;5257 if (m_data.GetU32(&offset, &ident_command, 2) == nullptr)5258 break;5259 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {5260 std::string result(ident_command.cmdsize, '\0');5261 if (m_data.CopyData(offset, ident_command.cmdsize, result.data()) ==5262 ident_command.cmdsize) {5263 LLDB_LOGF(log, "LC_IDENT found with text '%s'", result.c_str());5264 return result;5265 }5266 }5267 offset = cmd_offset + ident_command.cmdsize;5268 }5269 }5270 return {};5271}5272 5273AddressableBits ObjectFileMachO::GetAddressableBits() {5274 AddressableBits addressable_bits;5275 5276 Log *log(GetLog(LLDBLog::Process));5277 ModuleSP module_sp(GetModule());5278 if (module_sp) {5279 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5280 auto lc_notes = FindLC_NOTEByName("addrable bits");5281 for (auto lc_note : lc_notes) {5282 offset_t payload_offset = std::get<0>(lc_note);5283 uint32_t version;5284 if (m_data.GetU32(&payload_offset, &version, 1) != nullptr) {5285 if (version == 3) {5286 uint32_t num_addr_bits = m_data.GetU32_unchecked(&payload_offset);5287 addressable_bits.SetAddressableBits(num_addr_bits);5288 LLDB_LOGF(log,5289 "LC_NOTE 'addrable bits' v3 found, value %d "5290 "bits",5291 num_addr_bits);5292 }5293 if (version == 4) {5294 uint32_t lo_addr_bits = m_data.GetU32_unchecked(&payload_offset);5295 uint32_t hi_addr_bits = m_data.GetU32_unchecked(&payload_offset);5296 5297 if (lo_addr_bits == hi_addr_bits)5298 addressable_bits.SetAddressableBits(lo_addr_bits);5299 else5300 addressable_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits);5301 LLDB_LOGF(log, "LC_NOTE 'addrable bits' v4 found, value %d & %d bits",5302 lo_addr_bits, hi_addr_bits);5303 }5304 }5305 }5306 }5307 return addressable_bits;5308}5309 5310bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,5311 bool &value_is_offset,5312 UUID &uuid,5313 ObjectFile::BinaryType &type) {5314 Log *log(5315 GetLog(LLDBLog::Symbols | LLDBLog::Process | LLDBLog::DynamicLoader));5316 value = LLDB_INVALID_ADDRESS;5317 value_is_offset = false;5318 uuid.Clear();5319 uint32_t log2_pagesize = 0; // not currently passed up to caller5320 uint32_t platform = 0; // not currently passed up to caller5321 ModuleSP module_sp(GetModule());5322 if (module_sp) {5323 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5324 5325 auto lc_notes = FindLC_NOTEByName("main bin spec");5326 for (auto lc_note : lc_notes) {5327 offset_t payload_offset = std::get<0>(lc_note);5328 5329 // struct main_bin_spec5330 // {5331 // uint32_t version; // currently 25332 // uint32_t type; // 0 == unspecified,5333 // // 1 == kernel5334 // // 2 == user process,5335 // dyld mach-o binary addr5336 // // 3 == standalone binary5337 // // 4 == user process,5338 // // dyld_all_image_infos addr5339 // uint64_t address; // UINT64_MAX if address not specified5340 // uint64_t slide; // slide, UINT64_MAX if unspecified5341 // // 0 if no slide needs to be applied to5342 // // file address5343 // uuid_t uuid; // all zero's if uuid not specified5344 // uint32_t log2_pagesize; // process page size in log base 2,5345 // // e.g. 4k pages are 12.5346 // // 0 for unspecified5347 // uint32_t platform; // The Mach-O platform for this corefile.5348 // // 0 for unspecified.5349 // // The values are defined in5350 // // <mach-o/loader.h>, PLATFORM_*.5351 // } __attribute((packed));5352 5353 // "main bin spec" (main binary specification) data payload is5354 // formatted:5355 // uint32_t version [currently 1]5356 // uint32_t type [0 == unspecified, 1 == kernel,5357 // 2 == user process, 3 == firmware ]5358 // uint64_t address [ UINT64_MAX if address not specified ]5359 // uuid_t uuid [ all zero's if uuid not specified ]5360 // uint32_t log2_pagesize [ process page size in log base5361 // 2, e.g. 4k pages are 12.5362 // 0 for unspecified ]5363 // uint32_t unused [ for alignment ]5364 5365 uint32_t version;5366 if (m_data.GetU32(&payload_offset, &version, 1) != nullptr &&5367 version <= 2) {5368 uint32_t binspec_type = 0;5369 uuid_t raw_uuid;5370 memset(raw_uuid, 0, sizeof(uuid_t));5371 5372 if (!m_data.GetU32(&payload_offset, &binspec_type, 1))5373 return false;5374 if (!m_data.GetU64(&payload_offset, &value, 1))5375 return false;5376 uint64_t slide = LLDB_INVALID_ADDRESS;5377 if (version > 1 && !m_data.GetU64(&payload_offset, &slide, 1))5378 return false;5379 if (value == LLDB_INVALID_ADDRESS && slide != LLDB_INVALID_ADDRESS) {5380 value = slide;5381 value_is_offset = true;5382 }5383 5384 if (m_data.CopyData(payload_offset, sizeof(uuid_t), raw_uuid) != 0) {5385 uuid = UUID(raw_uuid, sizeof(uuid_t));5386 // convert the "main bin spec" type into our5387 // ObjectFile::BinaryType enum5388 const char *typestr = "unrecognized type";5389 type = eBinaryTypeInvalid;5390 switch (binspec_type) {5391 case 0:5392 type = eBinaryTypeUnknown;5393 typestr = "uknown";5394 break;5395 case 1:5396 type = eBinaryTypeKernel;5397 typestr = "xnu kernel";5398 break;5399 case 2:5400 type = eBinaryTypeUser;5401 typestr = "userland dyld";5402 break;5403 case 3:5404 type = eBinaryTypeStandalone;5405 typestr = "standalone";5406 break;5407 case 4:5408 type = eBinaryTypeUserAllImageInfos;5409 typestr = "userland dyld_all_image_infos";5410 break;5411 }5412 LLDB_LOGF(log,5413 "LC_NOTE 'main bin spec' found, version %d type %d "5414 "(%s), value 0x%" PRIx64 " value-is-slide==%s uuid %s",5415 version, type, typestr, value,5416 value_is_offset ? "true" : "false",5417 uuid.GetAsString().c_str());5418 if (!m_data.GetU32(&payload_offset, &log2_pagesize, 1))5419 return false;5420 if (version > 1 && !m_data.GetU32(&payload_offset, &platform, 1))5421 return false;5422 return true;5423 }5424 }5425 }5426 }5427 return false;5428}5429 5430bool ObjectFileMachO::GetCorefileThreadExtraInfos(5431 std::vector<lldb::tid_t> &tids) {5432 tids.clear();5433 ModuleSP module_sp(GetModule());5434 if (module_sp) {5435 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5436 5437 Log *log(GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));5438 if (StructuredData::ObjectSP object_sp = GetCorefileProcessMetadata()) {5439 StructuredData::Dictionary *dict = object_sp->GetAsDictionary();5440 StructuredData::Array *threads;5441 if (!dict->GetValueForKeyAsArray("threads", threads) || !threads) {5442 LLDB_LOGF(log,5443 "'process metadata' LC_NOTE does not have a 'threads' key");5444 return false;5445 }5446 if (threads->GetSize() != GetNumThreadContexts()) {5447 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, number of "5448 "threads does not match number of LC_THREADS.");5449 return false;5450 }5451 const size_t num_threads = threads->GetSize();5452 for (size_t i = 0; i < num_threads; i++) {5453 std::optional<StructuredData::Dictionary *> maybe_thread =5454 threads->GetItemAtIndexAsDictionary(i);5455 if (!maybe_thread) {5456 LLDB_LOGF(log,5457 "Unable to read 'process metadata' LC_NOTE, threads "5458 "array does not have a dictionary at index %zu.",5459 i);5460 return false;5461 }5462 StructuredData::Dictionary *thread = *maybe_thread;5463 lldb::tid_t tid = LLDB_INVALID_THREAD_ID;5464 if (thread->GetValueForKeyAsInteger<lldb::tid_t>("thread_id", tid))5465 if (tid == 0)5466 tid = LLDB_INVALID_THREAD_ID;5467 tids.push_back(tid);5468 }5469 5470 if (log) {5471 StreamString logmsg;5472 logmsg.Printf("LC_NOTE 'process metadata' found: ");5473 dict->Dump(logmsg, /* pretty_print */ false);5474 LLDB_LOGF(log, "%s", logmsg.GetData());5475 }5476 return true;5477 }5478 }5479 return false;5480}5481 5482StructuredData::ObjectSP ObjectFileMachO::GetCorefileProcessMetadata() {5483 ModuleSP module_sp(GetModule());5484 if (!module_sp)5485 return {};5486 5487 Log *log(GetLog(LLDBLog::Object | LLDBLog::Process | LLDBLog::Thread));5488 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5489 auto lc_notes = FindLC_NOTEByName("process metadata");5490 if (lc_notes.size() == 0)5491 return {};5492 5493 if (lc_notes.size() > 1)5494 LLDB_LOGF(5495 log,5496 "Multiple 'process metadata' LC_NOTEs found, only using the first.");5497 5498 auto [payload_offset, strsize] = lc_notes[0];5499 std::string buf(strsize, '\0');5500 if (m_data.CopyData(payload_offset, strsize, buf.data()) != strsize) {5501 LLDB_LOGF(log,5502 "Unable to read %" PRIu645503 " bytes of 'process metadata' LC_NOTE JSON contents",5504 strsize);5505 return {};5506 }5507 while (buf.back() == '\0')5508 buf.resize(buf.size() - 1);5509 StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(buf);5510 if (!object_sp) {5511 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "5512 "parse as valid JSON.");5513 return {};5514 }5515 StructuredData::Dictionary *dict = object_sp->GetAsDictionary();5516 if (!dict) {5517 LLDB_LOGF(log, "Unable to read 'process metadata' LC_NOTE, did not "5518 "get a dictionary.");5519 return {};5520 }5521 5522 return object_sp;5523}5524 5525lldb::RegisterContextSP5526ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,5527 lldb_private::Thread &thread) {5528 lldb::RegisterContextSP reg_ctx_sp;5529 5530 ModuleSP module_sp(GetModule());5531 if (module_sp) {5532 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5533 if (!m_thread_context_offsets_valid)5534 GetNumThreadContexts();5535 5536 const FileRangeArray::Entry *thread_context_file_range =5537 m_thread_context_offsets.GetEntryAtIndex(idx);5538 if (thread_context_file_range) {5539 5540 DataExtractor data(m_data, thread_context_file_range->GetRangeBase(),5541 thread_context_file_range->GetByteSize());5542 5543 switch (m_header.cputype) {5544 case llvm::MachO::CPU_TYPE_ARM64:5545 case llvm::MachO::CPU_TYPE_ARM64_32:5546 reg_ctx_sp =5547 std::make_shared<RegisterContextDarwin_arm64_Mach>(thread, data);5548 break;5549 5550 case llvm::MachO::CPU_TYPE_ARM:5551 reg_ctx_sp =5552 std::make_shared<RegisterContextDarwin_arm_Mach>(thread, data);5553 break;5554 5555 case llvm::MachO::CPU_TYPE_X86_64:5556 reg_ctx_sp =5557 std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);5558 break;5559 5560 case llvm::MachO::CPU_TYPE_RISCV:5561 reg_ctx_sp =5562 std::make_shared<RegisterContextDarwin_riscv32_Mach>(thread, data);5563 break;5564 }5565 }5566 }5567 return reg_ctx_sp;5568}5569 5570ObjectFile::Type ObjectFileMachO::CalculateType() {5571 switch (m_header.filetype) {5572 case MH_OBJECT: // 0x1u5573 if (GetAddressByteSize() == 4) {5574 // 32 bit kexts are just object files, but they do have a valid5575 // UUID load command.5576 if (GetUUID()) {5577 // this checking for the UUID load command is not enough we could5578 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as5579 // this is required of kexts5580 if (m_strata == eStrataInvalid)5581 m_strata = eStrataKernel;5582 return eTypeSharedLibrary;5583 }5584 }5585 return eTypeObjectFile;5586 5587 case MH_EXECUTE:5588 return eTypeExecutable; // 0x2u5589 case MH_FVMLIB:5590 return eTypeSharedLibrary; // 0x3u5591 case MH_CORE:5592 return eTypeCoreFile; // 0x4u5593 case MH_PRELOAD:5594 return eTypeSharedLibrary; // 0x5u5595 case MH_DYLIB:5596 return eTypeSharedLibrary; // 0x6u5597 case MH_DYLINKER:5598 return eTypeDynamicLinker; // 0x7u5599 case MH_BUNDLE:5600 return eTypeSharedLibrary; // 0x8u5601 case MH_DYLIB_STUB:5602 return eTypeStubLibrary; // 0x9u5603 case MH_DSYM:5604 return eTypeDebugInfo; // 0xAu5605 case MH_KEXT_BUNDLE:5606 return eTypeSharedLibrary; // 0xBu5607 default:5608 break;5609 }5610 return eTypeUnknown;5611}5612 5613ObjectFile::Strata ObjectFileMachO::CalculateStrata() {5614 switch (m_header.filetype) {5615 case MH_OBJECT: // 0x1u5616 {5617 // 32 bit kexts are just object files, but they do have a valid5618 // UUID load command.5619 if (GetUUID()) {5620 // this checking for the UUID load command is not enough we could5621 // eventually look for the symbol named "OSKextGetCurrentIdentifier" as5622 // this is required of kexts5623 if (m_type == eTypeInvalid)5624 m_type = eTypeSharedLibrary;5625 5626 return eStrataKernel;5627 }5628 }5629 return eStrataUnknown;5630 5631 case MH_EXECUTE: // 0x2u5632 // Check for the MH_DYLDLINK bit in the flags5633 if (m_header.flags & MH_DYLDLINK) {5634 return eStrataUser;5635 } else {5636 SectionList *section_list = GetSectionList();5637 if (section_list) {5638 static ConstString g_kld_section_name("__KLD");5639 if (section_list->FindSectionByName(g_kld_section_name))5640 return eStrataKernel;5641 }5642 }5643 return eStrataRawImage;5644 5645 case MH_FVMLIB:5646 return eStrataUser; // 0x3u5647 case MH_CORE:5648 return eStrataUnknown; // 0x4u5649 case MH_PRELOAD:5650 return eStrataRawImage; // 0x5u5651 case MH_DYLIB:5652 return eStrataUser; // 0x6u5653 case MH_DYLINKER:5654 return eStrataUser; // 0x7u5655 case MH_BUNDLE:5656 return eStrataUser; // 0x8u5657 case MH_DYLIB_STUB:5658 return eStrataUser; // 0x9u5659 case MH_DSYM:5660 return eStrataUnknown; // 0xAu5661 case MH_KEXT_BUNDLE:5662 return eStrataKernel; // 0xBu5663 default:5664 break;5665 }5666 return eStrataUnknown;5667}5668 5669llvm::VersionTuple ObjectFileMachO::GetVersion() {5670 ModuleSP module_sp(GetModule());5671 if (module_sp) {5672 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5673 llvm::MachO::dylib_command load_cmd;5674 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);5675 uint32_t version_cmd = 0;5676 uint64_t version = 0;5677 uint32_t i;5678 for (i = 0; i < m_header.ncmds; ++i) {5679 const lldb::offset_t cmd_offset = offset;5680 if (m_data.GetU32(&offset, &load_cmd, 2) == nullptr)5681 break;5682 5683 if (load_cmd.cmd == LC_ID_DYLIB) {5684 if (version_cmd == 0) {5685 version_cmd = load_cmd.cmd;5686 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == nullptr)5687 break;5688 version = load_cmd.dylib.current_version;5689 }5690 break; // Break for now unless there is another more complete version5691 // number load command in the future.5692 }5693 offset = cmd_offset + load_cmd.cmdsize;5694 }5695 5696 if (version_cmd == LC_ID_DYLIB) {5697 unsigned major = (version & 0xFFFF0000ull) >> 16;5698 unsigned minor = (version & 0x0000FF00ull) >> 8;5699 unsigned subminor = (version & 0x000000FFull);5700 return llvm::VersionTuple(major, minor, subminor);5701 }5702 }5703 return llvm::VersionTuple();5704}5705 5706ArchSpec ObjectFileMachO::GetArchitecture() {5707 ModuleSP module_sp(GetModule());5708 ArchSpec arch;5709 if (module_sp) {5710 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());5711 5712 return GetArchitecture(module_sp, m_header, m_data,5713 MachHeaderSizeFromMagic(m_header.magic));5714 }5715 return arch;5716}5717 5718void ObjectFileMachO::GetProcessSharedCacheUUID(Process *process,5719 addr_t &base_addr, UUID &uuid) {5720 uuid.Clear();5721 base_addr = LLDB_INVALID_ADDRESS;5722 if (process && process->GetDynamicLoader()) {5723 DynamicLoader *dl = process->GetDynamicLoader();5724 LazyBool using_shared_cache;5725 LazyBool private_shared_cache;5726 dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,5727 private_shared_cache);5728 }5729 Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));5730 LLDB_LOGF(5731 log,5732 "inferior process shared cache has a UUID of %s, base address 0x%" PRIx64,5733 uuid.GetAsString().c_str(), base_addr);5734}5735 5736// From dyld SPI header dyld_process_info.h5737typedef void *dyld_process_info;5738struct lldb_copy__dyld_process_cache_info {5739 uuid_t cacheUUID; // UUID of cache used by process5740 uint64_t cacheBaseAddress; // load address of dyld shared cache5741 bool noCache; // process is running without a dyld cache5742 bool privateCache; // process is using a private copy of its dyld cache5743};5744 5745// #including mach/mach.h pulls in machine.h & CPU_TYPE_ARM etc conflicts with5746// llvm enum definitions llvm::MachO::CPU_TYPE_ARM turning them into compile5747// errors. So we need to use the actual underlying types of task_t and5748// kern_return_t below.5749extern "C" unsigned int /*task_t*/ mach_task_self();5750 5751void ObjectFileMachO::GetLLDBSharedCacheUUID(addr_t &base_addr, UUID &uuid) {5752 uuid.Clear();5753 base_addr = LLDB_INVALID_ADDRESS;5754 5755#if defined(__APPLE__)5756 uint8_t *(*dyld_get_all_image_infos)(void);5757 dyld_get_all_image_infos =5758 (uint8_t * (*)()) dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos");5759 if (dyld_get_all_image_infos) {5760 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();5761 if (dyld_all_image_infos_address) {5762 uint32_t *version = (uint32_t *)5763 dyld_all_image_infos_address; // version <mach-o/dyld_images.h>5764 if (*version >= 13) {5765 uuid_t *sharedCacheUUID_address = 0;5766 int wordsize = sizeof(uint8_t *);5767 if (wordsize == 8) {5768 sharedCacheUUID_address =5769 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +5770 160); // sharedCacheUUID <mach-o/dyld_images.h>5771 if (*version >= 15)5772 base_addr =5773 *(uint64_t5774 *)((uint8_t *)dyld_all_image_infos_address +5775 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>5776 } else {5777 sharedCacheUUID_address =5778 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +5779 84); // sharedCacheUUID <mach-o/dyld_images.h>5780 if (*version >= 15) {5781 base_addr = 0;5782 base_addr =5783 *(uint32_t5784 *)((uint8_t *)dyld_all_image_infos_address +5785 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>5786 }5787 }5788 uuid = UUID(sharedCacheUUID_address, sizeof(uuid_t));5789 }5790 }5791 } else {5792 // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI5793 dyld_process_info (*dyld_process_info_create)(5794 unsigned int /* task_t */ task, uint64_t timestamp,5795 unsigned int /*kern_return_t*/ *kernelError);5796 void (*dyld_process_info_get_cache)(void *info, void *cacheInfo);5797 void (*dyld_process_info_release)(dyld_process_info info);5798 5799 dyld_process_info_create = (void *(*)(unsigned int /* task_t */, uint64_t,5800 unsigned int /*kern_return_t*/ *))5801 dlsym(RTLD_DEFAULT, "_dyld_process_info_create");5802 dyld_process_info_get_cache = (void (*)(void *, void *))dlsym(5803 RTLD_DEFAULT, "_dyld_process_info_get_cache");5804 dyld_process_info_release =5805 (void (*)(void *))dlsym(RTLD_DEFAULT, "_dyld_process_info_release");5806 5807 if (dyld_process_info_create && dyld_process_info_get_cache) {5808 unsigned int /*kern_return_t */ kern_ret;5809 dyld_process_info process_info =5810 dyld_process_info_create(::mach_task_self(), 0, &kern_ret);5811 if (process_info) {5812 struct lldb_copy__dyld_process_cache_info sc_info;5813 memset(&sc_info, 0, sizeof(struct lldb_copy__dyld_process_cache_info));5814 dyld_process_info_get_cache(process_info, &sc_info);5815 if (sc_info.cacheBaseAddress != 0) {5816 base_addr = sc_info.cacheBaseAddress;5817 uuid = UUID(sc_info.cacheUUID, sizeof(uuid_t));5818 }5819 dyld_process_info_release(process_info);5820 }5821 }5822 }5823 Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));5824 if (log && uuid.IsValid())5825 LLDB_LOGF(log,5826 "lldb's in-memory shared cache has a UUID of %s base address of "5827 "0x%" PRIx64,5828 uuid.GetAsString().c_str(), base_addr);5829#endif5830}5831 5832static llvm::VersionTuple FindMinimumVersionInfo(DataExtractor &data,5833 lldb::offset_t offset,5834 size_t ncmds) {5835 for (size_t i = 0; i < ncmds; i++) {5836 const lldb::offset_t load_cmd_offset = offset;5837 llvm::MachO::load_command lc = {};5838 if (data.GetU32(&offset, &lc.cmd, 2) == nullptr)5839 break;5840 5841 uint32_t version = 0;5842 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||5843 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||5844 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||5845 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {5846 // struct version_min_command {5847 // uint32_t cmd; // LC_VERSION_MIN_*5848 // uint32_t cmdsize;5849 // uint32_t version; // X.Y.Z encoded in nibbles xxxx.yy.zz5850 // uint32_t sdk;5851 // };5852 // We want to read version.5853 version = data.GetU32(&offset);5854 } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {5855 // struct build_version_command {5856 // uint32_t cmd; // LC_BUILD_VERSION5857 // uint32_t cmdsize;5858 // uint32_t platform;5859 // uint32_t minos; // X.Y.Z encoded in nibbles xxxx.yy.zz5860 // uint32_t sdk;5861 // uint32_t ntools;5862 // };5863 // We want to read minos.5864 offset += sizeof(uint32_t); // Skip over platform5865 version = data.GetU32(&offset); // Extract minos5866 }5867 5868 if (version) {5869 const uint32_t xxxx = version >> 16;5870 const uint32_t yy = (version >> 8) & 0xffu;5871 const uint32_t zz = version & 0xffu;5872 if (xxxx)5873 return llvm::VersionTuple(xxxx, yy, zz);5874 }5875 offset = load_cmd_offset + lc.cmdsize;5876 }5877 return llvm::VersionTuple();5878}5879 5880llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() {5881 if (!m_min_os_version)5882 m_min_os_version = FindMinimumVersionInfo(5883 m_data, MachHeaderSizeFromMagic(m_header.magic), m_header.ncmds);5884 return *m_min_os_version;5885}5886 5887llvm::VersionTuple ObjectFileMachO::GetSDKVersion() {5888 if (!m_sdk_versions)5889 m_sdk_versions = FindMinimumVersionInfo(5890 m_data, MachHeaderSizeFromMagic(m_header.magic), m_header.ncmds);5891 return *m_sdk_versions;5892}5893 5894bool ObjectFileMachO::GetIsDynamicLinkEditor() {5895 return m_header.filetype == llvm::MachO::MH_DYLINKER;5896}5897 5898bool ObjectFileMachO::CanTrustAddressRanges() {5899 // Dsymutil guarantees that the .debug_aranges accelerator is complete and can5900 // be trusted by LLDB.5901 return m_header.filetype == llvm::MachO::MH_DSYM;5902}5903 5904bool ObjectFileMachO::AllowAssemblyEmulationUnwindPlans() {5905 return m_allow_assembly_emulation_unwind_plans;5906}5907 5908Section *ObjectFileMachO::GetMachHeaderSection() {5909 // Find the first address of the mach header which is the first non-zero file5910 // sized section whose file offset is zero. This is the base file address of5911 // the mach-o file which can be subtracted from the vmaddr of the other5912 // segments found in memory and added to the load address5913 ModuleSP module_sp = GetModule();5914 if (!module_sp)5915 return nullptr;5916 SectionList *section_list = GetSectionList();5917 if (!section_list)5918 return nullptr;5919 5920 // Some binaries can have a TEXT segment with a non-zero file offset.5921 // Binaries in the shared cache are one example. Some hand-generated5922 // binaries may not be laid out in the normal TEXT,DATA,LC_SYMTAB order5923 // in the file, even though they're laid out correctly in vmaddr terms.5924 SectionSP text_segment_sp =5925 section_list->FindSectionByName(GetSegmentNameTEXT());5926 if (text_segment_sp.get() && SectionIsLoadable(text_segment_sp.get()))5927 return text_segment_sp.get();5928 5929 const size_t num_sections = section_list->GetSize();5930 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {5931 Section *section = section_list->GetSectionAtIndex(sect_idx).get();5932 if (section->GetFileOffset() == 0 && SectionIsLoadable(section))5933 return section;5934 }5935 5936 return nullptr;5937}5938 5939bool ObjectFileMachO::IsGOTSection(const lldb_private::Section §ion) const {5940 assert(section.GetObjectFile() == this && "Wrong object file!");5941 SectionSP segment = section.GetParent();5942 if (!segment)5943 return false;5944 5945 const bool is_data_const_got =5946 segment->GetName() == "__DATA_CONST" && section.GetName() == "__got";5947 const bool is_auth_const_ptr =5948 segment->GetName() == "__AUTH_CONST" &&5949 (section.GetName() == "__auth_got" || section.GetName() == "__auth_ptr");5950 return is_data_const_got || is_auth_const_ptr;5951}5952 5953bool ObjectFileMachO::SectionIsLoadable(const Section *section) {5954 if (!section)5955 return false;5956 if (section->IsThreadSpecific())5957 return false;5958 if (GetModule().get() != section->GetModule().get())5959 return false;5960 // firmware style binaries with llvm gcov segment do5961 // not have that segment mapped into memory.5962 if (section->GetName() == GetSegmentNameLLVM_COV()) {5963 const Strata strata = GetStrata();5964 if (strata == eStrataKernel || strata == eStrataRawImage)5965 return false;5966 }5967 // Be careful with __LINKEDIT and __DWARF segments5968 if (section->GetName() == GetSegmentNameLINKEDIT() ||5969 section->GetName() == GetSegmentNameDWARF()) {5970 // Only map __LINKEDIT and __DWARF if we have an in memory image and5971 // this isn't a kernel binary like a kext or mach_kernel.5972 const bool is_memory_image = (bool)m_process_wp.lock();5973 const Strata strata = GetStrata();5974 if (is_memory_image == false || strata == eStrataKernel)5975 return false;5976 }5977 return true;5978}5979 5980lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(5981 lldb::addr_t header_load_address, const Section *header_section,5982 const Section *section) {5983 ModuleSP module_sp = GetModule();5984 if (module_sp && header_section && section &&5985 header_load_address != LLDB_INVALID_ADDRESS) {5986 lldb::addr_t file_addr = header_section->GetFileAddress();5987 if (file_addr != LLDB_INVALID_ADDRESS && SectionIsLoadable(section))5988 return section->GetFileAddress() - file_addr + header_load_address;5989 }5990 return LLDB_INVALID_ADDRESS;5991}5992 5993bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,5994 bool value_is_offset) {5995 Log *log(GetLog(LLDBLog::DynamicLoader));5996 ModuleSP module_sp = GetModule();5997 if (!module_sp)5998 return false;5999 6000 SectionList *section_list = GetSectionList();6001 if (!section_list)6002 return false;6003 6004 size_t num_loaded_sections = 0;6005 const size_t num_sections = section_list->GetSize();6006 6007 // Warn if some top-level segments map to the same address. The binary may be6008 // malformed.6009 const bool warn_multiple = true;6010 6011 if (log) {6012 StreamString logmsg;6013 logmsg << "ObjectFileMachO::SetLoadAddress ";6014 if (GetFileSpec())6015 logmsg << "path='" << GetFileSpec().GetPath() << "' ";6016 if (GetUUID()) {6017 logmsg << "uuid=" << GetUUID().GetAsString();6018 }6019 LLDB_LOGF(log, "%s", logmsg.GetData());6020 }6021 if (value_is_offset) {6022 // "value" is an offset to apply to each top level segment6023 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {6024 // Iterate through the object file sections to find all of the6025 // sections that size on disk (to avoid __PAGEZERO) and load them6026 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));6027 if (SectionIsLoadable(section_sp.get())) {6028 LLDB_LOGF(log,6029 "ObjectFileMachO::SetLoadAddress segment '%s' load addr is "6030 "0x%" PRIx64,6031 section_sp->GetName().AsCString(),6032 section_sp->GetFileAddress() + value);6033 if (target.SetSectionLoadAddress(section_sp,6034 section_sp->GetFileAddress() + value,6035 warn_multiple))6036 ++num_loaded_sections;6037 }6038 }6039 } else {6040 // "value" is the new base address of the mach_header, adjust each6041 // section accordingly6042 6043 Section *mach_header_section = GetMachHeaderSection();6044 if (mach_header_section) {6045 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {6046 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));6047 6048 lldb::addr_t section_load_addr =6049 CalculateSectionLoadAddressForMemoryImage(6050 value, mach_header_section, section_sp.get());6051 if (section_load_addr != LLDB_INVALID_ADDRESS) {6052 LLDB_LOGF(log,6053 "ObjectFileMachO::SetLoadAddress segment '%s' load addr is "6054 "0x%" PRIx64,6055 section_sp->GetName().AsCString(), section_load_addr);6056 if (target.SetSectionLoadAddress(section_sp, section_load_addr,6057 warn_multiple))6058 ++num_loaded_sections;6059 }6060 }6061 }6062 }6063 return num_loaded_sections > 0;6064}6065 6066struct all_image_infos_header {6067 uint32_t version; // currently 16068 uint32_t imgcount; // number of binary images6069 uint64_t entries_fileoff; // file offset in the corefile of where the array of6070 // struct entry's begin.6071 uint32_t entries_size; // size of 'struct entry'.6072 uint32_t unused;6073};6074 6075struct image_entry {6076 uint64_t filepath_offset; // offset in corefile to c-string of the file path,6077 // UINT64_MAX if unavailable.6078 uuid_t uuid; // uint8_t[16]. should be set to all zeroes if6079 // uuid is unknown.6080 uint64_t load_address; // UINT64_MAX if unknown.6081 uint64_t seg_addrs_offset; // offset to the array of struct segment_vmaddr's.6082 uint32_t segment_count; // The number of segments for this binary.6083 uint32_t unused;6084 6085 image_entry() {6086 filepath_offset = UINT64_MAX;6087 memset(&uuid, 0, sizeof(uuid_t));6088 segment_count = 0;6089 load_address = UINT64_MAX;6090 seg_addrs_offset = UINT64_MAX;6091 unused = 0;6092 }6093 image_entry(const image_entry &rhs) {6094 filepath_offset = rhs.filepath_offset;6095 memcpy(&uuid, &rhs.uuid, sizeof(uuid_t));6096 segment_count = rhs.segment_count;6097 seg_addrs_offset = rhs.seg_addrs_offset;6098 load_address = rhs.load_address;6099 unused = rhs.unused;6100 }6101};6102 6103struct segment_vmaddr {6104 char segname[16];6105 uint64_t vmaddr;6106 uint64_t unused;6107 6108 segment_vmaddr() {6109 memset(&segname, 0, 16);6110 vmaddr = UINT64_MAX;6111 unused = 0;6112 }6113 segment_vmaddr(const segment_vmaddr &rhs) {6114 memcpy(&segname, &rhs.segname, 16);6115 vmaddr = rhs.vmaddr;6116 unused = rhs.unused;6117 }6118};6119 6120// Write the payload for the "all image infos" LC_NOTE into6121// the supplied all_image_infos_payload, assuming that this6122// will be written into the corefile starting at6123// initial_file_offset.6124//6125// The placement of this payload is a little tricky. We're6126// laying this out as6127//6128// 1. header (struct all_image_info_header)6129// 2. Array of fixed-size (struct image_entry)'s, one6130// per binary image present in the process.6131// 3. Arrays of (struct segment_vmaddr)'s, a varying number6132// for each binary image.6133// 4. Variable length c-strings of binary image filepaths,6134// one per binary.6135//6136// To compute where everything will be laid out in the6137// payload, we need to iterate over the images and calculate6138// how many segment_vmaddr structures each image will need,6139// and how long each image's filepath c-string is. There6140// are some multiple passes over the image list while calculating6141// everything.6142 6143static offset_t6144CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp,6145 offset_t initial_file_offset,6146 StreamString &all_image_infos_payload,6147 lldb_private::SaveCoreOptions &options) {6148 Target &target = process_sp->GetTarget();6149 ModuleList modules = target.GetImages();6150 6151 // stack-only corefiles have no reason to include binaries that6152 // are not executing; we're trying to make the smallest corefile6153 // we can, so leave the rest out.6154 if (options.GetStyle() == SaveCoreStyle::eSaveCoreStackOnly)6155 modules.Clear();6156 6157 std::set<std::string> executing_uuids;6158 std::vector<ThreadSP> thread_list =6159 process_sp->CalculateCoreFileThreadList(options);6160 for (const ThreadSP &thread_sp : thread_list) {6161 uint32_t stack_frame_count = thread_sp->GetStackFrameCount();6162 for (uint32_t j = 0; j < stack_frame_count; j++) {6163 StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);6164 Address pc = stack_frame_sp->GetFrameCodeAddress();6165 ModuleSP module_sp = pc.GetModule();6166 if (module_sp) {6167 UUID uuid = module_sp->GetUUID();6168 if (uuid.IsValid()) {6169 executing_uuids.insert(uuid.GetAsString());6170 modules.AppendIfNeeded(module_sp);6171 }6172 }6173 }6174 }6175 size_t modules_count = modules.GetSize();6176 6177 struct all_image_infos_header infos;6178 infos.version = 1;6179 infos.imgcount = modules_count;6180 infos.entries_size = sizeof(image_entry);6181 infos.entries_fileoff = initial_file_offset + sizeof(all_image_infos_header);6182 infos.unused = 0;6183 6184 all_image_infos_payload.PutHex32(infos.version);6185 all_image_infos_payload.PutHex32(infos.imgcount);6186 all_image_infos_payload.PutHex64(infos.entries_fileoff);6187 all_image_infos_payload.PutHex32(infos.entries_size);6188 all_image_infos_payload.PutHex32(infos.unused);6189 6190 // First create the structures for all of the segment name+vmaddr vectors6191 // for each module, so we will know the size of them as we add the6192 // module entries.6193 std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;6194 for (size_t i = 0; i < modules_count; i++) {6195 ModuleSP module = modules.GetModuleAtIndex(i);6196 6197 SectionList *sections = module->GetSectionList();6198 size_t sections_count = sections->GetSize();6199 std::vector<segment_vmaddr> segment_vmaddrs;6200 for (size_t j = 0; j < sections_count; j++) {6201 SectionSP section = sections->GetSectionAtIndex(j);6202 if (!section->GetParent().get()) {6203 addr_t vmaddr = section->GetLoadBaseAddress(&target);6204 if (vmaddr == LLDB_INVALID_ADDRESS)6205 continue;6206 ConstString name = section->GetName();6207 segment_vmaddr seg_vmaddr;6208 // This is the uncommon case where strncpy is exactly6209 // the right one, doesn't need to be nul terminated.6210 // The segment name in a Mach-O LC_SEGMENT/LC_SEGMENT_64 is char[16] and6211 // is not guaranteed to be nul-terminated if all 16 characters are6212 // used.6213 // coverity[buffer_size_warning]6214 strncpy(seg_vmaddr.segname, name.AsCString(),6215 sizeof(seg_vmaddr.segname));6216 seg_vmaddr.vmaddr = vmaddr;6217 seg_vmaddr.unused = 0;6218 segment_vmaddrs.push_back(seg_vmaddr);6219 }6220 }6221 modules_segment_vmaddrs.push_back(segment_vmaddrs);6222 }6223 6224 offset_t size_of_vmaddr_structs = 0;6225 for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {6226 size_of_vmaddr_structs +=6227 modules_segment_vmaddrs[i].size() * sizeof(segment_vmaddr);6228 }6229 6230 offset_t size_of_filepath_cstrings = 0;6231 for (size_t i = 0; i < modules_count; i++) {6232 ModuleSP module_sp = modules.GetModuleAtIndex(i);6233 size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;6234 }6235 6236 // Calculate the file offsets of our "all image infos" payload in the6237 // corefile. initial_file_offset the original value passed in to this method.6238 6239 offset_t start_of_entries =6240 initial_file_offset + sizeof(all_image_infos_header);6241 offset_t start_of_seg_vmaddrs =6242 start_of_entries + sizeof(image_entry) * modules_count;6243 offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;6244 6245 offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;6246 6247 // Now write the one-per-module 'struct image_entry' into the6248 // StringStream; keep track of where the struct segment_vmaddr6249 // entries for each module will end up in the corefile.6250 6251 offset_t current_string_offset = start_of_filenames;6252 offset_t current_segaddrs_offset = start_of_seg_vmaddrs;6253 for (size_t i = 0; i < modules_count; i++) {6254 ModuleSP module_sp = modules.GetModuleAtIndex(i);6255 6256 struct image_entry ent;6257 memcpy(&ent.uuid, module_sp->GetUUID().GetBytes().data(), sizeof(ent.uuid));6258 if (modules_segment_vmaddrs[i].size() > 0) {6259 ent.segment_count = modules_segment_vmaddrs[i].size();6260 ent.seg_addrs_offset = current_segaddrs_offset;6261 }6262 ent.filepath_offset = current_string_offset;6263 ObjectFile *objfile = module_sp->GetObjectFile();6264 if (objfile) {6265 Address base_addr(objfile->GetBaseAddress());6266 if (base_addr.IsValid()) {6267 ent.load_address = base_addr.GetLoadAddress(&target);6268 }6269 }6270 6271 all_image_infos_payload.PutHex64(ent.filepath_offset);6272 all_image_infos_payload.PutRawBytes(ent.uuid, sizeof(ent.uuid));6273 all_image_infos_payload.PutHex64(ent.load_address);6274 all_image_infos_payload.PutHex64(ent.seg_addrs_offset);6275 all_image_infos_payload.PutHex32(ent.segment_count);6276 6277 if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=6278 executing_uuids.end())6279 all_image_infos_payload.PutHex32(1);6280 else6281 all_image_infos_payload.PutHex32(0);6282 6283 current_segaddrs_offset += ent.segment_count * sizeof(segment_vmaddr);6284 current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;6285 }6286 6287 // Now write the struct segment_vmaddr entries into the StringStream.6288 6289 for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {6290 if (modules_segment_vmaddrs[i].size() == 0)6291 continue;6292 for (struct segment_vmaddr segvm : modules_segment_vmaddrs[i]) {6293 all_image_infos_payload.PutRawBytes(segvm.segname, sizeof(segvm.segname));6294 all_image_infos_payload.PutHex64(segvm.vmaddr);6295 all_image_infos_payload.PutHex64(segvm.unused);6296 }6297 }6298 6299 for (size_t i = 0; i < modules_count; i++) {6300 ModuleSP module_sp = modules.GetModuleAtIndex(i);6301 std::string filepath = module_sp->GetFileSpec().GetPath();6302 all_image_infos_payload.PutRawBytes(filepath.data(), filepath.size() + 1);6303 }6304 6305 return final_file_offset;6306}6307 6308// Temp struct used to combine contiguous memory regions with6309// identical permissions.6310struct page_object {6311 addr_t addr;6312 addr_t size;6313 uint32_t prot;6314};6315 6316bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,6317 lldb_private::SaveCoreOptions &options,6318 Status &error) {6319 // The FileSpec and Process are already checked in PluginManager::SaveCore.6320 assert(options.GetOutputFile().has_value());6321 assert(process_sp);6322 const FileSpec outfile = options.GetOutputFile().value();6323 6324 // MachO defaults to dirty pages6325 if (options.GetStyle() == SaveCoreStyle::eSaveCoreUnspecified)6326 options.SetStyle(eSaveCoreDirtyOnly);6327 6328 Target &target = process_sp->GetTarget();6329 const ArchSpec target_arch = target.GetArchitecture();6330 const llvm::Triple &target_triple = target_arch.GetTriple();6331 if (target_triple.getVendor() == llvm::Triple::Apple &&6332 (target_triple.getOS() == llvm::Triple::MacOSX ||6333 target_triple.getOS() == llvm::Triple::IOS ||6334 target_triple.getOS() == llvm::Triple::WatchOS ||6335 target_triple.getOS() == llvm::Triple::TvOS ||6336 target_triple.getOS() == llvm::Triple::BridgeOS ||6337 target_triple.getOS() == llvm::Triple::XROS)) {6338 bool make_core = false;6339 switch (target_arch.GetMachine()) {6340 case llvm::Triple::aarch64:6341 case llvm::Triple::aarch64_32:6342 case llvm::Triple::arm:6343 case llvm::Triple::thumb:6344 case llvm::Triple::x86:6345 case llvm::Triple::x86_64:6346 make_core = true;6347 break;6348 default:6349 error = Status::FromErrorStringWithFormat(6350 "unsupported core architecture: %s", target_triple.str().c_str());6351 break;6352 }6353 6354 if (make_core) {6355 CoreFileMemoryRanges core_ranges;6356 error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);6357 if (error.Success()) {6358 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();6359 const ByteOrder byte_order = target_arch.GetByteOrder();6360 std::vector<llvm::MachO::segment_command_64> segment_load_commands;6361 for (const auto &core_range_info : core_ranges) {6362 // TODO: Refactor RangeDataVector to have a data iterator.6363 const auto &core_range = core_range_info.data;6364 uint32_t cmd_type = LC_SEGMENT_64;6365 uint32_t segment_size = sizeof(llvm::MachO::segment_command_64);6366 if (addr_byte_size == 4) {6367 cmd_type = LC_SEGMENT;6368 segment_size = sizeof(llvm::MachO::segment_command);6369 }6370 // Skip any ranges with no read/write/execute permissions and empty6371 // ranges.6372 if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)6373 continue;6374 uint32_t vm_prot = 0;6375 if (core_range.lldb_permissions & ePermissionsReadable)6376 vm_prot |= VM_PROT_READ;6377 if (core_range.lldb_permissions & ePermissionsWritable)6378 vm_prot |= VM_PROT_WRITE;6379 if (core_range.lldb_permissions & ePermissionsExecutable)6380 vm_prot |= VM_PROT_EXECUTE;6381 const addr_t vm_addr = core_range.range.start();6382 const addr_t vm_size = core_range.range.size();6383 llvm::MachO::segment_command_64 segment = {6384 cmd_type, // uint32_t cmd;6385 segment_size, // uint32_t cmdsize;6386 {0}, // char segname[16];6387 vm_addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O6388 vm_size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O6389 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O6390 vm_size, // uint64_t filesize; // uint32_t for 32-bit Mach-O6391 vm_prot, // uint32_t maxprot;6392 vm_prot, // uint32_t initprot;6393 0, // uint32_t nsects;6394 0}; // uint32_t flags;6395 segment_load_commands.push_back(segment);6396 }6397 6398 StreamString buffer(Stream::eBinary, addr_byte_size, byte_order);6399 6400 llvm::MachO::mach_header_64 mach_header;6401 mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;6402 mach_header.cputype = target_arch.GetMachOCPUType();6403 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();6404 mach_header.filetype = MH_CORE;6405 mach_header.ncmds = segment_load_commands.size();6406 mach_header.flags = 0;6407 mach_header.reserved = 0;6408 ThreadList &thread_list = process_sp->GetThreadList();6409 const uint32_t num_threads = thread_list.GetSize();6410 6411 // Make an array of LC_THREAD data items. Each one contains the6412 // contents of the LC_THREAD load command. The data doesn't contain6413 // the load command + load command size, we will add the load command6414 // and load command size as we emit the data.6415 std::vector<StreamString> LC_THREAD_datas(num_threads);6416 for (auto &LC_THREAD_data : LC_THREAD_datas) {6417 LC_THREAD_data.GetFlags().Set(Stream::eBinary);6418 LC_THREAD_data.SetAddressByteSize(addr_byte_size);6419 LC_THREAD_data.SetByteOrder(byte_order);6420 }6421 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {6422 ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));6423 if (thread_sp) {6424 switch (mach_header.cputype) {6425 case llvm::MachO::CPU_TYPE_ARM64:6426 case llvm::MachO::CPU_TYPE_ARM64_32:6427 RegisterContextDarwin_arm64_Mach::Create_LC_THREAD(6428 thread_sp.get(), LC_THREAD_datas[thread_idx]);6429 break;6430 6431 case llvm::MachO::CPU_TYPE_ARM:6432 RegisterContextDarwin_arm_Mach::Create_LC_THREAD(6433 thread_sp.get(), LC_THREAD_datas[thread_idx]);6434 break;6435 6436 case llvm::MachO::CPU_TYPE_X86_64:6437 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(6438 thread_sp.get(), LC_THREAD_datas[thread_idx]);6439 break;6440 6441 case llvm::MachO::CPU_TYPE_RISCV:6442 RegisterContextDarwin_riscv32_Mach::Create_LC_THREAD(6443 thread_sp.get(), LC_THREAD_datas[thread_idx]);6444 break;6445 }6446 }6447 }6448 6449 // The size of the load command is the size of the segments...6450 if (addr_byte_size == 8) {6451 mach_header.sizeofcmds = segment_load_commands.size() *6452 sizeof(llvm::MachO::segment_command_64);6453 } else {6454 mach_header.sizeofcmds = segment_load_commands.size() *6455 sizeof(llvm::MachO::segment_command);6456 }6457 6458 // and the size of all LC_THREAD load command6459 for (const auto &LC_THREAD_data : LC_THREAD_datas) {6460 ++mach_header.ncmds;6461 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();6462 }6463 6464 // Bits will be set to indicate which bits are NOT used in6465 // addressing in this process or 0 for unknown.6466 uint64_t address_mask = process_sp->GetCodeAddressMask();6467 if (address_mask != LLDB_INVALID_ADDRESS_MASK) {6468 // LC_NOTE "addrable bits"6469 mach_header.ncmds++;6470 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);6471 }6472 6473 // LC_NOTE "process metadata"6474 mach_header.ncmds++;6475 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);6476 6477 // LC_NOTE "all image infos"6478 mach_header.ncmds++;6479 mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);6480 6481 // Write the mach header6482 buffer.PutHex32(mach_header.magic);6483 buffer.PutHex32(mach_header.cputype);6484 buffer.PutHex32(mach_header.cpusubtype);6485 buffer.PutHex32(mach_header.filetype);6486 buffer.PutHex32(mach_header.ncmds);6487 buffer.PutHex32(mach_header.sizeofcmds);6488 buffer.PutHex32(mach_header.flags);6489 if (addr_byte_size == 8) {6490 buffer.PutHex32(mach_header.reserved);6491 }6492 6493 // Skip the mach header and all load commands and align to the next6494 // 0x1000 byte boundary6495 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;6496 6497 file_offset = llvm::alignTo(file_offset, 16);6498 std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;6499 6500 // Add "addrable bits" LC_NOTE when an address mask is available6501 if (address_mask != LLDB_INVALID_ADDRESS_MASK) {6502 std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(6503 new LCNoteEntry(addr_byte_size, byte_order));6504 addrable_bits_lcnote_up->name = "addrable bits";6505 addrable_bits_lcnote_up->payload_file_offset = file_offset;6506 int bits = std::bitset<64>(~address_mask).count();6507 addrable_bits_lcnote_up->payload.PutHex32(4); // version6508 addrable_bits_lcnote_up->payload.PutHex32(6509 bits); // # of bits used for low addresses6510 addrable_bits_lcnote_up->payload.PutHex32(6511 bits); // # of bits used for high addresses6512 addrable_bits_lcnote_up->payload.PutHex32(0); // reserved6513 6514 file_offset += addrable_bits_lcnote_up->payload.GetSize();6515 6516 lc_notes.push_back(std::move(addrable_bits_lcnote_up));6517 }6518 6519 // Add "process metadata" LC_NOTE6520 std::unique_ptr<LCNoteEntry> thread_extrainfo_lcnote_up(6521 new LCNoteEntry(addr_byte_size, byte_order));6522 thread_extrainfo_lcnote_up->name = "process metadata";6523 thread_extrainfo_lcnote_up->payload_file_offset = file_offset;6524 6525 StructuredData::DictionarySP dict(6526 std::make_shared<StructuredData::Dictionary>());6527 StructuredData::ArraySP threads(6528 std::make_shared<StructuredData::Array>());6529 for (const ThreadSP &thread_sp :6530 process_sp->CalculateCoreFileThreadList(options)) {6531 StructuredData::DictionarySP thread(6532 std::make_shared<StructuredData::Dictionary>());6533 thread->AddIntegerItem("thread_id", thread_sp->GetID());6534 threads->AddItem(thread);6535 }6536 dict->AddItem("threads", threads);6537 StreamString strm;6538 dict->Dump(strm, /* pretty */ false);6539 thread_extrainfo_lcnote_up->payload.PutRawBytes(strm.GetData(),6540 strm.GetSize());6541 6542 file_offset += thread_extrainfo_lcnote_up->payload.GetSize();6543 file_offset = llvm::alignTo(file_offset, 16);6544 lc_notes.push_back(std::move(thread_extrainfo_lcnote_up));6545 6546 // Add "all image infos" LC_NOTE6547 std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(6548 new LCNoteEntry(addr_byte_size, byte_order));6549 all_image_infos_lcnote_up->name = "all image infos";6550 all_image_infos_lcnote_up->payload_file_offset = file_offset;6551 file_offset = CreateAllImageInfosPayload(6552 process_sp, file_offset, all_image_infos_lcnote_up->payload,6553 options);6554 lc_notes.push_back(std::move(all_image_infos_lcnote_up));6555 6556 // Add LC_NOTE load commands6557 for (auto &lcnote : lc_notes) {6558 // Add the LC_NOTE load command to the file.6559 buffer.PutHex32(LC_NOTE);6560 buffer.PutHex32(sizeof(llvm::MachO::note_command));6561 char namebuf[16];6562 memset(namebuf, 0, sizeof(namebuf));6563 // This is the uncommon case where strncpy is exactly6564 // the right one, doesn't need to be nul terminated.6565 // LC_NOTE name field is char[16] and is not guaranteed to be6566 // nul-terminated.6567 // coverity[buffer_size_warning]6568 strncpy(namebuf, lcnote->name.c_str(), sizeof(namebuf));6569 buffer.PutRawBytes(namebuf, sizeof(namebuf));6570 buffer.PutHex64(lcnote->payload_file_offset);6571 buffer.PutHex64(lcnote->payload.GetSize());6572 }6573 6574 // Align to 4096-byte page boundary for the LC_SEGMENTs.6575 file_offset = llvm::alignTo(file_offset, 4096);6576 6577 for (auto &segment : segment_load_commands) {6578 segment.fileoff = file_offset;6579 file_offset += segment.filesize;6580 }6581 6582 // Write out all of the LC_THREAD load commands6583 for (const auto &LC_THREAD_data : LC_THREAD_datas) {6584 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();6585 buffer.PutHex32(LC_THREAD);6586 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data6587 buffer.Write(LC_THREAD_data.GetString().data(), LC_THREAD_data_size);6588 }6589 6590 // Write out all of the segment load commands6591 for (const auto &segment : segment_load_commands) {6592 buffer.PutHex32(segment.cmd);6593 buffer.PutHex32(segment.cmdsize);6594 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));6595 if (addr_byte_size == 8) {6596 buffer.PutHex64(segment.vmaddr);6597 buffer.PutHex64(segment.vmsize);6598 buffer.PutHex64(segment.fileoff);6599 buffer.PutHex64(segment.filesize);6600 } else {6601 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));6602 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));6603 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));6604 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));6605 }6606 buffer.PutHex32(segment.maxprot);6607 buffer.PutHex32(segment.initprot);6608 buffer.PutHex32(segment.nsects);6609 buffer.PutHex32(segment.flags);6610 }6611 6612 std::string core_file_path(outfile.GetPath());6613 auto core_file = FileSystem::Instance().Open(6614 outfile, File::eOpenOptionWriteOnly | File::eOpenOptionTruncate |6615 File::eOpenOptionCanCreate);6616 if (!core_file) {6617 error = Status::FromError(core_file.takeError());6618 } else {6619 // Read 1 page at a time6620 uint8_t bytes[0x1000];6621 // Write the mach header and load commands out to the core file6622 size_t bytes_written = buffer.GetString().size();6623 error =6624 core_file.get()->Write(buffer.GetString().data(), bytes_written);6625 if (error.Success()) {6626 6627 for (auto &lcnote : lc_notes) {6628 if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==6629 -1) {6630 error = Status::FromErrorStringWithFormat(6631 "Unable to seek to corefile pos "6632 "to write '%s' LC_NOTE payload",6633 lcnote->name.c_str());6634 return false;6635 }6636 bytes_written = lcnote->payload.GetSize();6637 error = core_file.get()->Write(lcnote->payload.GetData(),6638 bytes_written);6639 if (!error.Success())6640 return false;6641 }6642 6643 // Now write the file data for all memory segments in the process6644 for (const auto &segment : segment_load_commands) {6645 if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {6646 error = Status::FromErrorStringWithFormat(6647 "unable to seek to offset 0x%" PRIx64 " in '%s'",6648 segment.fileoff, core_file_path.c_str());6649 break;6650 }6651 6652 target.GetDebugger().GetAsyncOutputStream()->Printf(6653 "Saving %" PRId646654 " bytes of data for memory region at 0x%" PRIx64 "\n",6655 segment.vmsize, segment.vmaddr);6656 addr_t bytes_left = segment.vmsize;6657 addr_t addr = segment.vmaddr;6658 Status memory_read_error;6659 while (bytes_left > 0 && error.Success()) {6660 const size_t bytes_to_read =6661 bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;6662 6663 // In a savecore setting, we don't really care about caching,6664 // as the data is dumped and very likely never read again,6665 // so we call ReadMemoryFromInferior to bypass it.6666 const size_t bytes_read = process_sp->ReadMemoryFromInferior(6667 addr, bytes, bytes_to_read, memory_read_error);6668 6669 if (bytes_read == bytes_to_read) {6670 size_t bytes_written = bytes_read;6671 error = core_file.get()->Write(bytes, bytes_written);6672 bytes_left -= bytes_read;6673 addr += bytes_read;6674 } else {6675 // Some pages within regions are not readable, those should6676 // be zero filled6677 memset(bytes, 0, bytes_to_read);6678 size_t bytes_written = bytes_to_read;6679 error = core_file.get()->Write(bytes, bytes_written);6680 bytes_left -= bytes_to_read;6681 addr += bytes_to_read;6682 }6683 }6684 }6685 }6686 }6687 }6688 }6689 return true; // This is the right plug to handle saving core files for6690 // this process6691 }6692 return false;6693}6694 6695ObjectFileMachO::MachOCorefileAllImageInfos6696ObjectFileMachO::GetCorefileAllImageInfos() {6697 MachOCorefileAllImageInfos image_infos;6698 Log *log(GetLog(LLDBLog::Object | LLDBLog::Symbols | LLDBLog::Process |6699 LLDBLog::DynamicLoader));6700 6701 auto lc_notes = FindLC_NOTEByName("all image infos");6702 for (auto lc_note : lc_notes) {6703 offset_t payload_offset = std::get<0>(lc_note);6704 // Read the struct all_image_infos_header.6705 uint32_t version = m_data.GetU32(&payload_offset);6706 if (version != 1) {6707 return image_infos;6708 }6709 uint32_t imgcount = m_data.GetU32(&payload_offset);6710 uint64_t entries_fileoff = m_data.GetU64(&payload_offset);6711 // 'entries_size' is not used, nor is the 'unused' entry.6712 // offset += 4; // uint32_t entries_size;6713 // offset += 4; // uint32_t unused;6714 6715 LLDB_LOGF(log, "LC_NOTE 'all image infos' found version %d with %d images",6716 version, imgcount);6717 payload_offset = entries_fileoff;6718 for (uint32_t i = 0; i < imgcount; i++) {6719 // Read the struct image_entry.6720 offset_t filepath_offset = m_data.GetU64(&payload_offset);6721 uuid_t uuid;6722 memcpy(&uuid, m_data.GetData(&payload_offset, sizeof(uuid_t)),6723 sizeof(uuid_t));6724 uint64_t load_address = m_data.GetU64(&payload_offset);6725 offset_t seg_addrs_offset = m_data.GetU64(&payload_offset);6726 uint32_t segment_count = m_data.GetU32(&payload_offset);6727 uint32_t currently_executing = m_data.GetU32(&payload_offset);6728 6729 MachOCorefileImageEntry image_entry;6730 image_entry.filename = (const char *)m_data.GetCStr(&filepath_offset);6731 image_entry.uuid = UUID(uuid, sizeof(uuid_t));6732 image_entry.load_address = load_address;6733 image_entry.currently_executing = currently_executing;6734 6735 offset_t seg_vmaddrs_offset = seg_addrs_offset;6736 for (uint32_t j = 0; j < segment_count; j++) {6737 char segname[17];6738 m_data.CopyData(seg_vmaddrs_offset, 16, segname);6739 segname[16] = '\0';6740 seg_vmaddrs_offset += 16;6741 uint64_t vmaddr = m_data.GetU64(&seg_vmaddrs_offset);6742 seg_vmaddrs_offset += 8; /* unused */6743 6744 std::tuple<ConstString, addr_t> new_seg{ConstString(segname), vmaddr};6745 image_entry.segment_load_addresses.push_back(new_seg);6746 }6747 LLDB_LOGF(log, " image entry: %s %s 0x%" PRIx64 " %s",6748 image_entry.filename.c_str(),6749 image_entry.uuid.GetAsString().c_str(),6750 image_entry.load_address,6751 image_entry.currently_executing ? "currently executing"6752 : "not currently executing");6753 image_infos.all_image_infos.push_back(image_entry);6754 }6755 }6756 6757 lc_notes = FindLC_NOTEByName("load binary");6758 for (auto lc_note : lc_notes) {6759 offset_t payload_offset = std::get<0>(lc_note);6760 uint32_t version = m_data.GetU32(&payload_offset);6761 if (version == 1) {6762 uuid_t uuid;6763 memcpy(&uuid, m_data.GetData(&payload_offset, sizeof(uuid_t)),6764 sizeof(uuid_t));6765 uint64_t load_address = m_data.GetU64(&payload_offset);6766 uint64_t slide = m_data.GetU64(&payload_offset);6767 std::string filename = m_data.GetCStr(&payload_offset);6768 6769 MachOCorefileImageEntry image_entry;6770 image_entry.filename = filename;6771 image_entry.uuid = UUID(uuid, sizeof(uuid_t));6772 image_entry.load_address = load_address;6773 image_entry.slide = slide;6774 image_entry.currently_executing = true;6775 image_infos.all_image_infos.push_back(image_entry);6776 LLDB_LOGF(log,6777 "LC_NOTE 'load binary' found, filename %s uuid %s load "6778 "address 0x%" PRIx64 " slide 0x%" PRIx64,6779 filename.c_str(),6780 image_entry.uuid.IsValid()6781 ? image_entry.uuid.GetAsString().c_str()6782 : "00000000-0000-0000-0000-000000000000",6783 load_address, slide);6784 }6785 }6786 6787 return image_infos;6788}6789 6790bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {6791 MachOCorefileAllImageInfos image_infos = GetCorefileAllImageInfos();6792 Log *log = GetLog(LLDBLog::Object | LLDBLog::DynamicLoader);6793 Status error;6794 6795 bool found_platform_binary = false;6796 ModuleList added_modules;6797 for (MachOCorefileImageEntry &image : image_infos.all_image_infos) {6798 ModuleSP module_sp, local_filesystem_module_sp;6799 6800 // If this is a platform binary, it has been loaded (or registered with6801 // the DynamicLoader to be loaded), we don't need to do any further6802 // processing. We're not going to call ModulesDidLoad on this in this6803 // method, so notify==true.6804 if (process.GetTarget()6805 .GetDebugger()6806 .GetPlatformList()6807 .LoadPlatformBinaryAndSetup(&process, image.load_address,6808 true /* notify */)) {6809 LLDB_LOGF(log,6810 "ObjectFileMachO::%s binary at 0x%" PRIx646811 " is a platform binary, has been handled by a Platform plugin.",6812 __FUNCTION__, image.load_address);6813 continue;6814 }6815 6816 bool value_is_offset = image.load_address == LLDB_INVALID_ADDRESS;6817 uint64_t value = value_is_offset ? image.slide : image.load_address;6818 if (value_is_offset && value == LLDB_INVALID_ADDRESS) {6819 // We have neither address nor slide; so we will find the binary6820 // by UUID and load it at slide/offset 0.6821 value = 0;6822 }6823 6824 // We have either a UUID, or we have a load address which6825 // and can try to read load commands and find a UUID.6826 if (image.uuid.IsValid() ||6827 (!value_is_offset && value != LLDB_INVALID_ADDRESS)) {6828 const bool set_load_address = image.segment_load_addresses.size() == 0;6829 const bool notify = false;6830 // Userland Darwin binaries will have segment load addresses via6831 // the `all image infos` LC_NOTE.6832 const bool allow_memory_image_last_resort =6833 image.segment_load_addresses.size();6834 module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(6835 &process, image.filename, image.uuid, value, value_is_offset,6836 image.currently_executing, notify, set_load_address,6837 allow_memory_image_last_resort);6838 }6839 6840 // We have a ModuleSP to load in the Target. Load it at the6841 // correct address/slide and notify/load scripting resources.6842 if (module_sp) {6843 added_modules.Append(module_sp, false /* notify */);6844 6845 // We have a list of segment load address6846 if (image.segment_load_addresses.size() > 0) {6847 if (log) {6848 std::string uuidstr = image.uuid.GetAsString();6849 log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "6850 "UUID %s with section load addresses",6851 module_sp->GetFileSpec().GetPath().c_str(),6852 uuidstr.c_str());6853 }6854 for (auto name_vmaddr_tuple : image.segment_load_addresses) {6855 SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList();6856 if (sectlist) {6857 SectionSP sect_sp =6858 sectlist->FindSectionByName(std::get<0>(name_vmaddr_tuple));6859 if (sect_sp) {6860 process.GetTarget().SetSectionLoadAddress(6861 sect_sp, std::get<1>(name_vmaddr_tuple));6862 }6863 }6864 }6865 } else {6866 if (log) {6867 std::string uuidstr = image.uuid.GetAsString();6868 log->Printf("ObjectFileMachO::LoadCoreFileImages adding binary '%s' "6869 "UUID %s with %s 0x%" PRIx64,6870 module_sp->GetFileSpec().GetPath().c_str(),6871 uuidstr.c_str(),6872 value_is_offset ? "slide" : "load address", value);6873 }6874 bool changed;6875 module_sp->SetLoadAddress(process.GetTarget(), value, value_is_offset,6876 changed);6877 }6878 }6879 }6880 if (added_modules.GetSize() > 0) {6881 process.GetTarget().ModulesDidLoad(added_modules);6882 process.Flush();6883 return true;6884 }6885 // Return true if the only binary we found was the platform binary,6886 // and it was loaded outside the scope of this method.6887 if (found_platform_binary)6888 return true;6889 6890 // No binaries.6891 return false;6892}6893