brintos

brintos / llvm-project-archived public Read only

0
0
Text · 273.7 KiB · 2218c23 Raw
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(&sect64, 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, &sect64.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                                 &region_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 &section) 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