Bug Summary

File:tools/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Warning:line 4248, column 47
Array access (from variable 'symbol_name') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ObjectFileMachO.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D LLDB_USE_BUILTIN_DEMANGLER -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/source/Plugins/ObjectFile/Mach-O -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/ObjectFile/Mach-O -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/source/Plugins/ObjectFile/Mach-O -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c++ /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
1//===-- ObjectFileMachO.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
13#include "llvm/ADT/StringRef.h"
14
15// Project includes
16#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
17#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
18#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
19#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
20#include "lldb/Core/Debugger.h"
21#include "lldb/Core/FileSpecList.h"
22#include "lldb/Core/Module.h"
23#include "lldb/Core/ModuleSpec.h"
24#include "lldb/Core/PluginManager.h"
25#include "lldb/Core/RangeMap.h"
26#include "lldb/Core/RegisterValue.h"
27#include "lldb/Core/Section.h"
28#include "lldb/Core/StreamFile.h"
29#include "lldb/Host/Host.h"
30#include "lldb/Symbol/DWARFCallFrameInfo.h"
31#include "lldb/Symbol/ObjectFile.h"
32#include "lldb/Target/DynamicLoader.h"
33#include "lldb/Target/MemoryRegionInfo.h"
34#include "lldb/Target/Platform.h"
35#include "lldb/Target/Process.h"
36#include "lldb/Target/SectionLoadList.h"
37#include "lldb/Target/Target.h"
38#include "lldb/Target/Thread.h"
39#include "lldb/Target/ThreadList.h"
40#include "lldb/Utility/ArchSpec.h"
41#include "lldb/Utility/DataBuffer.h"
42#include "lldb/Utility/FileSpec.h"
43#include "lldb/Utility/Log.h"
44#include "lldb/Utility/Status.h"
45#include "lldb/Utility/StreamString.h"
46#include "lldb/Utility/Timer.h"
47#include "lldb/Utility/UUID.h"
48
49#include "lldb/Utility/SafeMachO.h"
50
51#include "llvm/Support/MemoryBuffer.h"
52
53#include "ObjectFileMachO.h"
54
55#if defined(__APPLE__) && \
56 (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
57// GetLLDBSharedCacheUUID() needs to call dlsym()
58#include <dlfcn.h>
59#endif
60
61#ifndef __APPLE__
62#include "Utility/UuidCompatibility.h"
63#else
64#include <uuid/uuid.h>
65#endif
66
67#define THUMB_ADDRESS_BIT_MASK0xfffffffffffffffeull 0xfffffffffffffffeull
68using namespace lldb;
69using namespace lldb_private;
70using namespace llvm::MachO;
71
72// Some structure definitions needed for parsing the dyld shared cache files
73// found on iOS devices.
74
75struct lldb_copy_dyld_cache_header_v1 {
76 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
77 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
78 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
79 uint32_t imagesOffset;
80 uint32_t imagesCount;
81 uint64_t dyldBaseAddress;
82 uint64_t codeSignatureOffset;
83 uint64_t codeSignatureSize;
84 uint64_t slideInfoOffset;
85 uint64_t slideInfoSize;
86 uint64_t localSymbolsOffset;
87 uint64_t localSymbolsSize;
88 uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13
89 // and later
90};
91
92struct lldb_copy_dyld_cache_mapping_info {
93 uint64_t address;
94 uint64_t size;
95 uint64_t fileOffset;
96 uint32_t maxProt;
97 uint32_t initProt;
98};
99
100struct lldb_copy_dyld_cache_local_symbols_info {
101 uint32_t nlistOffset;
102 uint32_t nlistCount;
103 uint32_t stringsOffset;
104 uint32_t stringsSize;
105 uint32_t entriesOffset;
106 uint32_t entriesCount;
107};
108struct lldb_copy_dyld_cache_local_symbols_entry {
109 uint32_t dylibOffset;
110 uint32_t nlistStartIndex;
111 uint32_t nlistCount;
112};
113
114class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 {
115public:
116 RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread,
117 const DataExtractor &data)
118 : RegisterContextDarwin_x86_64(thread, 0) {
119 SetRegisterDataFrom_LC_THREAD(data);
120 }
121
122 void InvalidateAllRegisters() override {
123 // Do nothing... registers are always valid...
124 }
125
126 void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
127 lldb::offset_t offset = 0;
128 SetError(GPRRegSet, Read, -1);
129 SetError(FPURegSet, Read, -1);
130 SetError(EXCRegSet, Read, -1);
131 bool done = false;
132
133 while (!done) {
134 int flavor = data.GetU32(&offset);
135 if (flavor == 0)
136 done = true;
137 else {
138 uint32_t i;
139 uint32_t count = data.GetU32(&offset);
140 switch (flavor) {
141 case GPRRegSet:
142 for (i = 0; i < count; ++i)
143 (&gpr.rax)[i] = data.GetU64(&offset);
144 SetError(GPRRegSet, Read, 0);
145 done = true;
146
147 break;
148 case FPURegSet:
149 // TODO: fill in FPU regs....
150 // SetError (FPURegSet, Read, -1);
151 done = true;
152
153 break;
154 case EXCRegSet:
155 exc.trapno = data.GetU32(&offset);
156 exc.err = data.GetU32(&offset);
157 exc.faultvaddr = data.GetU64(&offset);
158 SetError(EXCRegSet, Read, 0);
159 done = true;
160 break;
161 case 7:
162 case 8:
163 case 9:
164 // fancy flavors that encapsulate of the above
165 // flavors...
166 break;
167
168 default:
169 done = true;
170 break;
171 }
172 }
173 }
174 }
175
176 static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
177 const char *alt_name, size_t reg_byte_size,
178 Stream &data) {
179 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
180 if (reg_info == NULL__null)
181 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
182 if (reg_info) {
183 lldb_private::RegisterValue reg_value;
184 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
185 if (reg_info->byte_size >= reg_byte_size)
186 data.Write(reg_value.GetBytes(), reg_byte_size);
187 else {
188 data.Write(reg_value.GetBytes(), reg_info->byte_size);
189 for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
190 ++i)
191 data.PutChar(0);
192 }
193 return reg_byte_size;
194 }
195 }
196 // Just write zeros if all else fails
197 for (size_t i = 0; i < reg_byte_size; ++i)
198 data.PutChar(0);
199 return reg_byte_size;
200 }
201
202 static bool Create_LC_THREAD(Thread *thread, Stream &data) {
203 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
204 if (reg_ctx_sp) {
205 RegisterContext *reg_ctx = reg_ctx_sp.get();
206
207 data.PutHex32(GPRRegSet); // Flavor
208 data.PutHex32(GPRWordCount);
209 WriteRegister(reg_ctx, "rax", NULL__null, 8, data);
210 WriteRegister(reg_ctx, "rbx", NULL__null, 8, data);
211 WriteRegister(reg_ctx, "rcx", NULL__null, 8, data);
212 WriteRegister(reg_ctx, "rdx", NULL__null, 8, data);
213 WriteRegister(reg_ctx, "rdi", NULL__null, 8, data);
214 WriteRegister(reg_ctx, "rsi", NULL__null, 8, data);
215 WriteRegister(reg_ctx, "rbp", NULL__null, 8, data);
216 WriteRegister(reg_ctx, "rsp", NULL__null, 8, data);
217 WriteRegister(reg_ctx, "r8", NULL__null, 8, data);
218 WriteRegister(reg_ctx, "r9", NULL__null, 8, data);
219 WriteRegister(reg_ctx, "r10", NULL__null, 8, data);
220 WriteRegister(reg_ctx, "r11", NULL__null, 8, data);
221 WriteRegister(reg_ctx, "r12", NULL__null, 8, data);
222 WriteRegister(reg_ctx, "r13", NULL__null, 8, data);
223 WriteRegister(reg_ctx, "r14", NULL__null, 8, data);
224 WriteRegister(reg_ctx, "r15", NULL__null, 8, data);
225 WriteRegister(reg_ctx, "rip", NULL__null, 8, data);
226 WriteRegister(reg_ctx, "rflags", NULL__null, 8, data);
227 WriteRegister(reg_ctx, "cs", NULL__null, 8, data);
228 WriteRegister(reg_ctx, "fs", NULL__null, 8, data);
229 WriteRegister(reg_ctx, "gs", NULL__null, 8, data);
230
231 // // Write out the FPU registers
232 // const size_t fpu_byte_size = sizeof(FPU);
233 // size_t bytes_written = 0;
234 // data.PutHex32 (FPURegSet);
235 // data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
236 // bytes_written += data.PutHex32(0); // uint32_t pad[0]
237 // bytes_written += data.PutHex32(0); // uint32_t pad[1]
238 // bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2,
239 // data); // uint16_t fcw; // "fctrl"
240 // bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2,
241 // data); // uint16_t fsw; // "fstat"
242 // bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1,
243 // data); // uint8_t ftw; // "ftag"
244 // bytes_written += data.PutHex8 (0); // uint8_t pad1;
245 // bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2,
246 // data); // uint16_t fop; // "fop"
247 // bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4,
248 // data); // uint32_t ip; // "fioff"
249 // bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2,
250 // data); // uint16_t cs; // "fiseg"
251 // bytes_written += data.PutHex16 (0); // uint16_t pad2;
252 // bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4,
253 // data); // uint32_t dp; // "fooff"
254 // bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2,
255 // data); // uint16_t ds; // "foseg"
256 // bytes_written += data.PutHex16 (0); // uint16_t pad3;
257 // bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4,
258 // data); // uint32_t mxcsr;
259 // bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL,
260 // 4, data);// uint32_t mxcsrmask;
261 // bytes_written += WriteRegister (reg_ctx, "stmm0", NULL,
262 // sizeof(MMSReg), data);
263 // bytes_written += WriteRegister (reg_ctx, "stmm1", NULL,
264 // sizeof(MMSReg), data);
265 // bytes_written += WriteRegister (reg_ctx, "stmm2", NULL,
266 // sizeof(MMSReg), data);
267 // bytes_written += WriteRegister (reg_ctx, "stmm3", NULL,
268 // sizeof(MMSReg), data);
269 // bytes_written += WriteRegister (reg_ctx, "stmm4", NULL,
270 // sizeof(MMSReg), data);
271 // bytes_written += WriteRegister (reg_ctx, "stmm5", NULL,
272 // sizeof(MMSReg), data);
273 // bytes_written += WriteRegister (reg_ctx, "stmm6", NULL,
274 // sizeof(MMSReg), data);
275 // bytes_written += WriteRegister (reg_ctx, "stmm7", NULL,
276 // sizeof(MMSReg), data);
277 // bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL,
278 // sizeof(XMMReg), data);
279 // bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL,
280 // sizeof(XMMReg), data);
281 // bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL,
282 // sizeof(XMMReg), data);
283 // bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL,
284 // sizeof(XMMReg), data);
285 // bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL,
286 // sizeof(XMMReg), data);
287 // bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL,
288 // sizeof(XMMReg), data);
289 // bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL,
290 // sizeof(XMMReg), data);
291 // bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL,
292 // sizeof(XMMReg), data);
293 // bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL,
294 // sizeof(XMMReg), data);
295 // bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL,
296 // sizeof(XMMReg), data);
297 // bytes_written += WriteRegister (reg_ctx, "xmm10", NULL,
298 // sizeof(XMMReg), data);
299 // bytes_written += WriteRegister (reg_ctx, "xmm11", NULL,
300 // sizeof(XMMReg), data);
301 // bytes_written += WriteRegister (reg_ctx, "xmm12", NULL,
302 // sizeof(XMMReg), data);
303 // bytes_written += WriteRegister (reg_ctx, "xmm13", NULL,
304 // sizeof(XMMReg), data);
305 // bytes_written += WriteRegister (reg_ctx, "xmm14", NULL,
306 // sizeof(XMMReg), data);
307 // bytes_written += WriteRegister (reg_ctx, "xmm15", NULL,
308 // sizeof(XMMReg), data);
309 //
310 // // Fill rest with zeros
311 // for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++
312 // i)
313 // data.PutChar(0);
314
315 // Write out the EXC registers
316 data.PutHex32(EXCRegSet);
317 data.PutHex32(EXCWordCount);
318 WriteRegister(reg_ctx, "trapno", NULL__null, 4, data);
319 WriteRegister(reg_ctx, "err", NULL__null, 4, data);
320 WriteRegister(reg_ctx, "faultvaddr", NULL__null, 8, data);
321 return true;
322 }
323 return false;
324 }
325
326protected:
327 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }
328
329 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }
330
331 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }
332
333 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
334 return 0;
335 }
336
337 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
338 return 0;
339 }
340
341 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
342 return 0;
343 }
344};
345
346class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386 {
347public:
348 RegisterContextDarwin_i386_Mach(lldb_private::Thread &thread,
349 const DataExtractor &data)
350 : RegisterContextDarwin_i386(thread, 0) {
351 SetRegisterDataFrom_LC_THREAD(data);
352 }
353
354 void InvalidateAllRegisters() override {
355 // Do nothing... registers are always valid...
356 }
357
358 void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
359 lldb::offset_t offset = 0;
360 SetError(GPRRegSet, Read, -1);
361 SetError(FPURegSet, Read, -1);
362 SetError(EXCRegSet, Read, -1);
363 bool done = false;
364
365 while (!done) {
366 int flavor = data.GetU32(&offset);
367 if (flavor == 0)
368 done = true;
369 else {
370 uint32_t i;
371 uint32_t count = data.GetU32(&offset);
372 switch (flavor) {
373 case GPRRegSet:
374 for (i = 0; i < count; ++i)
375 (&gpr.eax)[i] = data.GetU32(&offset);
376 SetError(GPRRegSet, Read, 0);
377 done = true;
378
379 break;
380 case FPURegSet:
381 // TODO: fill in FPU regs....
382 // SetError (FPURegSet, Read, -1);
383 done = true;
384
385 break;
386 case EXCRegSet:
387 exc.trapno = data.GetU32(&offset);
388 exc.err = data.GetU32(&offset);
389 exc.faultvaddr = data.GetU32(&offset);
390 SetError(EXCRegSet, Read, 0);
391 done = true;
392 break;
393 case 7:
394 case 8:
395 case 9:
396 // fancy flavors that encapsulate of the above
397 // flavors...
398 break;
399
400 default:
401 done = true;
402 break;
403 }
404 }
405 }
406 }
407
408 static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
409 const char *alt_name, size_t reg_byte_size,
410 Stream &data) {
411 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
412 if (reg_info == NULL__null)
413 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
414 if (reg_info) {
415 lldb_private::RegisterValue reg_value;
416 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
417 if (reg_info->byte_size >= reg_byte_size)
418 data.Write(reg_value.GetBytes(), reg_byte_size);
419 else {
420 data.Write(reg_value.GetBytes(), reg_info->byte_size);
421 for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
422 ++i)
423 data.PutChar(0);
424 }
425 return reg_byte_size;
426 }
427 }
428 // Just write zeros if all else fails
429 for (size_t i = 0; i < reg_byte_size; ++i)
430 data.PutChar(0);
431 return reg_byte_size;
432 }
433
434 static bool Create_LC_THREAD(Thread *thread, Stream &data) {
435 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
436 if (reg_ctx_sp) {
437 RegisterContext *reg_ctx = reg_ctx_sp.get();
438
439 data.PutHex32(GPRRegSet); // Flavor
440 data.PutHex32(GPRWordCount);
441 WriteRegister(reg_ctx, "eax", NULL__null, 4, data);
442 WriteRegister(reg_ctx, "ebx", NULL__null, 4, data);
443 WriteRegister(reg_ctx, "ecx", NULL__null, 4, data);
444 WriteRegister(reg_ctx, "edx", NULL__null, 4, data);
445 WriteRegister(reg_ctx, "edi", NULL__null, 4, data);
446 WriteRegister(reg_ctx, "esi", NULL__null, 4, data);
447 WriteRegister(reg_ctx, "ebp", NULL__null, 4, data);
448 WriteRegister(reg_ctx, "esp", NULL__null, 4, data);
449 WriteRegister(reg_ctx, "ss", NULL__null, 4, data);
450 WriteRegister(reg_ctx, "eflags", NULL__null, 4, data);
451 WriteRegister(reg_ctx, "eip", NULL__null, 4, data);
452 WriteRegister(reg_ctx, "cs", NULL__null, 4, data);
453 WriteRegister(reg_ctx, "ds", NULL__null, 4, data);
454 WriteRegister(reg_ctx, "es", NULL__null, 4, data);
455 WriteRegister(reg_ctx, "fs", NULL__null, 4, data);
456 WriteRegister(reg_ctx, "gs", NULL__null, 4, data);
457
458 // Write out the EXC registers
459 data.PutHex32(EXCRegSet);
460 data.PutHex32(EXCWordCount);
461 WriteRegister(reg_ctx, "trapno", NULL__null, 4, data);
462 WriteRegister(reg_ctx, "err", NULL__null, 4, data);
463 WriteRegister(reg_ctx, "faultvaddr", NULL__null, 4, data);
464 return true;
465 }
466 return false;
467 }
468
469protected:
470 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; }
471
472 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; }
473
474 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; }
475
476 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
477 return 0;
478 }
479
480 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
481 return 0;
482 }
483
484 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
485 return 0;
486 }
487};
488
489class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm {
490public:
491 RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread,
492 const DataExtractor &data)
493 : RegisterContextDarwin_arm(thread, 0) {
494 SetRegisterDataFrom_LC_THREAD(data);
495 }
496
497 void InvalidateAllRegisters() override {
498 // Do nothing... registers are always valid...
499 }
500
501 void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
502 lldb::offset_t offset = 0;
503 SetError(GPRRegSet, Read, -1);
504 SetError(FPURegSet, Read, -1);
505 SetError(EXCRegSet, Read, -1);
506 bool done = false;
507
508 while (!done) {
509 int flavor = data.GetU32(&offset);
510 uint32_t count = data.GetU32(&offset);
511 lldb::offset_t next_thread_state = offset + (count * 4);
512 switch (flavor) {
513 case GPRAltRegSet:
514 case GPRRegSet:
515 for (uint32_t i = 0; i < count; ++i) {
516 gpr.r[i] = data.GetU32(&offset);
517 }
518
519 // Note that gpr.cpsr is also copied by the above loop; this loop
520 // technically extends
521 // one element past the end of the gpr.r[] array.
522
523 SetError(GPRRegSet, Read, 0);
524 offset = next_thread_state;
525 break;
526
527 case FPURegSet: {
528 uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats.s[0];
529 const int fpu_reg_buf_size = sizeof(fpu.floats);
530 if (data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
531 fpu_reg_buf) == fpu_reg_buf_size) {
532 offset += fpu_reg_buf_size;
533 fpu.fpscr = data.GetU32(&offset);
534 SetError(FPURegSet, Read, 0);
535 } else {
536 done = true;
537 }
538 }
539 offset = next_thread_state;
540 break;
541
542 case EXCRegSet:
543 if (count == 3) {
544 exc.exception = data.GetU32(&offset);
545 exc.fsr = data.GetU32(&offset);
546 exc.far = data.GetU32(&offset);
547 SetError(EXCRegSet, Read, 0);
548 }
549 done = true;
550 offset = next_thread_state;
551 break;
552
553 // Unknown register set flavor, stop trying to parse.
554 default:
555 done = true;
556 }
557 }
558 }
559
560 static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
561 const char *alt_name, size_t reg_byte_size,
562 Stream &data) {
563 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
564 if (reg_info == NULL__null)
565 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
566 if (reg_info) {
567 lldb_private::RegisterValue reg_value;
568 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
569 if (reg_info->byte_size >= reg_byte_size)
570 data.Write(reg_value.GetBytes(), reg_byte_size);
571 else {
572 data.Write(reg_value.GetBytes(), reg_info->byte_size);
573 for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
574 ++i)
575 data.PutChar(0);
576 }
577 return reg_byte_size;
578 }
579 }
580 // Just write zeros if all else fails
581 for (size_t i = 0; i < reg_byte_size; ++i)
582 data.PutChar(0);
583 return reg_byte_size;
584 }
585
586 static bool Create_LC_THREAD(Thread *thread, Stream &data) {
587 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
588 if (reg_ctx_sp) {
589 RegisterContext *reg_ctx = reg_ctx_sp.get();
590
591 data.PutHex32(GPRRegSet); // Flavor
592 data.PutHex32(GPRWordCount);
593 WriteRegister(reg_ctx, "r0", NULL__null, 4, data);
594 WriteRegister(reg_ctx, "r1", NULL__null, 4, data);
595 WriteRegister(reg_ctx, "r2", NULL__null, 4, data);
596 WriteRegister(reg_ctx, "r3", NULL__null, 4, data);
597 WriteRegister(reg_ctx, "r4", NULL__null, 4, data);
598 WriteRegister(reg_ctx, "r5", NULL__null, 4, data);
599 WriteRegister(reg_ctx, "r6", NULL__null, 4, data);
600 WriteRegister(reg_ctx, "r7", NULL__null, 4, data);
601 WriteRegister(reg_ctx, "r8", NULL__null, 4, data);
602 WriteRegister(reg_ctx, "r9", NULL__null, 4, data);
603 WriteRegister(reg_ctx, "r10", NULL__null, 4, data);
604 WriteRegister(reg_ctx, "r11", NULL__null, 4, data);
605 WriteRegister(reg_ctx, "r12", NULL__null, 4, data);
606 WriteRegister(reg_ctx, "sp", NULL__null, 4, data);
607 WriteRegister(reg_ctx, "lr", NULL__null, 4, data);
608 WriteRegister(reg_ctx, "pc", NULL__null, 4, data);
609 WriteRegister(reg_ctx, "cpsr", NULL__null, 4, data);
610
611 // Write out the EXC registers
612 // data.PutHex32 (EXCRegSet);
613 // data.PutHex32 (EXCWordCount);
614 // WriteRegister (reg_ctx, "exception", NULL, 4, data);
615 // WriteRegister (reg_ctx, "fsr", NULL, 4, data);
616 // WriteRegister (reg_ctx, "far", NULL, 4, data);
617 return true;
618 }
619 return false;
620 }
621
622protected:
623 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
624
625 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
626
627 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
628
629 int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }
630
631 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
632 return 0;
633 }
634
635 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
636 return 0;
637 }
638
639 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
640 return 0;
641 }
642
643 int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
644 return -1;
645 }
646};
647
648class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 {
649public:
650 RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread,
651 const DataExtractor &data)
652 : RegisterContextDarwin_arm64(thread, 0) {
653 SetRegisterDataFrom_LC_THREAD(data);
654 }
655
656 void InvalidateAllRegisters() override {
657 // Do nothing... registers are always valid...
658 }
659
660 void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) {
661 lldb::offset_t offset = 0;
662 SetError(GPRRegSet, Read, -1);
663 SetError(FPURegSet, Read, -1);
664 SetError(EXCRegSet, Read, -1);
665 bool done = false;
666 while (!done) {
667 int flavor = data.GetU32(&offset);
668 uint32_t count = data.GetU32(&offset);
669 lldb::offset_t next_thread_state = offset + (count * 4);
670 switch (flavor) {
671 case GPRRegSet:
672 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1
673 // 32-bit register)
674 if (count >= (33 * 2) + 1) {
675 for (uint32_t i = 0; i < 29; ++i)
676 gpr.x[i] = data.GetU64(&offset);
677 gpr.fp = data.GetU64(&offset);
678 gpr.lr = data.GetU64(&offset);
679 gpr.sp = data.GetU64(&offset);
680 gpr.pc = data.GetU64(&offset);
681 gpr.cpsr = data.GetU32(&offset);
682 SetError(GPRRegSet, Read, 0);
683 }
684 offset = next_thread_state;
685 break;
686 case FPURegSet: {
687 uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0];
688 const int fpu_reg_buf_size = sizeof(fpu);
689 if (fpu_reg_buf_size == count * sizeof(uint32_t) &&
690 data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle,
691 fpu_reg_buf) == fpu_reg_buf_size) {
692 SetError(FPURegSet, Read, 0);
693 } else {
694 done = true;
695 }
696 }
697 offset = next_thread_state;
698 break;
699 case EXCRegSet:
700 if (count == 4) {
701 exc.far = data.GetU64(&offset);
702 exc.esr = data.GetU32(&offset);
703 exc.exception = data.GetU32(&offset);
704 SetError(EXCRegSet, Read, 0);
705 }
706 offset = next_thread_state;
707 break;
708 default:
709 done = true;
710 break;
711 }
712 }
713 }
714
715 static size_t WriteRegister(RegisterContext *reg_ctx, const char *name,
716 const char *alt_name, size_t reg_byte_size,
717 Stream &data) {
718 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
719 if (reg_info == NULL__null)
720 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
721 if (reg_info) {
722 lldb_private::RegisterValue reg_value;
723 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
724 if (reg_info->byte_size >= reg_byte_size)
725 data.Write(reg_value.GetBytes(), reg_byte_size);
726 else {
727 data.Write(reg_value.GetBytes(), reg_info->byte_size);
728 for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n;
729 ++i)
730 data.PutChar(0);
731 }
732 return reg_byte_size;
733 }
734 }
735 // Just write zeros if all else fails
736 for (size_t i = 0; i < reg_byte_size; ++i)
737 data.PutChar(0);
738 return reg_byte_size;
739 }
740
741 static bool Create_LC_THREAD(Thread *thread, Stream &data) {
742 RegisterContextSP reg_ctx_sp(thread->GetRegisterContext());
743 if (reg_ctx_sp) {
744 RegisterContext *reg_ctx = reg_ctx_sp.get();
745
746 data.PutHex32(GPRRegSet); // Flavor
747 data.PutHex32(GPRWordCount);
748 WriteRegister(reg_ctx, "x0", NULL__null, 8, data);
749 WriteRegister(reg_ctx, "x1", NULL__null, 8, data);
750 WriteRegister(reg_ctx, "x2", NULL__null, 8, data);
751 WriteRegister(reg_ctx, "x3", NULL__null, 8, data);
752 WriteRegister(reg_ctx, "x4", NULL__null, 8, data);
753 WriteRegister(reg_ctx, "x5", NULL__null, 8, data);
754 WriteRegister(reg_ctx, "x6", NULL__null, 8, data);
755 WriteRegister(reg_ctx, "x7", NULL__null, 8, data);
756 WriteRegister(reg_ctx, "x8", NULL__null, 8, data);
757 WriteRegister(reg_ctx, "x9", NULL__null, 8, data);
758 WriteRegister(reg_ctx, "x10", NULL__null, 8, data);
759 WriteRegister(reg_ctx, "x11", NULL__null, 8, data);
760 WriteRegister(reg_ctx, "x12", NULL__null, 8, data);
761 WriteRegister(reg_ctx, "x13", NULL__null, 8, data);
762 WriteRegister(reg_ctx, "x14", NULL__null, 8, data);
763 WriteRegister(reg_ctx, "x15", NULL__null, 8, data);
764 WriteRegister(reg_ctx, "x16", NULL__null, 8, data);
765 WriteRegister(reg_ctx, "x17", NULL__null, 8, data);
766 WriteRegister(reg_ctx, "x18", NULL__null, 8, data);
767 WriteRegister(reg_ctx, "x19", NULL__null, 8, data);
768 WriteRegister(reg_ctx, "x20", NULL__null, 8, data);
769 WriteRegister(reg_ctx, "x21", NULL__null, 8, data);
770 WriteRegister(reg_ctx, "x22", NULL__null, 8, data);
771 WriteRegister(reg_ctx, "x23", NULL__null, 8, data);
772 WriteRegister(reg_ctx, "x24", NULL__null, 8, data);
773 WriteRegister(reg_ctx, "x25", NULL__null, 8, data);
774 WriteRegister(reg_ctx, "x26", NULL__null, 8, data);
775 WriteRegister(reg_ctx, "x27", NULL__null, 8, data);
776 WriteRegister(reg_ctx, "x28", NULL__null, 8, data);
777 WriteRegister(reg_ctx, "fp", NULL__null, 8, data);
778 WriteRegister(reg_ctx, "lr", NULL__null, 8, data);
779 WriteRegister(reg_ctx, "sp", NULL__null, 8, data);
780 WriteRegister(reg_ctx, "pc", NULL__null, 8, data);
781 WriteRegister(reg_ctx, "cpsr", NULL__null, 4, data);
782
783 // Write out the EXC registers
784 // data.PutHex32 (EXCRegSet);
785 // data.PutHex32 (EXCWordCount);
786 // WriteRegister (reg_ctx, "far", NULL, 8, data);
787 // WriteRegister (reg_ctx, "esr", NULL, 4, data);
788 // WriteRegister (reg_ctx, "exception", NULL, 4, data);
789 return true;
790 }
791 return false;
792 }
793
794protected:
795 int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; }
796
797 int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; }
798
799 int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; }
800
801 int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; }
802
803 int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override {
804 return 0;
805 }
806
807 int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override {
808 return 0;
809 }
810
811 int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {
812 return 0;
813 }
814
815 int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override {
816 return -1;
817 }
818};
819
820static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
821 switch (magic) {
822 case MH_MAGIC:
823 case MH_CIGAM:
824 return sizeof(struct mach_header);
825
826 case MH_MAGIC_64:
827 case MH_CIGAM_64:
828 return sizeof(struct mach_header_64);
829 break;
830
831 default:
832 break;
833 }
834 return 0;
835}
836
837#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB0x0008 0x0008
838
839void ObjectFileMachO::Initialize() {
840 PluginManager::RegisterPlugin(
841 GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
842 CreateMemoryInstance, GetModuleSpecifications, SaveCore);
843}
844
845void ObjectFileMachO::Terminate() {
846 PluginManager::UnregisterPlugin(CreateInstance);
847}
848
849lldb_private::ConstString ObjectFileMachO::GetPluginNameStatic() {
850 static ConstString g_name("mach-o");
851 return g_name;
852}
853
854const char *ObjectFileMachO::GetPluginDescriptionStatic() {
855 return "Mach-o object file reader (32 and 64 bit)";
856}
857
858ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp,
859 DataBufferSP &data_sp,
860 lldb::offset_t data_offset,
861 const FileSpec *file,
862 lldb::offset_t file_offset,
863 lldb::offset_t length) {
864 if (!data_sp) {
865 data_sp = MapFileData(*file, length, file_offset);
866 if (!data_sp)
867 return nullptr;
868 data_offset = 0;
869 }
870
871 if (!ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
872 return nullptr;
873
874 // Update the data to contain the entire file if it doesn't already
875 if (data_sp->GetByteSize() < length) {
876 data_sp = MapFileData(*file, length, file_offset);
877 if (!data_sp)
878 return nullptr;
879 data_offset = 0;
880 }
881 auto objfile_ap = llvm::make_unique<ObjectFileMachO>(
882 module_sp, data_sp, data_offset, file, file_offset, length);
883 if (!objfile_ap || !objfile_ap->ParseHeader())
884 return nullptr;
885
886 return objfile_ap.release();
887}
888
889ObjectFile *ObjectFileMachO::CreateMemoryInstance(
890 const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
891 const ProcessSP &process_sp, lldb::addr_t header_addr) {
892 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
893 std::unique_ptr<ObjectFile> objfile_ap(
894 new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr));
895 if (objfile_ap.get() && objfile_ap->ParseHeader())
896 return objfile_ap.release();
897 }
898 return NULL__null;
899}
900
901size_t ObjectFileMachO::GetModuleSpecifications(
902 const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
903 lldb::offset_t data_offset, lldb::offset_t file_offset,
904 lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
905 const size_t initial_count = specs.GetSize();
906
907 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
908 DataExtractor data;
909 data.SetData(data_sp);
910 llvm::MachO::mach_header header;
911 if (ParseHeader(data, &data_offset, header)) {
912 size_t header_and_load_cmds =
913 header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
914 if (header_and_load_cmds >= data_sp->GetByteSize()) {
915 data_sp = MapFileData(file, header_and_load_cmds, file_offset);
916 data.SetData(data_sp);
917 data_offset = MachHeaderSizeFromMagic(header.magic);
918 }
919 if (data_sp) {
920 ModuleSpec spec;
921 spec.GetFileSpec() = file;
922 spec.SetObjectOffset(file_offset);
923 spec.SetObjectSize(length);
924
925 if (GetArchitecture(header, data, data_offset,
926 spec.GetArchitecture())) {
927 if (spec.GetArchitecture().IsValid()) {
928 GetUUID(header, data, data_offset, spec.GetUUID());
929 specs.Append(spec);
930 }
931 }
932 }
933 }
934 }
935 return specs.GetSize() - initial_count;
936}
937
938const ConstString &ObjectFileMachO::GetSegmentNameTEXT() {
939 static ConstString g_segment_name_TEXT("__TEXT");
940 return g_segment_name_TEXT;
941}
942
943const ConstString &ObjectFileMachO::GetSegmentNameDATA() {
944 static ConstString g_segment_name_DATA("__DATA");
945 return g_segment_name_DATA;
946}
947
948const ConstString &ObjectFileMachO::GetSegmentNameDATA_DIRTY() {
949 static ConstString g_segment_name("__DATA_DIRTY");
950 return g_segment_name;
951}
952
953const ConstString &ObjectFileMachO::GetSegmentNameDATA_CONST() {
954 static ConstString g_segment_name("__DATA_CONST");
955 return g_segment_name;
956}
957
958const ConstString &ObjectFileMachO::GetSegmentNameOBJC() {
959 static ConstString g_segment_name_OBJC("__OBJC");
960 return g_segment_name_OBJC;
961}
962
963const ConstString &ObjectFileMachO::GetSegmentNameLINKEDIT() {
964 static ConstString g_section_name_LINKEDIT("__LINKEDIT");
965 return g_section_name_LINKEDIT;
966}
967
968const ConstString &ObjectFileMachO::GetSectionNameEHFrame() {
969 static ConstString g_section_name_eh_frame("__eh_frame");
970 return g_section_name_eh_frame;
971}
972
973bool ObjectFileMachO::MagicBytesMatch(DataBufferSP &data_sp,
974 lldb::addr_t data_offset,
975 lldb::addr_t data_length) {
976 DataExtractor data;
977 data.SetData(data_sp, data_offset, data_length);
978 lldb::offset_t offset = 0;
979 uint32_t magic = data.GetU32(&offset);
980 return MachHeaderSizeFromMagic(magic) != 0;
981}
982
983ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
984 DataBufferSP &data_sp,
985 lldb::offset_t data_offset,
986 const FileSpec *file,
987 lldb::offset_t file_offset,
988 lldb::offset_t length)
989 : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
990 m_mach_segments(), m_mach_sections(), m_entry_point_address(),
991 m_thread_context_offsets(), m_thread_context_offsets_valid(false),
992 m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
993 ::memset(&m_header, 0, sizeof(m_header));
994 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
995}
996
997ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
998 lldb::DataBufferSP &header_data_sp,
999 const lldb::ProcessSP &process_sp,
1000 lldb::addr_t header_addr)
1001 : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
1002 m_mach_segments(), m_mach_sections(), m_entry_point_address(),
1003 m_thread_context_offsets(), m_thread_context_offsets_valid(false),
1004 m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) {
1005 ::memset(&m_header, 0, sizeof(m_header));
1006 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
1007}
1008
1009bool ObjectFileMachO::ParseHeader(DataExtractor &data,
1010 lldb::offset_t *data_offset_ptr,
1011 llvm::MachO::mach_header &header) {
1012 data.SetByteOrder(endian::InlHostByteOrder());
1013 // Leave magic in the original byte order
1014 header.magic = data.GetU32(data_offset_ptr);
1015 bool can_parse = false;
1016 bool is_64_bit = false;
1017 switch (header.magic) {
1018 case MH_MAGIC:
1019 data.SetByteOrder(endian::InlHostByteOrder());
1020 data.SetAddressByteSize(4);
1021 can_parse = true;
1022 break;
1023
1024 case MH_MAGIC_64:
1025 data.SetByteOrder(endian::InlHostByteOrder());
1026 data.SetAddressByteSize(8);
1027 can_parse = true;
1028 is_64_bit = true;
1029 break;
1030
1031 case MH_CIGAM:
1032 data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
1033 ? eByteOrderLittle
1034 : eByteOrderBig);
1035 data.SetAddressByteSize(4);
1036 can_parse = true;
1037 break;
1038
1039 case MH_CIGAM_64:
1040 data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
1041 ? eByteOrderLittle
1042 : eByteOrderBig);
1043 data.SetAddressByteSize(8);
1044 is_64_bit = true;
1045 can_parse = true;
1046 break;
1047
1048 default:
1049 break;
1050 }
1051
1052 if (can_parse) {
1053 data.GetU32(data_offset_ptr, &header.cputype, 6);
1054 if (is_64_bit)
1055 *data_offset_ptr += 4;
1056 return true;
1057 } else {
1058 memset(&header, 0, sizeof(header));
1059 }
1060 return false;
1061}
1062
1063bool ObjectFileMachO::ParseHeader() {
1064 ModuleSP module_sp(GetModule());
1065 if (module_sp) {
1066 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1067 bool can_parse = false;
1068 lldb::offset_t offset = 0;
1069 m_data.SetByteOrder(endian::InlHostByteOrder());
1070 // Leave magic in the original byte order
1071 m_header.magic = m_data.GetU32(&offset);
1072 switch (m_header.magic) {
1073 case MH_MAGIC:
1074 m_data.SetByteOrder(endian::InlHostByteOrder());
1075 m_data.SetAddressByteSize(4);
1076 can_parse = true;
1077 break;
1078
1079 case MH_MAGIC_64:
1080 m_data.SetByteOrder(endian::InlHostByteOrder());
1081 m_data.SetAddressByteSize(8);
1082 can_parse = true;
1083 break;
1084
1085 case MH_CIGAM:
1086 m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
1087 ? eByteOrderLittle
1088 : eByteOrderBig);
1089 m_data.SetAddressByteSize(4);
1090 can_parse = true;
1091 break;
1092
1093 case MH_CIGAM_64:
1094 m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
1095 ? eByteOrderLittle
1096 : eByteOrderBig);
1097 m_data.SetAddressByteSize(8);
1098 can_parse = true;
1099 break;
1100
1101 default:
1102 break;
1103 }
1104
1105 if (can_parse) {
1106 m_data.GetU32(&offset, &m_header.cputype, 6);
1107
1108 ArchSpec mach_arch;
1109
1110 if (GetArchitecture(mach_arch)) {
1111 // Check if the module has a required architecture
1112 const ArchSpec &module_arch = module_sp->GetArchitecture();
1113 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
1114 return false;
1115
1116 if (SetModulesArchitecture(mach_arch)) {
1117 const size_t header_and_lc_size =
1118 m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
1119 if (m_data.GetByteSize() < header_and_lc_size) {
1120 DataBufferSP data_sp;
1121 ProcessSP process_sp(m_process_wp.lock());
1122 if (process_sp) {
1123 data_sp =
1124 ReadMemory(process_sp, m_memory_addr, header_and_lc_size);
1125 } else {
1126 // Read in all only the load command data from the file on disk
1127 data_sp = MapFileData(m_file, header_and_lc_size, m_file_offset);
1128 if (data_sp->GetByteSize() != header_and_lc_size)
1129 return false;
1130 }
1131 if (data_sp)
1132 m_data.SetData(data_sp);
1133 }
1134 }
1135 return true;
1136 }
1137 } else {
1138 memset(&m_header, 0, sizeof(struct mach_header));
1139 }
1140 }
1141 return false;
1142}
1143
1144ByteOrder ObjectFileMachO::GetByteOrder() const {
1145 return m_data.GetByteOrder();
1146}
1147
1148bool ObjectFileMachO::IsExecutable() const {
1149 return m_header.filetype == MH_EXECUTE;
1150}
1151
1152uint32_t ObjectFileMachO::GetAddressByteSize() const {
1153 return m_data.GetAddressByteSize();
1154}
1155
1156AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
1157 Symtab *symtab = GetSymtab();
1158 if (symtab) {
1159 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
1160 if (symbol) {
1161 if (symbol->ValueIsAddress()) {
1162 SectionSP section_sp(symbol->GetAddressRef().GetSection());
1163 if (section_sp) {
1164 const lldb::SectionType section_type = section_sp->GetType();
1165 switch (section_type) {
1166 case eSectionTypeInvalid:
1167 return eAddressClassUnknown;
1168
1169 case eSectionTypeCode:
1170 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1171 // For ARM we have a bit in the n_desc field of the symbol
1172 // that tells us ARM/Thumb which is bit 0x0008.
1173 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB0x0008)
1174 return eAddressClassCodeAlternateISA;
1175 }
1176 return eAddressClassCode;
1177
1178 case eSectionTypeContainer:
1179 return eAddressClassUnknown;
1180
1181 case eSectionTypeData:
1182 case eSectionTypeDataCString:
1183 case eSectionTypeDataCStringPointers:
1184 case eSectionTypeDataSymbolAddress:
1185 case eSectionTypeData4:
1186 case eSectionTypeData8:
1187 case eSectionTypeData16:
1188 case eSectionTypeDataPointers:
1189 case eSectionTypeZeroFill:
1190 case eSectionTypeDataObjCMessageRefs:
1191 case eSectionTypeDataObjCCFStrings:
1192 case eSectionTypeGoSymtab:
1193 return eAddressClassData;
1194
1195 case eSectionTypeDebug:
1196 case eSectionTypeDWARFDebugAbbrev:
1197 case eSectionTypeDWARFDebugAddr:
1198 case eSectionTypeDWARFDebugAranges:
1199 case eSectionTypeDWARFDebugCuIndex:
1200 case eSectionTypeDWARFDebugFrame:
1201 case eSectionTypeDWARFDebugInfo:
1202 case eSectionTypeDWARFDebugLine:
1203 case eSectionTypeDWARFDebugLoc:
1204 case eSectionTypeDWARFDebugMacInfo:
1205 case eSectionTypeDWARFDebugMacro:
1206 case eSectionTypeDWARFDebugPubNames:
1207 case eSectionTypeDWARFDebugPubTypes:
1208 case eSectionTypeDWARFDebugRanges:
1209 case eSectionTypeDWARFDebugStr:
1210 case eSectionTypeDWARFDebugStrOffsets:
1211 case eSectionTypeDWARFAppleNames:
1212 case eSectionTypeDWARFAppleTypes:
1213 case eSectionTypeDWARFAppleNamespaces:
1214 case eSectionTypeDWARFAppleObjC:
1215 return eAddressClassDebug;
1216
1217 case eSectionTypeEHFrame:
1218 case eSectionTypeARMexidx:
1219 case eSectionTypeARMextab:
1220 case eSectionTypeCompactUnwind:
1221 return eAddressClassRuntime;
1222
1223 case eSectionTypeAbsoluteAddress:
1224 case eSectionTypeELFSymbolTable:
1225 case eSectionTypeELFDynamicSymbols:
1226 case eSectionTypeELFRelocationEntries:
1227 case eSectionTypeELFDynamicLinkInfo:
1228 case eSectionTypeOther:
1229 return eAddressClassUnknown;
1230 }
1231 }
1232 }
1233
1234 const SymbolType symbol_type = symbol->GetType();
1235 switch (symbol_type) {
1236 case eSymbolTypeAny:
1237 return eAddressClassUnknown;
1238 case eSymbolTypeAbsolute:
1239 return eAddressClassUnknown;
1240
1241 case eSymbolTypeCode:
1242 case eSymbolTypeTrampoline:
1243 case eSymbolTypeResolver:
1244 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) {
1245 // For ARM we have a bit in the n_desc field of the symbol
1246 // that tells us ARM/Thumb which is bit 0x0008.
1247 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB0x0008)
1248 return eAddressClassCodeAlternateISA;
1249 }
1250 return eAddressClassCode;
1251
1252 case eSymbolTypeData:
1253 return eAddressClassData;
1254 case eSymbolTypeRuntime:
1255 return eAddressClassRuntime;
1256 case eSymbolTypeException:
1257 return eAddressClassRuntime;
1258 case eSymbolTypeSourceFile:
1259 return eAddressClassDebug;
1260 case eSymbolTypeHeaderFile:
1261 return eAddressClassDebug;
1262 case eSymbolTypeObjectFile:
1263 return eAddressClassDebug;
1264 case eSymbolTypeCommonBlock:
1265 return eAddressClassDebug;
1266 case eSymbolTypeBlock:
1267 return eAddressClassDebug;
1268 case eSymbolTypeLocal:
1269 return eAddressClassData;
1270 case eSymbolTypeParam:
1271 return eAddressClassData;
1272 case eSymbolTypeVariable:
1273 return eAddressClassData;
1274 case eSymbolTypeVariableType:
1275 return eAddressClassDebug;
1276 case eSymbolTypeLineEntry:
1277 return eAddressClassDebug;
1278 case eSymbolTypeLineHeader:
1279 return eAddressClassDebug;
1280 case eSymbolTypeScopeBegin:
1281 return eAddressClassDebug;
1282 case eSymbolTypeScopeEnd:
1283 return eAddressClassDebug;
1284 case eSymbolTypeAdditional:
1285 return eAddressClassUnknown;
1286 case eSymbolTypeCompiler:
1287 return eAddressClassDebug;
1288 case eSymbolTypeInstrumentation:
1289 return eAddressClassDebug;
1290 case eSymbolTypeUndefined:
1291 return eAddressClassUnknown;
1292 case eSymbolTypeObjCClass:
1293 return eAddressClassRuntime;
1294 case eSymbolTypeObjCMetaClass:
1295 return eAddressClassRuntime;
1296 case eSymbolTypeObjCIVar:
1297 return eAddressClassRuntime;
1298 case eSymbolTypeReExported:
1299 return eAddressClassRuntime;
1300 }
1301 }
1302 }
1303 return eAddressClassUnknown;
1304}
1305
1306Symtab *ObjectFileMachO::GetSymtab() {
1307 ModuleSP module_sp(GetModule());
1308 if (module_sp) {
1309 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1310 if (m_symtab_ap.get() == NULL__null) {
1311 m_symtab_ap.reset(new Symtab(this));
1312 std::lock_guard<std::recursive_mutex> symtab_guard(
1313 m_symtab_ap->GetMutex());
1314 ParseSymtab();
1315 m_symtab_ap->Finalize();
1316 }
1317 }
1318 return m_symtab_ap.get();
1319}
1320
1321bool ObjectFileMachO::IsStripped() {
1322 if (m_dysymtab.cmd == 0) {
1323 ModuleSP module_sp(GetModule());
1324 if (module_sp) {
1325 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1326 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
1327 const lldb::offset_t load_cmd_offset = offset;
1328
1329 load_command lc;
1330 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL__null)
1331 break;
1332 if (lc.cmd == LC_DYSYMTAB) {
1333 m_dysymtab.cmd = lc.cmd;
1334 m_dysymtab.cmdsize = lc.cmdsize;
1335 if (m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
1336 (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) ==
1337 NULL__null) {
1338 // Clear m_dysymtab if we were unable to read all items from the
1339 // load command
1340 ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));
1341 }
1342 }
1343 offset = load_cmd_offset + lc.cmdsize;
1344 }
1345 }
1346 }
1347 if (m_dysymtab.cmd)
1348 return m_dysymtab.nlocalsym <= 1;
1349 return false;
1350}
1351
1352ObjectFileMachO::EncryptedFileRanges ObjectFileMachO::GetEncryptedFileRanges() {
1353 EncryptedFileRanges result;
1354 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1355
1356 encryption_info_command encryption_cmd;
1357 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
1358 const lldb::offset_t load_cmd_offset = offset;
1359 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL__null)
1360 break;
1361
1362 // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
1363 // the 3 fields we care about, so treat them the same.
1364 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO ||
1365 encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) {
1366 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) {
1367 if (encryption_cmd.cryptid != 0) {
1368 EncryptedFileRanges::Entry entry;
1369 entry.SetRangeBase(encryption_cmd.cryptoff);
1370 entry.SetByteSize(encryption_cmd.cryptsize);
1371 result.Append(entry);
1372 }
1373 }
1374 }
1375 offset = load_cmd_offset + encryption_cmd.cmdsize;
1376 }
1377
1378 return result;
1379}
1380
1381void ObjectFileMachO::SanitizeSegmentCommand(segment_command_64 &seg_cmd,
1382 uint32_t cmd_idx) {
1383 if (m_length == 0 || seg_cmd.filesize == 0)
1384 return;
1385
1386 if (seg_cmd.fileoff > m_length) {
1387 // We have a load command that says it extends past the end of the file.
1388 // This is likely a corrupt file. We don't have any way to return an error
1389 // condition here (this method was likely invoked from something like
1390 // ObjectFile::GetSectionList()), so we just null out the section contents,
1391 // and dump a message to stdout. The most common case here is core file
1392 // debugging with a truncated file.
1393 const char *lc_segment_name =
1394 seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
1395 GetModule()->ReportWarning(
1396 "load command %u %s has a fileoff (0x%" PRIx64"l" "x"
1397 ") that extends beyond the end of the file (0x%" PRIx64"l" "x"
1398 "), ignoring this section",
1399 cmd_idx, lc_segment_name, seg_cmd.fileoff, m_length);
1400
1401 seg_cmd.fileoff = 0;
1402 seg_cmd.filesize = 0;
1403 }
1404
1405 if (seg_cmd.fileoff + seg_cmd.filesize > m_length) {
1406 // We have a load command that says it extends past the end of the file.
1407 // This is likely a corrupt file. We don't have any way to return an error
1408 // condition here (this method was likely invoked from something like
1409 // ObjectFile::GetSectionList()), so we just null out the section contents,
1410 // and dump a message to stdout. The most common case here is core file
1411 // debugging with a truncated file.
1412 const char *lc_segment_name =
1413 seg_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
1414 GetModule()->ReportWarning(
1415 "load command %u %s has a fileoff + filesize (0x%" PRIx64"l" "x"
1416 ") that extends beyond the end of the file (0x%" PRIx64"l" "x"
1417 "), the segment will be truncated to match",
1418 cmd_idx, lc_segment_name, seg_cmd.fileoff + seg_cmd.filesize, m_length);
1419
1420 // Truncate the length
1421 seg_cmd.filesize = m_length - seg_cmd.fileoff;
1422 }
1423}
1424
1425static uint32_t GetSegmentPermissions(const segment_command_64 &seg_cmd) {
1426 uint32_t result = 0;
1427 if (seg_cmd.initprot & VM_PROT_READ)
1428 result |= ePermissionsReadable;
1429 if (seg_cmd.initprot & VM_PROT_WRITE)
1430 result |= ePermissionsWritable;
1431 if (seg_cmd.initprot & VM_PROT_EXECUTE)
1432 result |= ePermissionsExecutable;
1433 return result;
1434}
1435
1436static lldb::SectionType GetSectionType(uint32_t flags,
1437 ConstString section_name) {
1438
1439 if (flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1440 return eSectionTypeCode;
1441
1442 uint32_t mach_sect_type = flags & SECTION_TYPE;
1443 static ConstString g_sect_name_objc_data("__objc_data");
1444 static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs");
1445 static ConstString g_sect_name_objc_selrefs("__objc_selrefs");
1446 static ConstString g_sect_name_objc_classrefs("__objc_classrefs");
1447 static ConstString g_sect_name_objc_superrefs("__objc_superrefs");
1448 static ConstString g_sect_name_objc_const("__objc_const");
1449 static ConstString g_sect_name_objc_classlist("__objc_classlist");
1450 static ConstString g_sect_name_cfstring("__cfstring");
1451
1452 static ConstString g_sect_name_dwarf_debug_abbrev("__debug_abbrev");
1453 static ConstString g_sect_name_dwarf_debug_aranges("__debug_aranges");
1454 static ConstString g_sect_name_dwarf_debug_frame("__debug_frame");
1455 static ConstString g_sect_name_dwarf_debug_info("__debug_info");
1456 static ConstString g_sect_name_dwarf_debug_line("__debug_line");
1457 static ConstString g_sect_name_dwarf_debug_loc("__debug_loc");
1458 static ConstString g_sect_name_dwarf_debug_macinfo("__debug_macinfo");
1459 static ConstString g_sect_name_dwarf_debug_pubnames("__debug_pubnames");
1460 static ConstString g_sect_name_dwarf_debug_pubtypes("__debug_pubtypes");
1461 static ConstString g_sect_name_dwarf_debug_ranges("__debug_ranges");
1462 static ConstString g_sect_name_dwarf_debug_str("__debug_str");
1463 static ConstString g_sect_name_dwarf_apple_names("__apple_names");
1464 static ConstString g_sect_name_dwarf_apple_types("__apple_types");
1465 static ConstString g_sect_name_dwarf_apple_namespaces("__apple_namespac");
1466 static ConstString g_sect_name_dwarf_apple_objc("__apple_objc");
1467 static ConstString g_sect_name_eh_frame("__eh_frame");
1468 static ConstString g_sect_name_compact_unwind("__unwind_info");
1469 static ConstString g_sect_name_text("__text");
1470 static ConstString g_sect_name_data("__data");
1471 static ConstString g_sect_name_go_symtab("__gosymtab");
1472
1473 if (section_name == g_sect_name_dwarf_debug_abbrev)
1474 return eSectionTypeDWARFDebugAbbrev;
1475 if (section_name == g_sect_name_dwarf_debug_aranges)
1476 return eSectionTypeDWARFDebugAranges;
1477 if (section_name == g_sect_name_dwarf_debug_frame)
1478 return eSectionTypeDWARFDebugFrame;
1479 if (section_name == g_sect_name_dwarf_debug_info)
1480 return eSectionTypeDWARFDebugInfo;
1481 if (section_name == g_sect_name_dwarf_debug_line)
1482 return eSectionTypeDWARFDebugLine;
1483 if (section_name == g_sect_name_dwarf_debug_loc)
1484 return eSectionTypeDWARFDebugLoc;
1485 if (section_name == g_sect_name_dwarf_debug_macinfo)
1486 return eSectionTypeDWARFDebugMacInfo;
1487 if (section_name == g_sect_name_dwarf_debug_pubnames)
1488 return eSectionTypeDWARFDebugPubNames;
1489 if (section_name == g_sect_name_dwarf_debug_pubtypes)
1490 return eSectionTypeDWARFDebugPubTypes;
1491 if (section_name == g_sect_name_dwarf_debug_ranges)
1492 return eSectionTypeDWARFDebugRanges;
1493 if (section_name == g_sect_name_dwarf_debug_str)
1494 return eSectionTypeDWARFDebugStr;
1495 if (section_name == g_sect_name_dwarf_apple_names)
1496 return eSectionTypeDWARFAppleNames;
1497 if (section_name == g_sect_name_dwarf_apple_types)
1498 return eSectionTypeDWARFAppleTypes;
1499 if (section_name == g_sect_name_dwarf_apple_namespaces)
1500 return eSectionTypeDWARFAppleNamespaces;
1501 if (section_name == g_sect_name_dwarf_apple_objc)
1502 return eSectionTypeDWARFAppleObjC;
1503 if (section_name == g_sect_name_objc_selrefs)
1504 return eSectionTypeDataCStringPointers;
1505 if (section_name == g_sect_name_objc_msgrefs)
1506 return eSectionTypeDataObjCMessageRefs;
1507 if (section_name == g_sect_name_eh_frame)
1508 return eSectionTypeEHFrame;
1509 if (section_name == g_sect_name_compact_unwind)
1510 return eSectionTypeCompactUnwind;
1511 if (section_name == g_sect_name_cfstring)
1512 return eSectionTypeDataObjCCFStrings;
1513 if (section_name == g_sect_name_go_symtab)
1514 return eSectionTypeGoSymtab;
1515 if (section_name == g_sect_name_objc_data ||
1516 section_name == g_sect_name_objc_classrefs ||
1517 section_name == g_sect_name_objc_superrefs ||
1518 section_name == g_sect_name_objc_const ||
1519 section_name == g_sect_name_objc_classlist) {
1520 return eSectionTypeDataPointers;
1521 }
1522
1523 switch (mach_sect_type) {
1524 // TODO: categorize sections by other flags for regular sections
1525 case S_REGULAR:
1526 if (section_name == g_sect_name_text)
1527 return eSectionTypeCode;
1528 if (section_name == g_sect_name_data)
1529 return eSectionTypeData;
1530 return eSectionTypeOther;
1531 case S_ZEROFILL:
1532 return eSectionTypeZeroFill;
1533 case S_CSTRING_LITERALS: // section with only literal C strings
1534 return eSectionTypeDataCString;
1535 case S_4BYTE_LITERALS: // section with only 4 byte literals
1536 return eSectionTypeData4;
1537 case S_8BYTE_LITERALS: // section with only 8 byte literals
1538 return eSectionTypeData8;
1539 case S_LITERAL_POINTERS: // section with only pointers to literals
1540 return eSectionTypeDataPointers;
1541 case S_NON_LAZY_SYMBOL_POINTERS: // section with only non-lazy symbol pointers
1542 return eSectionTypeDataPointers;
1543 case S_LAZY_SYMBOL_POINTERS: // section with only lazy symbol pointers
1544 return eSectionTypeDataPointers;
1545 case S_SYMBOL_STUBS: // section with only symbol stubs, byte size of stub in
1546 // the reserved2 field
1547 return eSectionTypeCode;
1548 case S_MOD_INIT_FUNC_POINTERS: // section with only function pointers for
1549 // initialization
1550 return eSectionTypeDataPointers;
1551 case S_MOD_TERM_FUNC_POINTERS: // section with only function pointers for
1552 // termination
1553 return eSectionTypeDataPointers;
1554 case S_COALESCED:
1555 return eSectionTypeOther;
1556 case S_GB_ZEROFILL:
1557 return eSectionTypeZeroFill;
1558 case S_INTERPOSING: // section with only pairs of function pointers for
1559 // interposing
1560 return eSectionTypeCode;
1561 case S_16BYTE_LITERALS: // section with only 16 byte literals
1562 return eSectionTypeData16;
1563 case S_DTRACE_DOF:
1564 return eSectionTypeDebug;
1565 case S_LAZY_DYLIB_SYMBOL_POINTERS:
1566 return eSectionTypeDataPointers;
1567 default:
1568 return eSectionTypeOther;
1569 }
1570}
1571
1572struct ObjectFileMachO::SegmentParsingContext {
1573 const EncryptedFileRanges EncryptedRanges;
1574 lldb_private::SectionList &UnifiedList;
1575 uint32_t NextSegmentIdx = 0;
1576 uint32_t NextSectionIdx = 0;
1577 bool FileAddressesChanged = false;
1578
1579 SegmentParsingContext(EncryptedFileRanges EncryptedRanges,
1580 lldb_private::SectionList &UnifiedList)
1581 : EncryptedRanges(std::move(EncryptedRanges)), UnifiedList(UnifiedList) {}
1582};
1583
1584void ObjectFileMachO::ProcessSegmentCommand(const load_command &load_cmd_,
1585 lldb::offset_t offset,
1586 uint32_t cmd_idx,
1587 SegmentParsingContext &context) {
1588 segment_command_64 load_cmd;
1589 memcpy(&load_cmd, &load_cmd_, sizeof(load_cmd_));
1590
1591 if (!m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
1592 return;
1593
1594 ModuleSP module_sp = GetModule();
1595 const bool is_core = GetType() == eTypeCoreFile;
1596 const bool is_dsym = (m_header.filetype == MH_DSYM);
1597 bool add_section = true;
1598 bool add_to_unified = true;
1599 ConstString const_segname(
1600 load_cmd.segname,
1601 std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
1602
1603 SectionSP unified_section_sp(
1604 context.UnifiedList.FindSectionByName(const_segname));
1605 if (is_dsym && unified_section_sp) {
1606 if (const_segname == GetSegmentNameLINKEDIT()) {
1607 // We need to keep the __LINKEDIT segment private to this object
1608 // file only
1609 add_to_unified = false;
1610 } else {
1611 // This is the dSYM file and this section has already been created
1612 // by the object file, no need to create it.
1613 add_section = false;
1614 }
1615 }
1616 load_cmd.vmaddr = m_data.GetAddress(&offset);
1617 load_cmd.vmsize = m_data.GetAddress(&offset);
1618 load_cmd.fileoff = m_data.GetAddress(&offset);
1619 load_cmd.filesize = m_data.GetAddress(&offset);
1620 if (!m_data.GetU32(&offset, &load_cmd.maxprot, 4))
1621 return;
1622
1623 SanitizeSegmentCommand(load_cmd, cmd_idx);
1624
1625 const uint32_t segment_permissions = GetSegmentPermissions(load_cmd);
1626 const bool segment_is_encrypted =
1627 (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
1628
1629 // Keep a list of mach segments around in case we need to
1630 // get at data that isn't stored in the abstracted Sections.
1631 m_mach_segments.push_back(load_cmd);
1632
1633 // Use a segment ID of the segment index shifted left by 8 so they
1634 // never conflict with any of the sections.
1635 SectionSP segment_sp;
1636 if (add_section && (const_segname || is_core)) {
1637 segment_sp.reset(new Section(
1638 module_sp, // Module to which this section belongs
1639 this, // Object file to which this sections belongs
1640 ++context.NextSegmentIdx
1641 << 8, // Section ID is the 1 based segment index
1642 // shifted right by 8 bits as not to collide
1643 // with any of the 256 section IDs that are
1644 // possible
1645 const_segname, // Name of this section
1646 eSectionTypeContainer, // This section is a container of other
1647 // sections.
1648 load_cmd.vmaddr, // File VM address == addresses as they are
1649 // found in the object file
1650 load_cmd.vmsize, // VM size in bytes of this section
1651 load_cmd.fileoff, // Offset to the data for this section in
1652 // the file
1653 load_cmd.filesize, // Size in bytes of this section as found
1654 // in the file
1655 0, // Segments have no alignment information
1656 load_cmd.flags)); // Flags for this section
1657
1658 segment_sp->SetIsEncrypted(segment_is_encrypted);
1659 m_sections_ap->AddSection(segment_sp);
1660 segment_sp->SetPermissions(segment_permissions);
1661 if (add_to_unified)
1662 context.UnifiedList.AddSection(segment_sp);
1663 } else if (unified_section_sp) {
1664 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
1665 // Check to see if the module was read from memory?
1666 if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) {
1667 // We have a module that is in memory and needs to have its
1668 // file address adjusted. We need to do this because when we
1669 // load a file from memory, its addresses will be slid already,
1670 // yet the addresses in the new symbol file will still be
1671 // unslid. Since everything is stored as section offset, this
1672 // shouldn't cause any problems.
1673
1674 // Make sure we've parsed the symbol table from the
1675 // ObjectFile before we go around changing its Sections.
1676 module_sp->GetObjectFile()->GetSymtab();
1677 // eh_frame would present the same problems but we parse that
1678 // on a per-function basis as-needed so it's more difficult to
1679 // remove its use of the Sections. Realistically, the
1680 // environments where this code path will be taken will not
1681 // have eh_frame sections.
1682
1683 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
1684
1685 // Notify the module that the section addresses have been
1686 // changed once we're done so any file-address caches can be
1687 // updated.
1688 context.FileAddressesChanged = true;
1689 }
1690 }
1691 m_sections_ap->AddSection(unified_section_sp);
1692 }
1693
1694 struct section_64 sect64;
1695 ::memset(&sect64, 0, sizeof(sect64));
1696 // Push a section into our mach sections for the section at
1697 // index zero (NO_SECT) if we don't have any mach sections yet...
1698 if (m_mach_sections.empty())
1699 m_mach_sections.push_back(sect64);
1700 uint32_t segment_sect_idx;
1701 const lldb::user_id_t first_segment_sectID = context.NextSectionIdx + 1;
1702
1703 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
1704 for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
1705 ++segment_sect_idx) {
1706 if (m_data.GetU8(&offset, (uint8_t *)sect64.sectname,
1707 sizeof(sect64.sectname)) == NULL__null)
1708 break;
1709 if (m_data.GetU8(&offset, (uint8_t *)sect64.segname,
1710 sizeof(sect64.segname)) == NULL__null)
1711 break;
1712 sect64.addr = m_data.GetAddress(&offset);
1713 sect64.size = m_data.GetAddress(&offset);
1714
1715 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL__null)
1716 break;
1717
1718 // Keep a list of mach sections around in case we need to
1719 // get at data that isn't stored in the abstracted Sections.
1720 m_mach_sections.push_back(sect64);
1721
1722 if (add_section) {
1723 ConstString section_name(
1724 sect64.sectname,
1725 std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
1726 if (!const_segname) {
1727 // We have a segment with no name so we need to conjure up
1728 // segments that correspond to the section's segname if there
1729 // isn't already such a section. If there is such a section, we
1730 // resize the section so that it spans all sections. We also
1731 // mark these sections as fake so address matches don't hit if
1732 // they land in the gaps between the child sections.
1733 const_segname.SetTrimmedCStringWithLength(sect64.segname,
1734 sizeof(sect64.segname));
1735 segment_sp = context.UnifiedList.FindSectionByName(const_segname);
1736 if (segment_sp.get()) {
1737 Section *segment = segment_sp.get();
1738 // Grow the section size as needed.
1739 const lldb::addr_t sect64_min_addr = sect64.addr;
1740 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1741 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
1742 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
1743 const lldb::addr_t curr_seg_max_addr =
1744 curr_seg_min_addr + curr_seg_byte_size;
1745 if (sect64_min_addr >= curr_seg_min_addr) {
1746 const lldb::addr_t new_seg_byte_size =
1747 sect64_max_addr - curr_seg_min_addr;
1748 // Only grow the section size if needed
1749 if (new_seg_byte_size > curr_seg_byte_size)
1750 segment->SetByteSize(new_seg_byte_size);
1751 } else {
1752 // We need to change the base address of the segment and
1753 // adjust the child section offsets for all existing
1754 // children.
1755 const lldb::addr_t slide_amount =
1756 sect64_min_addr - curr_seg_min_addr;
1757 segment->Slide(slide_amount, false);
1758 segment->GetChildren().Slide(-slide_amount, false);
1759 segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);
1760 }
1761
1762 // Grow the section size as needed.
1763 if (sect64.offset) {
1764 const lldb::addr_t segment_min_file_offset =
1765 segment->GetFileOffset();
1766 const lldb::addr_t segment_max_file_offset =
1767 segment_min_file_offset + segment->GetFileSize();
1768
1769 const lldb::addr_t section_min_file_offset = sect64.offset;
1770 const lldb::addr_t section_max_file_offset =
1771 section_min_file_offset + sect64.size;
1772 const lldb::addr_t new_file_offset =
1773 std::min(section_min_file_offset, segment_min_file_offset);
1774 const lldb::addr_t new_file_size =
1775 std::max(section_max_file_offset, segment_max_file_offset) -
1776 new_file_offset;
1777 segment->SetFileOffset(new_file_offset);
1778 segment->SetFileSize(new_file_size);
1779 }
1780 } else {
1781 // Create a fake section for the section's named segment
1782 segment_sp.reset(new Section(
1783 segment_sp, // Parent section
1784 module_sp, // Module to which this section belongs
1785 this, // Object file to which this section belongs
1786 ++context.NextSegmentIdx
1787 << 8, // Section ID is the 1 based segment index
1788 // shifted right by 8 bits as not to
1789 // collide with any of the 256 section IDs
1790 // that are possible
1791 const_segname, // Name of this section
1792 eSectionTypeContainer, // This section is a container of
1793 // other sections.
1794 sect64.addr, // File VM address == addresses as they are
1795 // found in the object file
1796 sect64.size, // VM size in bytes of this section
1797 sect64.offset, // Offset to the data for this section in
1798 // the file
1799 sect64.offset ? sect64.size : 0, // Size in bytes of
1800 // this section as
1801 // found in the file
1802 sect64.align,
1803 load_cmd.flags)); // Flags for this section
1804 segment_sp->SetIsFake(true);
1805 segment_sp->SetPermissions(segment_permissions);
1806 m_sections_ap->AddSection(segment_sp);
1807 if (add_to_unified)
1808 context.UnifiedList.AddSection(segment_sp);
1809 segment_sp->SetIsEncrypted(segment_is_encrypted);
1810 }
1811 }
1812 assert(segment_sp.get())(static_cast <bool> (segment_sp.get()) ? void (0) : __assert_fail
("segment_sp.get()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp"
, 1812, __extension__ __PRETTY_FUNCTION__))
;
1813
1814 lldb::SectionType sect_type = GetSectionType(sect64.flags, section_name);
1815
1816 SectionSP section_sp(new Section(
1817 segment_sp, module_sp, this, ++context.NextSectionIdx, section_name,
1818 sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
1819 sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
1820 sect64.flags));
1821 // Set the section to be encrypted to match the segment
1822
1823 bool section_is_encrypted = false;
1824 if (!segment_is_encrypted && load_cmd.filesize != 0)
1825 section_is_encrypted = context.EncryptedRanges.FindEntryThatContains(
1826 sect64.offset) != NULL__null;
1827
1828 section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
1829 section_sp->SetPermissions(segment_permissions);
1830 segment_sp->GetChildren().AddSection(section_sp);
1831
1832 if (segment_sp->IsFake()) {
1833 segment_sp.reset();
1834 const_segname.Clear();
1835 }
1836 }
1837 }
1838 if (segment_sp && is_dsym) {
1839 if (first_segment_sectID <= context.NextSectionIdx) {
1840 lldb::user_id_t sect_uid;
1841 for (sect_uid = first_segment_sectID; sect_uid <= context.NextSectionIdx;
1842 ++sect_uid) {
1843 SectionSP curr_section_sp(
1844 segment_sp->GetChildren().FindSectionByID(sect_uid));
1845 SectionSP next_section_sp;
1846 if (sect_uid + 1 <= context.NextSectionIdx)
1847 next_section_sp =
1848 segment_sp->GetChildren().FindSectionByID(sect_uid + 1);
1849
1850 if (curr_section_sp.get()) {
1851 if (curr_section_sp->GetByteSize() == 0) {
1852 if (next_section_sp.get() != NULL__null)
1853 curr_section_sp->SetByteSize(next_section_sp->GetFileAddress() -
1854 curr_section_sp->GetFileAddress());
1855 else
1856 curr_section_sp->SetByteSize(load_cmd.vmsize);
1857 }
1858 }
1859 }
1860 }
1861 }
1862}
1863
1864void ObjectFileMachO::ProcessDysymtabCommand(const load_command &load_cmd,
1865 lldb::offset_t offset) {
1866 m_dysymtab.cmd = load_cmd.cmd;
1867 m_dysymtab.cmdsize = load_cmd.cmdsize;
1868 m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
1869 (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1870}
1871
1872void ObjectFileMachO::CreateSections(SectionList &unified_section_list) {
1873 if (m_sections_ap)
1874 return;
1875
1876 m_sections_ap.reset(new SectionList());
1877
1878 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1879 // bool dump_sections = false;
1880 ModuleSP module_sp(GetModule());
1881
1882 offset = MachHeaderSizeFromMagic(m_header.magic);
1883
1884 SegmentParsingContext context(GetEncryptedFileRanges(), unified_section_list);
1885 struct load_command load_cmd;
1886 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
1887 const lldb::offset_t load_cmd_offset = offset;
1888 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL__null)
1889 break;
1890
1891 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
1892 ProcessSegmentCommand(load_cmd, offset, i, context);
1893 else if (load_cmd.cmd == LC_DYSYMTAB)
1894 ProcessDysymtabCommand(load_cmd, offset);
1895
1896 offset = load_cmd_offset + load_cmd.cmdsize;
1897 }
1898
1899 if (context.FileAddressesChanged && module_sp)
1900 module_sp->SectionFileAddressesChanged();
1901}
1902
1903class MachSymtabSectionInfo {
1904public:
1905 MachSymtabSectionInfo(SectionList *section_list)
1906 : m_section_list(section_list), m_section_infos() {
1907 // Get the number of sections down to a depth of 1 to include
1908 // all segments and their sections, but no other sections that
1909 // may be added for debug map or
1910 m_section_infos.resize(section_list->GetNumSections(1));
1911 }
1912
1913 SectionSP GetSection(uint8_t n_sect, addr_t file_addr) {
1914 if (n_sect == 0)
1915 return SectionSP();
1916 if (n_sect < m_section_infos.size()) {
1917 if (!m_section_infos[n_sect].section_sp) {
1918 SectionSP section_sp(m_section_list->FindSectionByID(n_sect));
1919 m_section_infos[n_sect].section_sp = section_sp;
1920 if (section_sp) {
1921 m_section_infos[n_sect].vm_range.SetBaseAddress(
1922 section_sp->GetFileAddress());
1923 m_section_infos[n_sect].vm_range.SetByteSize(
1924 section_sp->GetByteSize());
1925 } else {
1926 Host::SystemLog(Host::eSystemLogError,
1927 "error: unable to find section for section %u\n",
1928 n_sect);
1929 }
1930 }
1931 if (m_section_infos[n_sect].vm_range.Contains(file_addr)) {
1932 // Symbol is in section.
1933 return m_section_infos[n_sect].section_sp;
1934 } else if (m_section_infos[n_sect].vm_range.GetByteSize() == 0 &&
1935 m_section_infos[n_sect].vm_range.GetBaseAddress() ==
1936 file_addr) {
1937 // Symbol is in section with zero size, but has the same start
1938 // address as the section. This can happen with linker symbols
1939 // (symbols that start with the letter 'l' or 'L'.
1940 return m_section_infos[n_sect].section_sp;
1941 }
1942 }
1943 return m_section_list->FindSectionContainingFileAddress(file_addr);
1944 }
1945
1946protected:
1947 struct SectionInfo {
1948 SectionInfo() : vm_range(), section_sp() {}
1949
1950 VMRange vm_range;
1951 SectionSP section_sp;
1952 };
1953 SectionList *m_section_list;
1954 std::vector<SectionInfo> m_section_infos;
1955};
1956
1957struct TrieEntry {
1958 TrieEntry()
1959 : name(), address(LLDB_INVALID_ADDRESS(18446744073709551615UL)), flags(0), other(0),
1960 import_name() {}
1961
1962 void Clear() {
1963 name.Clear();
1964 address = LLDB_INVALID_ADDRESS(18446744073709551615UL);
1965 flags = 0;
1966 other = 0;
1967 import_name.Clear();
1968 }
1969
1970 void Dump() const {
1971 printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
1972 static_cast<unsigned long long>(address),
1973 static_cast<unsigned long long>(flags),
1974 static_cast<unsigned long long>(other), name.GetCString());
1975 if (import_name)
1976 printf(" -> \"%s\"\n", import_name.GetCString());
1977 else
1978 printf("\n");
1979 }
1980 ConstString name;
1981 uint64_t address;
1982 uint64_t flags;
1983 uint64_t other;
1984 ConstString import_name;
1985};
1986
1987struct TrieEntryWithOffset {
1988 lldb::offset_t nodeOffset;
1989 TrieEntry entry;
1990
1991 TrieEntryWithOffset(lldb::offset_t offset) : nodeOffset(offset), entry() {}
1992
1993 void Dump(uint32_t idx) const {
1994 printf("[%3u] 0x%16.16llx: ", idx,
1995 static_cast<unsigned long long>(nodeOffset));
1996 entry.Dump();
1997 }
1998
1999 bool operator<(const TrieEntryWithOffset &other) const {
2000 return (nodeOffset < other.nodeOffset);
2001 }
2002};
2003
2004static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset,
2005 const bool is_arm,
2006 std::vector<llvm::StringRef> &nameSlices,
2007 std::set<lldb::addr_t> &resolver_addresses,
2008 std::vector<TrieEntryWithOffset> &output) {
2009 if (!data.ValidOffset(offset))
2010 return true;
2011
2012 const uint64_t terminalSize = data.GetULEB128(&offset);
2013 lldb::offset_t children_offset = offset + terminalSize;
2014 if (terminalSize != 0) {
2015 TrieEntryWithOffset e(offset);
2016 e.entry.flags = data.GetULEB128(&offset);
2017 const char *import_name = NULL__null;
2018 if (e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
2019 e.entry.address = 0;
2020 e.entry.other = data.GetULEB128(&offset); // dylib ordinal
2021 import_name = data.GetCStr(&offset);
2022 } else {
2023 e.entry.address = data.GetULEB128(&offset);
2024 if (e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
2025 e.entry.other = data.GetULEB128(&offset);
2026 uint64_t resolver_addr = e.entry.other;
2027 if (is_arm)
2028 resolver_addr &= THUMB_ADDRESS_BIT_MASK0xfffffffffffffffeull;
2029 resolver_addresses.insert(resolver_addr);
2030 } else
2031 e.entry.other = 0;
2032 }
2033 // Only add symbols that are reexport symbols with a valid import name
2034 if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name &&
2035 import_name[0]) {
2036 std::string name;
2037 if (!nameSlices.empty()) {
2038 for (auto name_slice : nameSlices)
2039 name.append(name_slice.data(), name_slice.size());
2040 }
2041 if (name.size() > 1) {
2042 // Skip the leading '_'
2043 e.entry.name.SetCStringWithLength(name.c_str() + 1, name.size() - 1);
2044 }
2045 if (import_name) {
2046 // Skip the leading '_'
2047 e.entry.import_name.SetCString(import_name + 1);
2048 }
2049 output.push_back(e);
2050 }
2051 }
2052
2053 const uint8_t childrenCount = data.GetU8(&children_offset);
2054 for (uint8_t i = 0; i < childrenCount; ++i) {
2055 const char *cstr = data.GetCStr(&children_offset);
2056 if (cstr)
2057 nameSlices.push_back(llvm::StringRef(cstr));
2058 else
2059 return false; // Corrupt data
2060 lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
2061 if (childNodeOffset) {
2062 if (!ParseTrieEntries(data, childNodeOffset, is_arm, nameSlices,
2063 resolver_addresses, output)) {
2064 return false;
2065 }
2066 }
2067 nameSlices.pop_back();
2068 }
2069 return true;
2070}
2071
2072// Read the UUID out of a dyld_shared_cache file on-disk.
2073UUID ObjectFileMachO::GetSharedCacheUUID(FileSpec dyld_shared_cache,
2074 const ByteOrder byte_order,
2075 const uint32_t addr_byte_size) {
2076 UUID dsc_uuid;
2077 DataBufferSP DscData = MapFileData(
2078 dyld_shared_cache, sizeof(struct lldb_copy_dyld_cache_header_v1), 0);
2079 if (!DscData)
2080 return dsc_uuid;
2081 DataExtractor dsc_header_data(DscData, byte_order, addr_byte_size);
2082
2083 char version_str[7];
2084 lldb::offset_t offset = 0;
2085 memcpy(version_str, dsc_header_data.GetData(&offset, 6), 6);
2086 version_str[6] = '\0';
2087 if (strcmp(version_str, "dyld_v") == 0) {
2088 offset = offsetof(struct lldb_copy_dyld_cache_header_v1, uuid)__builtin_offsetof(struct lldb_copy_dyld_cache_header_v1, uuid
)
;
2089 uint8_t uuid_bytes[sizeof(uuid_t)];
2090 memcpy(uuid_bytes, dsc_header_data.GetData(&offset, sizeof(uuid_t)),
2091 sizeof(uuid_t));
2092 dsc_uuid.SetBytes(uuid_bytes);
2093 }
2094 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS(1u << 20)));
2095 if (log && dsc_uuid.IsValid()) {
2096 log->Printf("Shared cache %s has UUID %s", dyld_shared_cache.GetPath().c_str(),
2097 dsc_uuid.GetAsString().c_str());
2098 }
2099 return dsc_uuid;
2100}
2101
2102size_t ObjectFileMachO::ParseSymtab() {
2103 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION__PRETTY_FUNCTION__);
2104 Timer scoped_timer(func_cat, "ObjectFileMachO::ParseSymtab () module = %s",
2105 m_file.GetFilename().AsCString(""));
2106 ModuleSP module_sp(GetModule());
2107 if (!module_sp)
1
Taking false branch
2108 return 0;
2109
2110 struct symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
2111 struct linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
2112 struct dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2113 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
2114 FunctionStarts function_starts;
2115 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
2116 uint32_t i;
2117 FileSpecList dylib_files;
2118 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS(1u << 20)));
2119 static const llvm::StringRef g_objc_v2_prefix_class("_OBJC_CLASS_$_");
2120 static const llvm::StringRef g_objc_v2_prefix_metaclass("_OBJC_METACLASS_$_");
2121 static const llvm::StringRef g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
2122
2123 for (i = 0; i < m_header.ncmds; ++i) {
2
Assuming the condition is true
3
Loop condition is true. Entering loop body
18
Assuming the condition is false
19
Loop condition is false. Execution continues on line 2210
2124 const lldb::offset_t cmd_offset = offset;
2125 // Read in the load command and load command size
2126 struct load_command lc;
2127 if (m_data.GetU32(&offset, &lc, 2) == NULL__null)
4
Assuming the condition is false
5
Taking false branch
2128 break;
2129 // Watch for the symbol table load command
2130 switch (lc.cmd) {
6
Control jumps to 'case LC_SYMTAB:' at line 2131
2131 case LC_SYMTAB:
2132 symtab_load_command.cmd = lc.cmd;
2133 symtab_load_command.cmdsize = lc.cmdsize;
2134 // Read in the rest of the symtab load command
2135 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) ==
7
Assuming the condition is false
8
Taking false branch
2136 0) // fill in symoff, nsyms, stroff, strsize fields
2137 return 0;
2138 if (symtab_load_command.symoff == 0) {
9
Assuming the condition is false
10
Taking false branch
2139 if (log)
2140 module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
2141 return 0;
2142 }
2143
2144 if (symtab_load_command.stroff == 0) {
11
Assuming the condition is false
12
Taking false branch
2145 if (log)
2146 module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
2147 return 0;
2148 }
2149
2150 if (symtab_load_command.nsyms == 0) {
13
Assuming the condition is false
14
Taking false branch
2151 if (log)
2152 module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
2153 return 0;
2154 }
2155
2156 if (symtab_load_command.strsize == 0) {
15
Assuming the condition is false
16
Taking false branch
2157 if (log)
2158 module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
2159 return 0;
2160 }
2161 break;
17
Execution continues on line 2207
2162
2163 case LC_DYLD_INFO:
2164 case LC_DYLD_INFO_ONLY:
2165 if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10)) {
2166 dyld_info.cmd = lc.cmd;
2167 dyld_info.cmdsize = lc.cmdsize;
2168 } else {
2169 memset(&dyld_info, 0, sizeof(dyld_info));
2170 }
2171 break;
2172
2173 case LC_LOAD_DYLIB:
2174 case LC_LOAD_WEAK_DYLIB:
2175 case LC_REEXPORT_DYLIB:
2176 case LC_LOADFVMLIB:
2177 case LC_LOAD_UPWARD_DYLIB: {
2178 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2179 const char *path = m_data.PeekCStr(name_offset);
2180 if (path) {
2181 FileSpec file_spec(path, false);
2182 // Strip the path if there is @rpath, @executable, etc so we just use
2183 // the basename
2184 if (path[0] == '@')
2185 file_spec.GetDirectory().Clear();
2186
2187 if (lc.cmd == LC_REEXPORT_DYLIB) {
2188 m_reexported_dylibs.AppendIfUnique(file_spec);
2189 }
2190
2191 dylib_files.Append(file_spec);
2192 }
2193 } break;
2194
2195 case LC_FUNCTION_STARTS:
2196 function_starts_load_command.cmd = lc.cmd;
2197 function_starts_load_command.cmdsize = lc.cmdsize;
2198 if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
2199 NULL__null) // fill in symoff, nsyms, stroff, strsize fields
2200 memset(&function_starts_load_command, 0,
2201 sizeof(function_starts_load_command));
2202 break;
2203
2204 default:
2205 break;
2206 }
2207 offset = cmd_offset + lc.cmdsize;
2208 }
2209
2210 if (symtab_load_command.cmd) {
20
Assuming the condition is true
21
Taking true branch
2211 Symtab *symtab = m_symtab_ap.get();
2212 SectionList *section_list = GetSectionList();
2213 if (section_list == NULL__null)
22
Assuming 'section_list' is not equal to NULL
23
Taking false branch
2214 return 0;
2215
2216 const uint32_t addr_byte_size = m_data.GetAddressByteSize();
2217 const ByteOrder byte_order = m_data.GetByteOrder();
2218 bool bit_width_32 = addr_byte_size == 4;
24
Assuming 'addr_byte_size' is not equal to 4
2219 const size_t nlist_byte_size =
2220 bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
25
'?' condition is false
2221
2222 DataExtractor nlist_data(NULL__null, 0, byte_order, addr_byte_size);
2223 DataExtractor strtab_data(NULL__null, 0, byte_order, addr_byte_size);
2224 DataExtractor function_starts_data(NULL__null, 0, byte_order, addr_byte_size);
2225 DataExtractor indirect_symbol_index_data(NULL__null, 0, byte_order,
2226 addr_byte_size);
2227 DataExtractor dyld_trie_data(NULL__null, 0, byte_order, addr_byte_size);
2228
2229 const addr_t nlist_data_byte_size =
2230 symtab_load_command.nsyms * nlist_byte_size;
2231 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
2232 addr_t strtab_addr = LLDB_INVALID_ADDRESS(18446744073709551615UL);
2233
2234 ProcessSP process_sp(m_process_wp.lock());
2235 Process *process = process_sp.get();
2236
2237 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
2238
2239 if (process && m_header.filetype != llvm::MachO::MH_OBJECT) {
2240 Target &target = process->GetTarget();
2241
2242 memory_module_load_level = target.GetMemoryModuleLoadLevel();
2243
2244 SectionSP linkedit_section_sp(
2245 section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2246 // Reading mach file from memory in a process or core file...
2247
2248 if (linkedit_section_sp) {
2249 addr_t linkedit_load_addr =
2250 linkedit_section_sp->GetLoadBaseAddress(&target);
2251 if (linkedit_load_addr == LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
2252 // We might be trying to access the symbol table before the
2253 // __LINKEDIT's load
2254 // address has been set in the target. We can't fail to read the
2255 // symbol table,
2256 // so calculate the right address manually
2257 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(
2258 m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2259 }
2260
2261 const addr_t linkedit_file_offset =
2262 linkedit_section_sp->GetFileOffset();
2263 const addr_t symoff_addr = linkedit_load_addr +
2264 symtab_load_command.symoff -
2265 linkedit_file_offset;
2266 strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
2267 linkedit_file_offset;
2268
2269 bool data_was_read = false;
2270
2271#if defined(__APPLE__) && \
2272 (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
2273 if (m_header.flags & 0x80000000u &&
2274 process->GetAddressByteSize() == sizeof(void *)) {
2275 // This mach-o memory file is in the dyld shared cache. If this
2276 // program is not remote and this is iOS, then this process will
2277 // share the same shared cache as the process we are debugging and
2278 // we can read the entire __LINKEDIT from the address space in this
2279 // process. This is a needed optimization that is used for local iOS
2280 // debugging only since all shared libraries in the shared cache do
2281 // not have corresponding files that exist in the file system of the
2282 // device. They have been combined into a single file. This means we
2283 // always have to load these files from memory. All of the symbol and
2284 // string tables from all of the __LINKEDIT sections from the shared
2285 // libraries in the shared cache have been merged into a single large
2286 // symbol and string table. Reading all of this symbol and string
2287 // table
2288 // data across can slow down debug launch times, so we optimize this
2289 // by
2290 // reading the memory for the __LINKEDIT section from this process.
2291
2292 UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
2293 UUID process_shared_cache(GetProcessSharedCacheUUID(process));
2294 bool use_lldb_cache = true;
2295 if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() &&
2296 lldb_shared_cache != process_shared_cache) {
2297 use_lldb_cache = false;
2298 ModuleSP module_sp(GetModule());
2299 if (module_sp)
2300 module_sp->ReportWarning("shared cache in process does not match "
2301 "lldb's own shared cache, startup will "
2302 "be slow.");
2303 }
2304
2305 PlatformSP platform_sp(target.GetPlatform());
2306 if (platform_sp && platform_sp->IsHost() && use_lldb_cache) {
2307 data_was_read = true;
2308 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size,
2309 eByteOrderLittle);
2310 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size,
2311 eByteOrderLittle);
2312 if (function_starts_load_command.cmd) {
2313 const addr_t func_start_addr =
2314 linkedit_load_addr + function_starts_load_command.dataoff -
2315 linkedit_file_offset;
2316 function_starts_data.SetData(
2317 (void *)func_start_addr,
2318 function_starts_load_command.datasize, eByteOrderLittle);
2319 }
2320 }
2321 }
2322#endif
2323
2324 if (!data_was_read) {
2325 // Always load dyld - the dynamic linker - from memory if we didn't
2326 // find a binary anywhere else.
2327 // lldb will not register dylib/framework/bundle loads/unloads if we
2328 // don't have the dyld symbols,
2329 // we force dyld to load from memory despite the user's
2330 // target.memory-module-load-level setting.
2331 if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
2332 m_header.filetype == llvm::MachO::MH_DYLINKER) {
2333 DataBufferSP nlist_data_sp(
2334 ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
2335 if (nlist_data_sp)
2336 nlist_data.SetData(nlist_data_sp, 0,
2337 nlist_data_sp->GetByteSize());
2338 // Load strings individually from memory when loading from memory
2339 // since shared cache
2340 // string tables contain strings for all symbols from all shared
2341 // cached libraries
2342 // DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr,
2343 // strtab_data_byte_size));
2344 // if (strtab_data_sp)
2345 // strtab_data.SetData (strtab_data_sp, 0,
2346 // strtab_data_sp->GetByteSize());
2347 if (m_dysymtab.nindirectsyms != 0) {
2348 const addr_t indirect_syms_addr = linkedit_load_addr +
2349 m_dysymtab.indirectsymoff -
2350 linkedit_file_offset;
2351 DataBufferSP indirect_syms_data_sp(
2352 ReadMemory(process_sp, indirect_syms_addr,
2353 m_dysymtab.nindirectsyms * 4));
2354 if (indirect_syms_data_sp)
2355 indirect_symbol_index_data.SetData(
2356 indirect_syms_data_sp, 0,
2357 indirect_syms_data_sp->GetByteSize());
2358 }
2359 } else if (memory_module_load_level >=
2360 eMemoryModuleLoadLevelPartial) {
2361 if (function_starts_load_command.cmd) {
2362 const addr_t func_start_addr =
2363 linkedit_load_addr + function_starts_load_command.dataoff -
2364 linkedit_file_offset;
2365 DataBufferSP func_start_data_sp(
2366 ReadMemory(process_sp, func_start_addr,
2367 function_starts_load_command.datasize));
2368 if (func_start_data_sp)
2369 function_starts_data.SetData(func_start_data_sp, 0,
2370 func_start_data_sp->GetByteSize());
2371 }
2372 }
2373 }
2374 }
2375 } else {
2376 nlist_data.SetData(m_data, symtab_load_command.symoff,
2377 nlist_data_byte_size);
2378 strtab_data.SetData(m_data, symtab_load_command.stroff,
2379 strtab_data_byte_size);
2380
2381 if (dyld_info.export_size > 0) {
26
Taking false branch
2382 dyld_trie_data.SetData(m_data, dyld_info.export_off,
2383 dyld_info.export_size);
2384 }
2385
2386 if (m_dysymtab.nindirectsyms != 0) {
27
Assuming the condition is false
28
Taking false branch
2387 indirect_symbol_index_data.SetData(m_data, m_dysymtab.indirectsymoff,
2388 m_dysymtab.nindirectsyms * 4);
2389 }
2390 if (function_starts_load_command.cmd) {
29
Taking false branch
2391 function_starts_data.SetData(m_data,
2392 function_starts_load_command.dataoff,
2393 function_starts_load_command.datasize);
2394 }
2395 }
2396
2397 if (nlist_data.GetByteSize() == 0 &&
30
Assuming the condition is false
2398 memory_module_load_level == eMemoryModuleLoadLevelComplete) {
2399 if (log)
2400 module_sp->LogMessage(log, "failed to read nlist data");
2401 return 0;
2402 }
2403
2404 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
31
Assuming the condition is true
2405 if (!have_strtab_data) {
32
Taking false branch
2406 if (process) {
2407 if (strtab_addr == LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
2408 if (log)
2409 module_sp->LogMessage(log, "failed to locate the strtab in memory");
2410 return 0;
2411 }
2412 } else {
2413 if (log)
2414 module_sp->LogMessage(log, "failed to read strtab data");
2415 return 0;
2416 }
2417 }
2418
2419 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
2420 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
2421 const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
2422 const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
2423 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
2424 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
2425 SectionSP text_section_sp(
2426 section_list->FindSectionByName(g_segment_name_TEXT));
2427 SectionSP data_section_sp(
2428 section_list->FindSectionByName(g_segment_name_DATA));
2429 SectionSP data_dirty_section_sp(
2430 section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2431 SectionSP data_const_section_sp(
2432 section_list->FindSectionByName(g_segment_name_DATA_CONST));
2433 SectionSP objc_section_sp(
2434 section_list->FindSectionByName(g_segment_name_OBJC));
2435 SectionSP eh_frame_section_sp;
2436 if (text_section_sp.get())
33
Assuming the condition is false
34
Taking false branch
2437 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName(
2438 g_section_name_eh_frame);
2439 else
2440 eh_frame_section_sp =
2441 section_list->FindSectionByName(g_section_name_eh_frame);
2442
2443 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
35
Assuming the condition is false
2444
2445 // lldb works best if it knows the start address of all functions in a
2446 // module.
2447 // Linker symbols or debug info are normally the best source of information
2448 // for start addr / size but
2449 // they may be stripped in a released binary.
2450 // Two additional sources of information exist in Mach-O binaries:
2451 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each
2452 // function's start address in the
2453 // binary, relative to the text section.
2454 // eh_frame - the eh_frame FDEs have the start addr & size of
2455 // each function
2456 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on
2457 // all modern binaries.
2458 // Binaries built to run on older releases may need to use eh_frame
2459 // information.
2460
2461 if (text_section_sp && function_starts_data.GetByteSize()) {
2462 FunctionStarts::Entry function_start_entry;
2463 function_start_entry.data = false;
2464 lldb::offset_t function_start_offset = 0;
2465 function_start_entry.addr = text_section_sp->GetFileAddress();
2466 uint64_t delta;
2467 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) >
2468 0) {
2469 // Now append the current entry
2470 function_start_entry.addr += delta;
2471 function_starts.Append(function_start_entry);
2472 }
2473 } else {
2474 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the
2475 // load command claiming an eh_frame
2476 // but it doesn't actually have the eh_frame content. And if we have a
2477 // dSYM, we don't need to do any
2478 // of this fill-in-the-missing-symbols works anyway - the debug info
2479 // should give us all the functions in
2480 // the module.
2481 if (text_section_sp.get() && eh_frame_section_sp.get() &&
2482 m_type != eTypeDebugInfo) {
2483 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp,
2484 DWARFCallFrameInfo::EH);
2485 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
2486 eh_frame.GetFunctionAddressAndSizeVector(functions);
2487 addr_t text_base_addr = text_section_sp->GetFileAddress();
2488 size_t count = functions.GetSize();
2489 for (size_t i = 0; i < count; ++i) {
2490 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func =
2491 functions.GetEntryAtIndex(i);
2492 if (func) {
2493 FunctionStarts::Entry function_start_entry;
2494 function_start_entry.addr = func->base - text_base_addr;
2495 function_starts.Append(function_start_entry);
2496 }
2497 }
2498 }
2499 }
2500
2501 const size_t function_starts_count = function_starts.GetSize();
2502
2503 // For user process binaries (executables, dylibs, frameworks, bundles), if
2504 // we don't have
2505 // LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume
2506 // the binary
2507 // has been stripped. Don't allow assembly language instruction emulation
2508 // because we don't
2509 // know proper function start boundaries.
2510 //
2511 // For all other types of binaries (kernels, stand-alone bare board
2512 // binaries, kexts), they
2513 // may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make
2514 // any assumptions
2515 // about them based on that.
2516 if (function_starts_count == 0 && CalculateStrata() == eStrataUser) {
36
Assuming 'function_starts_count' is not equal to 0
2517 m_allow_assembly_emulation_unwind_plans = false;
2518 Log *unwind_or_symbol_log(lldb_private::GetLogIfAnyCategoriesSet(
2519 LIBLLDB_LOG_SYMBOLS(1u << 20) | LIBLLDB_LOG_UNWIND(1u << 15)));
2520
2521 if (unwind_or_symbol_log)
2522 module_sp->LogMessage(
2523 unwind_or_symbol_log,
2524 "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds");
2525 }
2526
2527 const user_id_t TEXT_eh_frame_sectID =
2528 eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
37
Assuming the condition is false
38
'?' condition is false
2529 : static_cast<user_id_t>(NO_SECT);
2530
2531 lldb::offset_t nlist_data_offset = 0;
2532
2533 uint32_t N_SO_index = UINT32_MAX(4294967295U);
2534
2535 MachSymtabSectionInfo section_info(section_list);
2536 std::vector<uint32_t> N_FUN_indexes;
2537 std::vector<uint32_t> N_NSYM_indexes;
2538 std::vector<uint32_t> N_INCL_indexes;
2539 std::vector<uint32_t> N_BRAC_indexes;
2540 std::vector<uint32_t> N_COMM_indexes;
2541 typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap;
2542 typedef std::map<uint32_t, uint32_t> NListIndexToSymbolIndexMap;
2543 typedef std::map<const char *, uint32_t> ConstNameToSymbolIndexMap;
2544 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2545 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
2546 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
2547 // Any symbols that get merged into another will get an entry
2548 // in this map so we know
2549 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2550 uint32_t nlist_idx = 0;
2551 Symbol *symbol_ptr = NULL__null;
2552
2553 uint32_t sym_idx = 0;
2554 Symbol *sym = NULL__null;
2555 size_t num_syms = 0;
2556 std::string memory_symbol_name;
2557 uint32_t unmapped_local_symbols_found = 0;
2558
2559 std::vector<TrieEntryWithOffset> trie_entries;
2560 std::set<lldb::addr_t> resolver_addresses;
2561
2562 if (dyld_trie_data.GetByteSize() > 0) {
39
Assuming the condition is false
40
Taking false branch
2563 std::vector<llvm::StringRef> nameSlices;
2564 ParseTrieEntries(dyld_trie_data, 0, is_arm, nameSlices,
2565 resolver_addresses, trie_entries);
2566
2567 ConstString text_segment_name("__TEXT");
2568 SectionSP text_segment_sp =
2569 GetSectionList()->FindSectionByName(text_segment_name);
2570 if (text_segment_sp) {
2571 const lldb::addr_t text_segment_file_addr =
2572 text_segment_sp->GetFileAddress();
2573 if (text_segment_file_addr != LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
2574 for (auto &e : trie_entries)
2575 e.entry.address += text_segment_file_addr;
2576 }
2577 }
2578 }
2579
2580 typedef std::set<ConstString> IndirectSymbols;
2581 IndirectSymbols indirect_symbol_names;
2582
2583#if defined(__APPLE__) && \
2584 (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
2585
2586 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been
2587 // optimized by moving LOCAL
2588 // symbols out of the memory mapped portion of the DSC. The symbol
2589 // information has all been retained,
2590 // but it isn't available in the normal nlist data. However, there *are*
2591 // duplicate entries of *some*
2592 // LOCAL symbols in the normal nlist data. To handle this situation
2593 // correctly, we must first attempt
2594 // to parse any DSC unmapped symbol information. If we find any, we set a
2595 // flag that tells the normal
2596 // nlist parser to ignore all LOCAL symbols.
2597
2598 if (m_header.flags & 0x80000000u) {
2599 // Before we can start mapping the DSC, we need to make certain the target
2600 // process is actually
2601 // using the cache we can find.
2602
2603 // Next we need to determine the correct path for the dyld shared cache.
2604
2605 ArchSpec header_arch;
2606 GetArchitecture(header_arch);
2607 char dsc_path[PATH_MAX4096];
2608 char dsc_path_development[PATH_MAX4096];
2609
2610 snprintf(
2611 dsc_path, sizeof(dsc_path), "%s%s%s",
2612 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR
2613 */
2614 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
2615 header_arch.GetArchitectureName());
2616
2617 snprintf(
2618 dsc_path_development, sizeof(dsc_path), "%s%s%s%s",
2619 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR
2620 */
2621 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
2622 header_arch.GetArchitectureName(), ".development");
2623
2624 FileSpec dsc_nondevelopment_filespec(dsc_path, false);
2625 FileSpec dsc_development_filespec(dsc_path_development, false);
2626 FileSpec dsc_filespec;
2627
2628 UUID dsc_uuid;
2629 UUID process_shared_cache_uuid;
2630
2631 if (process) {
2632 process_shared_cache_uuid = GetProcessSharedCacheUUID(process);
2633 }
2634
2635 // First see if we can find an exact match for the inferior process shared
2636 // cache UUID in
2637 // the development or non-development shared caches on disk.
2638 if (process_shared_cache_uuid.IsValid()) {
2639 if (dsc_development_filespec.Exists()) {
2640 UUID dsc_development_uuid = GetSharedCacheUUID(
2641 dsc_development_filespec, byte_order, addr_byte_size);
2642 if (dsc_development_uuid.IsValid() &&
2643 dsc_development_uuid == process_shared_cache_uuid) {
2644 dsc_filespec = dsc_development_filespec;
2645 dsc_uuid = dsc_development_uuid;
2646 }
2647 }
2648 if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists()) {
2649 UUID dsc_nondevelopment_uuid = GetSharedCacheUUID(
2650 dsc_nondevelopment_filespec, byte_order, addr_byte_size);
2651 if (dsc_nondevelopment_uuid.IsValid() &&
2652 dsc_nondevelopment_uuid == process_shared_cache_uuid) {
2653 dsc_filespec = dsc_nondevelopment_filespec;
2654 dsc_uuid = dsc_nondevelopment_uuid;
2655 }
2656 }
2657 }
2658
2659 // Failing a UUID match, prefer the development dyld_shared cache if both
2660 // are present.
2661 if (!dsc_filespec.Exists()) {
2662 if (dsc_development_filespec.Exists()) {
2663 dsc_filespec = dsc_development_filespec;
2664 } else {
2665 dsc_filespec = dsc_nondevelopment_filespec;
2666 }
2667 }
2668
2669 /* The dyld_cache_header has a pointer to the
2670 dyld_cache_local_symbols_info structure (localSymbolsOffset).
2671 The dyld_cache_local_symbols_info structure gives us three things:
2672 1. The start and count of the nlist records in the dyld_shared_cache
2673 file
2674 2. The start and size of the strings for these nlist records
2675 3. The start and count of dyld_cache_local_symbols_entry entries
2676
2677 There is one dyld_cache_local_symbols_entry per dylib/framework in the
2678 dyld shared cache.
2679 The "dylibOffset" field is the Mach-O header of this dylib/framework in
2680 the dyld shared cache.
2681 The dyld_cache_local_symbols_entry also lists the start of this
2682 dylib/framework's nlist records
2683 and the count of how many nlist records there are for this
2684 dylib/framework.
2685 */
2686
2687 // Process the dyld shared cache header to find the unmapped symbols
2688
2689 DataBufferSP dsc_data_sp = MapFileData(
2690 dsc_filespec, sizeof(struct lldb_copy_dyld_cache_header_v1), 0);
2691 if (!dsc_uuid.IsValid()) {
2692 dsc_uuid = GetSharedCacheUUID(dsc_filespec, byte_order, addr_byte_size);
2693 }
2694 if (dsc_data_sp) {
2695 DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
2696
2697 bool uuid_match = true;
2698 if (dsc_uuid.IsValid() && process) {
2699 if (process_shared_cache_uuid.IsValid() &&
2700 dsc_uuid != process_shared_cache_uuid) {
2701 // The on-disk dyld_shared_cache file is not the same as the one in
2702 // this
2703 // process' memory, don't use it.
2704 uuid_match = false;
2705 ModuleSP module_sp(GetModule());
2706 if (module_sp)
2707 module_sp->ReportWarning("process shared cache does not match "
2708 "on-disk dyld_shared_cache file, some "
2709 "symbol names will be missing.");
2710 }
2711 }
2712
2713 offset = offsetof(struct lldb_copy_dyld_cache_header_v1, mappingOffset)__builtin_offsetof(struct lldb_copy_dyld_cache_header_v1, mappingOffset
)
;
2714
2715 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
2716
2717 // If the mappingOffset points to a location inside the header, we've
2718 // opened an old dyld shared cache, and should not proceed further.
2719 if (uuid_match &&
2720 mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)) {
2721
2722 DataBufferSP dsc_mapping_info_data_sp = MapFileData(
2723 dsc_filespec, sizeof(struct lldb_copy_dyld_cache_mapping_info),
2724 mappingOffset);
2725
2726 DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp,
2727 byte_order, addr_byte_size);
2728 offset = 0;
2729
2730 // The File addresses (from the in-memory Mach-O load commands) for
2731 // the shared libraries
2732 // in the shared library cache need to be adjusted by an offset to
2733 // match up with the
2734 // dylibOffset identifying field in the
2735 // dyld_cache_local_symbol_entry's. This offset is
2736 // recorded in mapping_offset_value.
2737 const uint64_t mapping_offset_value =
2738 dsc_mapping_info_data.GetU64(&offset);
2739
2740 offset = offsetof(struct lldb_copy_dyld_cache_header_v1,__builtin_offsetof(struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset
)
2741 localSymbolsOffset)__builtin_offsetof(struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset
)
;
2742 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
2743 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
2744
2745 if (localSymbolsOffset && localSymbolsSize) {
2746 // Map the local symbols
2747 DataBufferSP dsc_local_symbols_data_sp =
2748 MapFileData(dsc_filespec, localSymbolsSize, localSymbolsOffset);
2749
2750 if (dsc_local_symbols_data_sp) {
2751 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp,
2752 byte_order, addr_byte_size);
2753
2754 offset = 0;
2755
2756 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
2757 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
2758 UndefinedNameToDescMap undefined_name_to_desc;
2759 SymbolIndexToName reexport_shlib_needs_fixup;
2760
2761 // Read the local_symbols_infos struct in one shot
2762 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
2763 dsc_local_symbols_data.GetU32(&offset,
2764 &local_symbols_info.nlistOffset, 6);
2765
2766 SectionSP text_section_sp(
2767 section_list->FindSectionByName(GetSegmentNameTEXT()));
2768
2769 uint32_t header_file_offset =
2770 (text_section_sp->GetFileAddress() - mapping_offset_value);
2771
2772 offset = local_symbols_info.entriesOffset;
2773 for (uint32_t entry_index = 0;
2774 entry_index < local_symbols_info.entriesCount;
2775 entry_index++) {
2776 struct lldb_copy_dyld_cache_local_symbols_entry
2777 local_symbols_entry;
2778 local_symbols_entry.dylibOffset =
2779 dsc_local_symbols_data.GetU32(&offset);
2780 local_symbols_entry.nlistStartIndex =
2781 dsc_local_symbols_data.GetU32(&offset);
2782 local_symbols_entry.nlistCount =
2783 dsc_local_symbols_data.GetU32(&offset);
2784
2785 if (header_file_offset == local_symbols_entry.dylibOffset) {
2786 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
2787
2788 // The normal nlist code cannot correctly size the Symbols
2789 // array, we need to allocate it here.
2790 sym = symtab->Resize(
2791 symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
2792 unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2793 num_syms = symtab->GetNumSymbols();
2794
2795 nlist_data_offset =
2796 local_symbols_info.nlistOffset +
2797 (nlist_byte_size * local_symbols_entry.nlistStartIndex);
2798 uint32_t string_table_offset =
2799 local_symbols_info.stringsOffset;
2800
2801 for (uint32_t nlist_index = 0;
2802 nlist_index < local_symbols_entry.nlistCount;
2803 nlist_index++) {
2804 /////////////////////////////
2805 {
2806 struct nlist_64 nlist;
2807 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(
2808 nlist_data_offset, nlist_byte_size))
2809 break;
2810
2811 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(
2812 &nlist_data_offset);
2813 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked(
2814 &nlist_data_offset);
2815 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked(
2816 &nlist_data_offset);
2817 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked(
2818 &nlist_data_offset);
2819 nlist.n_value =
2820 dsc_local_symbols_data.GetAddress_unchecked(
2821 &nlist_data_offset);
2822
2823 SymbolType type = eSymbolTypeInvalid;
2824 const char *symbol_name = dsc_local_symbols_data.PeekCStr(
2825 string_table_offset + nlist.n_strx);
2826
2827 if (symbol_name == NULL__null) {
2828 // No symbol should be NULL, even the symbols with no
2829 // string values should have an offset zero which points
2830 // to an empty C-string
2831 Host::SystemLog(
2832 Host::eSystemLogError,
2833 "error: DSC unmapped local symbol[%u] has invalid "
2834 "string table offset 0x%x in %s, ignoring symbol\n",
2835 entry_index, nlist.n_strx,
2836 module_sp->GetFileSpec().GetPath().c_str());
2837 continue;
2838 }
2839 if (symbol_name[0] == '\0')
2840 symbol_name = NULL__null;
2841
2842 const char *symbol_name_non_abi_mangled = NULL__null;
2843
2844 SectionSP symbol_section;
2845 uint32_t symbol_byte_size = 0;
2846 bool add_nlist = true;
2847 bool is_debug = ((nlist.n_type & N_STAB) != 0);
2848 bool demangled_is_synthesized = false;
2849 bool is_gsym = false;
2850 bool set_value = true;
2851
2852 assert(sym_idx < num_syms)(static_cast <bool> (sym_idx < num_syms) ? void (0) :
__assert_fail ("sym_idx < num_syms", "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp"
, 2852, __extension__ __PRETTY_FUNCTION__))
;
2853
2854 sym[sym_idx].SetDebug(is_debug);
2855
2856 if (is_debug) {
2857 switch (nlist.n_type) {
2858 case N_GSYM:
2859 // global symbol: name,,NO_SECT,type,0
2860 // Sometimes the N_GSYM value contains the address.
2861
2862 // FIXME: In the .o files, we have a GSYM and a debug
2863 // symbol for all the ObjC data. They
2864 // have the same address, but we want to ensure that
2865 // we always find only the real symbol,
2866 // 'cause we don't currently correctly attribute the
2867 // GSYM one to the ObjCClass/Ivar/MetaClass
2868 // symbol type. This is a temporary hack to make sure
2869 // the ObjectiveC symbols get treated
2870 // correctly. To do this right, we should coalesce
2871 // all the GSYM & global symbols that have the
2872 // same address.
2873
2874 is_gsym = true;
2875 sym[sym_idx].SetExternal(true);
2876
2877 if (symbol_name && symbol_name[0] == '_' &&
2878 symbol_name[1] == 'O') {
2879 llvm::StringRef symbol_name_ref(symbol_name);
2880 if (symbol_name_ref.startswith(
2881 g_objc_v2_prefix_class)) {
2882 symbol_name_non_abi_mangled = symbol_name + 1;
2883 symbol_name =
2884 symbol_name + g_objc_v2_prefix_class.size();
2885 type = eSymbolTypeObjCClass;
2886 demangled_is_synthesized = true;
2887
2888 } else if (symbol_name_ref.startswith(
2889 g_objc_v2_prefix_metaclass)) {
2890 symbol_name_non_abi_mangled = symbol_name + 1;
2891 symbol_name = symbol_name +
2892 g_objc_v2_prefix_metaclass.size();
2893 type = eSymbolTypeObjCMetaClass;
2894 demangled_is_synthesized = true;
2895 } else if (symbol_name_ref.startswith(
2896 g_objc_v2_prefix_ivar)) {
2897 symbol_name_non_abi_mangled = symbol_name + 1;
2898 symbol_name =
2899 symbol_name + g_objc_v2_prefix_ivar.size();
2900 type = eSymbolTypeObjCIVar;
2901 demangled_is_synthesized = true;
2902 }
2903 } else {
2904 if (nlist.n_value != 0)
2905 symbol_section = section_info.GetSection(
2906 nlist.n_sect, nlist.n_value);
2907 type = eSymbolTypeData;
2908 }
2909 break;
2910
2911 case N_FNAME:
2912 // procedure name (f77 kludge): name,,NO_SECT,0,0
2913 type = eSymbolTypeCompiler;
2914 break;
2915
2916 case N_FUN:
2917 // procedure: name,,n_sect,linenumber,address
2918 if (symbol_name) {
2919 type = eSymbolTypeCode;
2920 symbol_section = section_info.GetSection(
2921 nlist.n_sect, nlist.n_value);
2922
2923 N_FUN_addr_to_sym_idx.insert(
2924 std::make_pair(nlist.n_value, sym_idx));
2925 // We use the current number of symbols in the
2926 // symbol table in lieu of
2927 // using nlist_idx in case we ever start trimming
2928 // entries out
2929 N_FUN_indexes.push_back(sym_idx);
2930 } else {
2931 type = eSymbolTypeCompiler;
2932
2933 if (!N_FUN_indexes.empty()) {
2934 // Copy the size of the function into the original
2935 // STAB entry so we don't have
2936 // to hunt for it later
2937 symtab->SymbolAtIndex(N_FUN_indexes.back())
2938 ->SetByteSize(nlist.n_value);
2939 N_FUN_indexes.pop_back();
2940 // We don't really need the end function STAB as
2941 // it contains the size which
2942 // we already placed with the original symbol, so
2943 // don't add it if we want a
2944 // minimal symbol table
2945 add_nlist = false;
2946 }
2947 }
2948 break;
2949
2950 case N_STSYM:
2951 // static symbol: name,,n_sect,type,address
2952 N_STSYM_addr_to_sym_idx.insert(
2953 std::make_pair(nlist.n_value, sym_idx));
2954 symbol_section = section_info.GetSection(
2955 nlist.n_sect, nlist.n_value);
2956 if (symbol_name && symbol_name[0]) {
2957 type = ObjectFile::GetSymbolTypeFromName(
2958 symbol_name + 1, eSymbolTypeData);
2959 }
2960 break;
2961
2962 case N_LCSYM:
2963 // .lcomm symbol: name,,n_sect,type,address
2964 symbol_section = section_info.GetSection(
2965 nlist.n_sect, nlist.n_value);
2966 type = eSymbolTypeCommonBlock;
2967 break;
2968
2969 case N_BNSYM:
2970 // We use the current number of symbols in the symbol
2971 // table in lieu of
2972 // using nlist_idx in case we ever start trimming
2973 // entries out
2974 // Skip these if we want minimal symbol tables
2975 add_nlist = false;
2976 break;
2977
2978 case N_ENSYM:
2979 // Set the size of the N_BNSYM to the terminating
2980 // index of this N_ENSYM
2981 // so that we can always skip the entire symbol if we
2982 // need to navigate
2983 // more quickly at the source level when parsing STABS
2984 // Skip these if we want minimal symbol tables
2985 add_nlist = false;
2986 break;
2987
2988 case N_OPT:
2989 // emitted with gcc2_compiled and in gcc source
2990 type = eSymbolTypeCompiler;
2991 break;
2992
2993 case N_RSYM:
2994 // register sym: name,,NO_SECT,type,register
2995 type = eSymbolTypeVariable;
2996 break;
2997
2998 case N_SLINE:
2999 // src line: 0,,n_sect,linenumber,address
3000 symbol_section = section_info.GetSection(
3001 nlist.n_sect, nlist.n_value);
3002 type = eSymbolTypeLineEntry;
3003 break;
3004
3005 case N_SSYM:
3006 // structure elt: name,,NO_SECT,type,struct_offset
3007 type = eSymbolTypeVariableType;
3008 break;
3009
3010 case N_SO:
3011 // source file name
3012 type = eSymbolTypeSourceFile;
3013 if (symbol_name == NULL__null) {
3014 add_nlist = false;
3015 if (N_SO_index != UINT32_MAX(4294967295U)) {
3016 // Set the size of the N_SO to the terminating
3017 // index of this N_SO
3018 // so that we can always skip the entire N_SO if
3019 // we need to navigate
3020 // more quickly at the source level when parsing
3021 // STABS
3022 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
3023 symbol_ptr->SetByteSize(sym_idx);
3024 symbol_ptr->SetSizeIsSibling(true);
3025 }
3026 N_NSYM_indexes.clear();
3027 N_INCL_indexes.clear();
3028 N_BRAC_indexes.clear();
3029 N_COMM_indexes.clear();
3030 N_FUN_indexes.clear();
3031 N_SO_index = UINT32_MAX(4294967295U);
3032 } else {
3033 // We use the current number of symbols in the
3034 // symbol table in lieu of
3035 // using nlist_idx in case we ever start trimming
3036 // entries out
3037 const bool N_SO_has_full_path =
3038 symbol_name[0] == '/';
3039 if (N_SO_has_full_path) {
3040 if ((N_SO_index == sym_idx - 1) &&
3041 ((sym_idx - 1) < num_syms)) {
3042 // We have two consecutive N_SO entries where
3043 // the first contains a directory
3044 // and the second contains a full path.
3045 sym[sym_idx - 1].GetMangled().SetValue(
3046 ConstString(symbol_name), false);
3047 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3048 add_nlist = false;
3049 } else {
3050 // This is the first entry in a N_SO that
3051 // contains a directory or
3052 // a full path to the source file
3053 N_SO_index = sym_idx;
3054 }
3055 } else if ((N_SO_index == sym_idx - 1) &&
3056 ((sym_idx - 1) < num_syms)) {
3057 // This is usually the second N_SO entry that
3058 // contains just the filename,
3059 // so here we combine it with the first one if we
3060 // are minimizing the symbol table
3061 const char *so_path =
3062 sym[sym_idx - 1]
3063 .GetMangled()
3064 .GetDemangledName(
3065 lldb::eLanguageTypeUnknown)
3066 .AsCString();
3067 if (so_path && so_path[0]) {
3068 std::string full_so_path(so_path);
3069 const size_t double_slash_pos =
3070 full_so_path.find("//");
3071 if (double_slash_pos != std::string::npos) {
3072 // The linker has been generating bad N_SO
3073 // entries with doubled up paths
3074 // in the format "%s%s" where the first string
3075 // in the DW_AT_comp_dir,
3076 // and the second is the directory for the
3077 // source file so you end up with
3078 // a path that looks like "/tmp/src//tmp/src/"
3079 FileSpec so_dir(so_path, false);
3080 if (!so_dir.Exists()) {
3081 so_dir.SetFile(
3082 &full_so_path[double_slash_pos + 1],
3083 false);
3084 if (so_dir.Exists()) {
3085 // Trim off the incorrect path
3086 full_so_path.erase(0,
3087 double_slash_pos + 1);
3088 }
3089 }
3090 }
3091 if (*full_so_path.rbegin() != '/')
3092 full_so_path += '/';
3093 full_so_path += symbol_name;
3094 sym[sym_idx - 1].GetMangled().SetValue(
3095 ConstString(full_so_path.c_str()), false);
3096 add_nlist = false;
3097 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3098 }
3099 } else {
3100 // This could be a relative path to a N_SO
3101 N_SO_index = sym_idx;
3102 }
3103 }
3104 break;
3105
3106 case N_OSO:
3107 // object file name: name,,0,0,st_mtime
3108 type = eSymbolTypeObjectFile;
3109 break;
3110
3111 case N_LSYM:
3112 // local sym: name,,NO_SECT,type,offset
3113 type = eSymbolTypeLocal;
3114 break;
3115
3116 //----------------------------------------------------------------------
3117 // INCL scopes
3118 //----------------------------------------------------------------------
3119 case N_BINCL:
3120 // include file beginning: name,,NO_SECT,0,sum
3121 // We use the current number of symbols in the symbol
3122 // table in lieu of
3123 // using nlist_idx in case we ever start trimming
3124 // entries out
3125 N_INCL_indexes.push_back(sym_idx);
3126 type = eSymbolTypeScopeBegin;
3127 break;
3128
3129 case N_EINCL:
3130 // include file end: name,,NO_SECT,0,0
3131 // Set the size of the N_BINCL to the terminating
3132 // index of this N_EINCL
3133 // so that we can always skip the entire symbol if we
3134 // need to navigate
3135 // more quickly at the source level when parsing STABS
3136 if (!N_INCL_indexes.empty()) {
3137 symbol_ptr =
3138 symtab->SymbolAtIndex(N_INCL_indexes.back());
3139 symbol_ptr->SetByteSize(sym_idx + 1);
3140 symbol_ptr->SetSizeIsSibling(true);
3141 N_INCL_indexes.pop_back();
3142 }
3143 type = eSymbolTypeScopeEnd;
3144 break;
3145
3146 case N_SOL:
3147 // #included file name: name,,n_sect,0,address
3148 type = eSymbolTypeHeaderFile;
3149
3150 // We currently don't use the header files on darwin
3151 add_nlist = false;
3152 break;
3153
3154 case N_PARAMS:
3155 // compiler parameters: name,,NO_SECT,0,0
3156 type = eSymbolTypeCompiler;
3157 break;
3158
3159 case N_VERSION:
3160 // compiler version: name,,NO_SECT,0,0
3161 type = eSymbolTypeCompiler;
3162 break;
3163
3164 case N_OLEVEL:
3165 // compiler -O level: name,,NO_SECT,0,0
3166 type = eSymbolTypeCompiler;
3167 break;
3168
3169 case N_PSYM:
3170 // parameter: name,,NO_SECT,type,offset
3171 type = eSymbolTypeVariable;
3172 break;
3173
3174 case N_ENTRY:
3175 // alternate entry: name,,n_sect,linenumber,address
3176 symbol_section = section_info.GetSection(
3177 nlist.n_sect, nlist.n_value);
3178 type = eSymbolTypeLineEntry;
3179 break;
3180
3181 //----------------------------------------------------------------------
3182 // Left and Right Braces
3183 //----------------------------------------------------------------------
3184 case N_LBRAC:
3185 // left bracket: 0,,NO_SECT,nesting level,address
3186 // We use the current number of symbols in the symbol
3187 // table in lieu of
3188 // using nlist_idx in case we ever start trimming
3189 // entries out
3190 symbol_section = section_info.GetSection(
3191 nlist.n_sect, nlist.n_value);
3192 N_BRAC_indexes.push_back(sym_idx);
3193 type = eSymbolTypeScopeBegin;
3194 break;
3195
3196 case N_RBRAC:
3197 // right bracket: 0,,NO_SECT,nesting level,address
3198 // Set the size of the N_LBRAC to the terminating
3199 // index of this N_RBRAC
3200 // so that we can always skip the entire symbol if we
3201 // need to navigate
3202 // more quickly at the source level when parsing STABS
3203 symbol_section = section_info.GetSection(
3204 nlist.n_sect, nlist.n_value);
3205 if (!N_BRAC_indexes.empty()) {
3206 symbol_ptr =
3207 symtab->SymbolAtIndex(N_BRAC_indexes.back());
3208 symbol_ptr->SetByteSize(sym_idx + 1);
3209 symbol_ptr->SetSizeIsSibling(true);
3210 N_BRAC_indexes.pop_back();
3211 }
3212 type = eSymbolTypeScopeEnd;
3213 break;
3214
3215 case N_EXCL:
3216 // deleted include file: name,,NO_SECT,0,sum
3217 type = eSymbolTypeHeaderFile;
3218 break;
3219
3220 //----------------------------------------------------------------------
3221 // COMM scopes
3222 //----------------------------------------------------------------------
3223 case N_BCOMM:
3224 // begin common: name,,NO_SECT,0,0
3225 // We use the current number of symbols in the symbol
3226 // table in lieu of
3227 // using nlist_idx in case we ever start trimming
3228 // entries out
3229 type = eSymbolTypeScopeBegin;
3230 N_COMM_indexes.push_back(sym_idx);
3231 break;
3232
3233 case N_ECOML:
3234 // end common (local name): 0,,n_sect,0,address
3235 symbol_section = section_info.GetSection(
3236 nlist.n_sect, nlist.n_value);
3237 // Fall through
3238
3239 case N_ECOMM:
3240 // end common: name,,n_sect,0,0
3241 // Set the size of the N_BCOMM to the terminating
3242 // index of this N_ECOMM/N_ECOML
3243 // so that we can always skip the entire symbol if we
3244 // need to navigate
3245 // more quickly at the source level when parsing STABS
3246 if (!N_COMM_indexes.empty()) {
3247 symbol_ptr =
3248 symtab->SymbolAtIndex(N_COMM_indexes.back());
3249 symbol_ptr->SetByteSize(sym_idx + 1);
3250 symbol_ptr->SetSizeIsSibling(true);
3251 N_COMM_indexes.pop_back();
3252 }
3253 type = eSymbolTypeScopeEnd;
3254 break;
3255
3256 case N_LENG:
3257 // second stab entry with length information
3258 type = eSymbolTypeAdditional;
3259 break;
3260
3261 default:
3262 break;
3263 }
3264 } else {
3265 // uint8_t n_pext = N_PEXT & nlist.n_type;
3266 uint8_t n_type = N_TYPE & nlist.n_type;
3267 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
3268
3269 switch (n_type) {
3270 case N_INDR: {
3271 const char *reexport_name_cstr =
3272 strtab_data.PeekCStr(nlist.n_value);
3273 if (reexport_name_cstr && reexport_name_cstr[0]) {
3274 type = eSymbolTypeReExported;
3275 ConstString reexport_name(
3276 reexport_name_cstr +
3277 ((reexport_name_cstr[0] == '_') ? 1 : 0));
3278 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3279 set_value = false;
3280 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3281 indirect_symbol_names.insert(
3282 ConstString(symbol_name +
3283 ((symbol_name[0] == '_') ? 1 : 0)));
3284 } else
3285 type = eSymbolTypeUndefined;
3286 } break;
3287
3288 case N_UNDF:
3289 if (symbol_name && symbol_name[0]) {
3290 ConstString undefined_name(
3291 symbol_name +
3292 ((symbol_name[0] == '_') ? 1 : 0));
3293 undefined_name_to_desc[undefined_name] =
3294 nlist.n_desc;
3295 }
3296 // Fall through
3297 case N_PBUD:
3298 type = eSymbolTypeUndefined;
3299 break;
3300
3301 case N_ABS:
3302 type = eSymbolTypeAbsolute;
3303 break;
3304
3305 case N_SECT: {
3306 symbol_section = section_info.GetSection(
3307 nlist.n_sect, nlist.n_value);
3308
3309 if (symbol_section == NULL__null) {
3310 // TODO: warn about this?
3311 add_nlist = false;
3312 break;
3313 }
3314
3315 if (TEXT_eh_frame_sectID == nlist.n_sect) {
3316 type = eSymbolTypeException;
3317 } else {
3318 uint32_t section_type =
3319 symbol_section->Get() & SECTION_TYPE;
3320
3321 switch (section_type) {
3322 case S_CSTRING_LITERALS:
3323 type = eSymbolTypeData;
3324 break; // section with only literal C strings
3325 case S_4BYTE_LITERALS:
3326 type = eSymbolTypeData;
3327 break; // section with only 4 byte literals
3328 case S_8BYTE_LITERALS:
3329 type = eSymbolTypeData;
3330 break; // section with only 8 byte literals
3331 case S_LITERAL_POINTERS:
3332 type = eSymbolTypeTrampoline;
3333 break; // section with only pointers to literals
3334 case S_NON_LAZY_SYMBOL_POINTERS:
3335 type = eSymbolTypeTrampoline;
3336 break; // section with only non-lazy symbol
3337 // pointers
3338 case S_LAZY_SYMBOL_POINTERS:
3339 type = eSymbolTypeTrampoline;
3340 break; // section with only lazy symbol pointers
3341 case S_SYMBOL_STUBS:
3342 type = eSymbolTypeTrampoline;
3343 break; // section with only symbol stubs, byte
3344 // size of stub in the reserved2 field
3345 case S_MOD_INIT_FUNC_POINTERS:
3346 type = eSymbolTypeCode;
3347 break; // section with only function pointers for
3348 // initialization
3349 case S_MOD_TERM_FUNC_POINTERS:
3350 type = eSymbolTypeCode;
3351 break; // section with only function pointers for
3352 // termination
3353 case S_INTERPOSING:
3354 type = eSymbolTypeTrampoline;
3355 break; // section with only pairs of function
3356 // pointers for interposing
3357 case S_16BYTE_LITERALS:
3358 type = eSymbolTypeData;
3359 break; // section with only 16 byte literals
3360 case S_DTRACE_DOF:
3361 type = eSymbolTypeInstrumentation;
3362 break;
3363 case S_LAZY_DYLIB_SYMBOL_POINTERS:
3364 type = eSymbolTypeTrampoline;
3365 break;
3366 default:
3367 switch (symbol_section->GetType()) {
3368 case lldb::eSectionTypeCode:
3369 type = eSymbolTypeCode;
3370 break;
3371 case eSectionTypeData:
3372 case eSectionTypeDataCString: // Inlined C string
3373 // data
3374 case eSectionTypeDataCStringPointers: // Pointers
3375 // to C
3376 // string
3377 // data
3378 case eSectionTypeDataSymbolAddress: // Address of
3379 // a symbol in
3380 // the symbol
3381 // table
3382 case eSectionTypeData4:
3383 case eSectionTypeData8:
3384 case eSectionTypeData16:
3385 type = eSymbolTypeData;
3386 break;
3387 default:
3388 break;
3389 }
3390 break;
3391 }
3392
3393 if (type == eSymbolTypeInvalid) {
3394 const char *symbol_sect_name =
3395 symbol_section->GetName().AsCString();
3396 if (symbol_section->IsDescendant(
3397 text_section_sp.get())) {
3398 if (symbol_section->IsClear(
3399 S_ATTR_PURE_INSTRUCTIONS |
3400 S_ATTR_SELF_MODIFYING_CODE |
3401 S_ATTR_SOME_INSTRUCTIONS))
3402 type = eSymbolTypeData;
3403 else
3404 type = eSymbolTypeCode;
3405 } else if (symbol_section->IsDescendant(
3406 data_section_sp.get()) ||
3407 symbol_section->IsDescendant(
3408 data_dirty_section_sp.get()) ||
3409 symbol_section->IsDescendant(
3410 data_const_section_sp.get())) {
3411 if (symbol_sect_name &&
3412 ::strstr(symbol_sect_name, "__objc") ==
3413 symbol_sect_name) {
3414 type = eSymbolTypeRuntime;
3415
3416 if (symbol_name) {
3417 llvm::StringRef symbol_name_ref(
3418 symbol_name);
3419 if (symbol_name_ref.startswith("_OBJC_")) {
3420 static const llvm::StringRef
3421 g_objc_v2_prefix_class(
3422 "_OBJC_CLASS_$_");
3423 static const llvm::StringRef
3424 g_objc_v2_prefix_metaclass(
3425 "_OBJC_METACLASS_$_");
3426 static const llvm::StringRef
3427 g_objc_v2_prefix_ivar(
3428 "_OBJC_IVAR_$_");
3429 if (symbol_name_ref.startswith(
3430 g_objc_v2_prefix_class)) {
3431 symbol_name_non_abi_mangled =
3432 symbol_name + 1;
3433 symbol_name =
3434 symbol_name +
3435 g_objc_v2_prefix_class.size();
3436 type = eSymbolTypeObjCClass;
3437 demangled_is_synthesized = true;
3438 } else if (
3439 symbol_name_ref.startswith(
3440 g_objc_v2_prefix_metaclass)) {
3441 symbol_name_non_abi_mangled =
3442 symbol_name + 1;
3443 symbol_name =
3444 symbol_name +
3445 g_objc_v2_prefix_metaclass.size();
3446 type = eSymbolTypeObjCMetaClass;
3447 demangled_is_synthesized = true;
3448 } else if (symbol_name_ref.startswith(
3449 g_objc_v2_prefix_ivar)) {
3450 symbol_name_non_abi_mangled =
3451 symbol_name + 1;
3452 symbol_name =
3453 symbol_name +
3454 g_objc_v2_prefix_ivar.size();
3455 type = eSymbolTypeObjCIVar;
3456 demangled_is_synthesized = true;
3457 }
3458 }
3459 }
3460 } else if (symbol_sect_name &&
3461 ::strstr(symbol_sect_name,
3462 "__gcc_except_tab") ==
3463 symbol_sect_name) {
3464 type = eSymbolTypeException;
3465 } else {
3466 type = eSymbolTypeData;
3467 }
3468 } else if (symbol_sect_name &&
3469 ::strstr(symbol_sect_name,
3470 "__IMPORT") ==
3471 symbol_sect_name) {
3472 type = eSymbolTypeTrampoline;
3473 } else if (symbol_section->IsDescendant(
3474 objc_section_sp.get())) {
3475 type = eSymbolTypeRuntime;
3476 if (symbol_name && symbol_name[0] == '.') {
3477 llvm::StringRef symbol_name_ref(symbol_name);
3478 static const llvm::StringRef
3479 g_objc_v1_prefix_class(
3480 ".objc_class_name_");
3481 if (symbol_name_ref.startswith(
3482 g_objc_v1_prefix_class)) {
3483 symbol_name_non_abi_mangled = symbol_name;
3484 symbol_name = symbol_name +
3485 g_objc_v1_prefix_class.size();
3486 type = eSymbolTypeObjCClass;
3487 demangled_is_synthesized = true;
3488 }
3489 }
3490 }
3491 }
3492 }
3493 } break;
3494 }
3495 }
3496
3497 if (add_nlist) {
3498 uint64_t symbol_value = nlist.n_value;
3499 if (symbol_name_non_abi_mangled) {
3500 sym[sym_idx].GetMangled().SetMangledName(
3501 ConstString(symbol_name_non_abi_mangled));
3502 sym[sym_idx].GetMangled().SetDemangledName(
3503 ConstString(symbol_name));
3504 } else {
3505 bool symbol_name_is_mangled = false;
3506
3507 if (symbol_name && symbol_name[0] == '_') {
3508 symbol_name_is_mangled = symbol_name[1] == '_';
3509 symbol_name++; // Skip the leading underscore
3510 }
3511
3512 if (symbol_name) {
3513 ConstString const_symbol_name(symbol_name);
3514 sym[sym_idx].GetMangled().SetValue(
3515 const_symbol_name, symbol_name_is_mangled);
3516 if (is_gsym && is_debug) {
3517 const char *gsym_name =
3518 sym[sym_idx]
3519 .GetMangled()
3520 .GetName(lldb::eLanguageTypeUnknown,
3521 Mangled::ePreferMangled)
3522 .GetCString();
3523 if (gsym_name)
3524 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3525 }
3526 }
3527 }
3528 if (symbol_section) {
3529 const addr_t section_file_addr =
3530 symbol_section->GetFileAddress();
3531 if (symbol_byte_size == 0 &&
3532 function_starts_count > 0) {
3533 addr_t symbol_lookup_file_addr = nlist.n_value;
3534 // Do an exact address match for non-ARM addresses,
3535 // else get the closest since
3536 // the symbol might be a thumb symbol which has an
3537 // address with bit zero set
3538 FunctionStarts::Entry *func_start_entry =
3539 function_starts.FindEntry(
3540 symbol_lookup_file_addr, !is_arm);
3541 if (is_arm && func_start_entry) {
3542 // Verify that the function start address is the
3543 // symbol address (ARM)
3544 // or the symbol address + 1 (thumb)
3545 if (func_start_entry->addr !=
3546 symbol_lookup_file_addr &&
3547 func_start_entry->addr !=
3548 (symbol_lookup_file_addr + 1)) {
3549 // Not the right entry, NULL it out...
3550 func_start_entry = NULL__null;
3551 }
3552 }
3553 if (func_start_entry) {
3554 func_start_entry->data = true;
3555
3556 addr_t symbol_file_addr = func_start_entry->addr;
3557 uint32_t symbol_flags = 0;
3558 if (is_arm) {
3559 if (symbol_file_addr & 1)
3560 symbol_flags =
3561 MACHO_NLIST_ARM_SYMBOL_IS_THUMB0x0008;
3562 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK0xfffffffffffffffeull;
3563 }
3564
3565 const FunctionStarts::Entry
3566 *next_func_start_entry =
3567 function_starts.FindNextEntry(
3568 func_start_entry);
3569 const addr_t section_end_file_addr =
3570 section_file_addr +
3571 symbol_section->GetByteSize();
3572 if (next_func_start_entry) {
3573 addr_t next_symbol_file_addr =
3574 next_func_start_entry->addr;
3575 // Be sure the clear the Thumb address bit when
3576 // we calculate the size
3577 // from the current and next address
3578 if (is_arm)
3579 next_symbol_file_addr &=
3580 THUMB_ADDRESS_BIT_MASK0xfffffffffffffffeull;
3581 symbol_byte_size = std::min<lldb::addr_t>(
3582 next_symbol_file_addr - symbol_file_addr,
3583 section_end_file_addr - symbol_file_addr);
3584 } else {
3585 symbol_byte_size =
3586 section_end_file_addr - symbol_file_addr;
3587 }
3588 }
3589 }
3590 symbol_value -= section_file_addr;
3591 }
3592
3593 if (is_debug == false) {
3594 if (type == eSymbolTypeCode) {
3595 // See if we can find a N_FUN entry for any code
3596 // symbols.
3597 // If we do find a match, and the name matches, then
3598 // we
3599 // can merge the two into just the function symbol
3600 // to avoid
3601 // duplicate entries in the symbol table
3602 std::pair<ValueToSymbolIndexMap::const_iterator,
3603 ValueToSymbolIndexMap::const_iterator>
3604 range;
3605 range = N_FUN_addr_to_sym_idx.equal_range(
3606 nlist.n_value);
3607 if (range.first != range.second) {
3608 bool found_it = false;
3609 for (ValueToSymbolIndexMap::const_iterator pos =
3610 range.first;
3611 pos != range.second; ++pos) {
3612 if (sym[sym_idx].GetMangled().GetName(
3613 lldb::eLanguageTypeUnknown,
3614 Mangled::ePreferMangled) ==
3615 sym[pos->second].GetMangled().GetName(
3616 lldb::eLanguageTypeUnknown,
3617 Mangled::ePreferMangled)) {
3618 m_nlist_idx_to_sym_idx[nlist_idx] =
3619 pos->second;
3620 // We just need the flags from the linker
3621 // symbol, so put these flags
3622 // into the N_FUN flags to avoid duplicate
3623 // symbols in the symbol table
3624 sym[pos->second].SetExternal(
3625 sym[sym_idx].IsExternal());
3626 sym[pos->second].SetFlags(nlist.n_type << 16 |
3627 nlist.n_desc);
3628 if (resolver_addresses.find(nlist.n_value) !=
3629 resolver_addresses.end())
3630 sym[pos->second].SetType(
3631 eSymbolTypeResolver);
3632 sym[sym_idx].Clear();
3633 found_it = true;
3634 break;
3635 }
3636 }
3637 if (found_it)
3638 continue;
3639 } else {
3640 if (resolver_addresses.find(nlist.n_value) !=
3641 resolver_addresses.end())
3642 type = eSymbolTypeResolver;
3643 }
3644 } else if (type == eSymbolTypeData ||
3645 type == eSymbolTypeObjCClass ||
3646 type == eSymbolTypeObjCMetaClass ||
3647 type == eSymbolTypeObjCIVar) {
3648 // See if we can find a N_STSYM entry for any data
3649 // symbols.
3650 // If we do find a match, and the name matches, then
3651 // we
3652 // can merge the two into just the Static symbol to
3653 // avoid
3654 // duplicate entries in the symbol table
3655 std::pair<ValueToSymbolIndexMap::const_iterator,
3656 ValueToSymbolIndexMap::const_iterator>
3657 range;
3658 range = N_STSYM_addr_to_sym_idx.equal_range(
3659 nlist.n_value);
3660 if (range.first != range.second) {
3661 bool found_it = false;
3662 for (ValueToSymbolIndexMap::const_iterator pos =
3663 range.first;
3664 pos != range.second; ++pos) {
3665 if (sym[sym_idx].GetMangled().GetName(
3666 lldb::eLanguageTypeUnknown,
3667 Mangled::ePreferMangled) ==
3668 sym[pos->second].GetMangled().GetName(
3669 lldb::eLanguageTypeUnknown,
3670 Mangled::ePreferMangled)) {
3671 m_nlist_idx_to_sym_idx[nlist_idx] =
3672 pos->second;
3673 // We just need the flags from the linker
3674 // symbol, so put these flags
3675 // into the N_STSYM flags to avoid duplicate
3676 // symbols in the symbol table
3677 sym[pos->second].SetExternal(
3678 sym[sym_idx].IsExternal());
3679 sym[pos->second].SetFlags(nlist.n_type << 16 |
3680 nlist.n_desc);
3681 sym[sym_idx].Clear();
3682 found_it = true;
3683 break;
3684 }
3685 }
3686 if (found_it)
3687 continue;
3688 } else {
3689 const char *gsym_name =
3690 sym[sym_idx]
3691 .GetMangled()
3692 .GetName(lldb::eLanguageTypeUnknown,
3693 Mangled::ePreferMangled)
3694 .GetCString();
3695 if (gsym_name) {
3696 // Combine N_GSYM stab entries with the non stab
3697 // symbol
3698 ConstNameToSymbolIndexMap::const_iterator pos =
3699 N_GSYM_name_to_sym_idx.find(gsym_name);
3700 if (pos != N_GSYM_name_to_sym_idx.end()) {
3701 const uint32_t GSYM_sym_idx = pos->second;
3702 m_nlist_idx_to_sym_idx[nlist_idx] =
3703 GSYM_sym_idx;
3704 // Copy the address, because often the N_GSYM
3705 // address has an invalid address of zero
3706 // when the global is a common symbol
3707 sym[GSYM_sym_idx].GetAddressRef().SetSection(
3708 symbol_section);
3709 sym[GSYM_sym_idx].GetAddressRef().SetOffset(
3710 symbol_value);
3711 // We just need the flags from the linker
3712 // symbol, so put these flags
3713 // into the N_GSYM flags to avoid duplicate
3714 // symbols in the symbol table
3715 sym[GSYM_sym_idx].SetFlags(
3716 nlist.n_type << 16 | nlist.n_desc);
3717 sym[sym_idx].Clear();
3718 continue;
3719 }
3720 }
3721 }
3722 }
3723 }
3724
3725 sym[sym_idx].SetID(nlist_idx);
3726 sym[sym_idx].SetType(type);
3727 if (set_value) {
3728 sym[sym_idx].GetAddressRef().SetSection(
3729 symbol_section);
3730 sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
3731 }
3732 sym[sym_idx].SetFlags(nlist.n_type << 16 |
3733 nlist.n_desc);
3734
3735 if (symbol_byte_size > 0)
3736 sym[sym_idx].SetByteSize(symbol_byte_size);
3737
3738 if (demangled_is_synthesized)
3739 sym[sym_idx].SetDemangledNameIsSynthesized(true);
3740 ++sym_idx;
3741 } else {
3742 sym[sym_idx].Clear();
3743 }
3744 }
3745 /////////////////////////////
3746 }
3747 break; // No more entries to consider
3748 }
3749 }
3750
3751 for (const auto &pos : reexport_shlib_needs_fixup) {
3752 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3753 if (undef_pos != undefined_name_to_desc.end()) {
3754 const uint8_t dylib_ordinal =
3755 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3756 if (dylib_ordinal > 0 &&
3757 dylib_ordinal < dylib_files.GetSize())
3758 sym[pos.first].SetReExportedSymbolSharedLibrary(
3759 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
3760 }
3761 }
3762 }
3763 }
3764 }
3765 }
3766 }
3767
3768 // Must reset this in case it was mutated above!
3769 nlist_data_offset = 0;
3770#endif
3771
3772 if (nlist_data.GetByteSize() > 0) {
41
Taking true branch
3773
3774 // If the sym array was not created while parsing the DSC unmapped
3775 // symbols, create it now.
3776 if (sym == NULL__null) {
42
Taking true branch
3777 sym = symtab->Resize(symtab_load_command.nsyms +
3778 m_dysymtab.nindirectsyms);
3779 num_syms = symtab->GetNumSymbols();
3780 }
3781
3782 if (unmapped_local_symbols_found) {
43
Taking false branch
3783 assert(m_dysymtab.ilocalsym == 0)(static_cast <bool> (m_dysymtab.ilocalsym == 0) ? void (
0) : __assert_fail ("m_dysymtab.ilocalsym == 0", "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp"
, 3783, __extension__ __PRETTY_FUNCTION__))
;
3784 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3785 nlist_idx = m_dysymtab.nlocalsym;
3786 } else {
3787 nlist_idx = 0;
3788 }
3789
3790 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
3791 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
3792 UndefinedNameToDescMap undefined_name_to_desc;
3793 SymbolIndexToName reexport_shlib_needs_fixup;
3794 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) {
44
Loop condition is true. Entering loop body
3795 struct nlist_64 nlist;
3796 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset,
45
Taking false branch
3797 nlist_byte_size))
3798 break;
3799
3800 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
3801 nlist.n_type = nlist_data.GetU8_unchecked(&nlist_data_offset);
3802 nlist.n_sect = nlist_data.GetU8_unchecked(&nlist_data_offset);
3803 nlist.n_desc = nlist_data.GetU16_unchecked(&nlist_data_offset);
3804 nlist.n_value = nlist_data.GetAddress_unchecked(&nlist_data_offset);
3805
3806 SymbolType type = eSymbolTypeInvalid;
3807 const char *symbol_name = NULL__null;
3808
3809 if (have_strtab_data) {
46
Taking true branch
3810 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
3811
3812 if (symbol_name == NULL__null) {
47
Assuming 'symbol_name' is not equal to NULL
48
Taking false branch
3813 // No symbol should be NULL, even the symbols with no
3814 // string values should have an offset zero which points
3815 // to an empty C-string
3816 Host::SystemLog(Host::eSystemLogError,
3817 "error: symbol[%u] has invalid string table offset "
3818 "0x%x in %s, ignoring symbol\n",
3819 nlist_idx, nlist.n_strx,
3820 module_sp->GetFileSpec().GetPath().c_str());
3821 continue;
3822 }
3823 if (symbol_name[0] == '\0')
49
Assuming the condition is true
50
Taking true branch
3824 symbol_name = NULL__null;
51
Null pointer value stored to 'symbol_name'
3825 } else {
3826 const addr_t str_addr = strtab_addr + nlist.n_strx;
3827 Status str_error;
3828 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name,
3829 str_error))
3830 symbol_name = memory_symbol_name.c_str();
3831 }
3832 const char *symbol_name_non_abi_mangled = NULL__null;
3833
3834 SectionSP symbol_section;
3835 lldb::addr_t symbol_byte_size = 0;
3836 bool add_nlist = true;
3837 bool is_gsym = false;
3838 bool is_debug = ((nlist.n_type & N_STAB) != 0);
52
Assuming the condition is false
3839 bool demangled_is_synthesized = false;
3840 bool set_value = true;
3841 assert(sym_idx < num_syms)(static_cast <bool> (sym_idx < num_syms) ? void (0) :
__assert_fail ("sym_idx < num_syms", "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp"
, 3841, __extension__ __PRETTY_FUNCTION__))
;
3842
3843 sym[sym_idx].SetDebug(is_debug);
3844
3845 if (is_debug) {
53
Taking false branch
3846 switch (nlist.n_type) {
3847 case N_GSYM:
3848 // global symbol: name,,NO_SECT,type,0
3849 // Sometimes the N_GSYM value contains the address.
3850
3851 // FIXME: In the .o files, we have a GSYM and a debug symbol for all
3852 // the ObjC data. They
3853 // have the same address, but we want to ensure that we always find
3854 // only the real symbol,
3855 // 'cause we don't currently correctly attribute the GSYM one to the
3856 // ObjCClass/Ivar/MetaClass
3857 // symbol type. This is a temporary hack to make sure the
3858 // ObjectiveC symbols get treated
3859 // correctly. To do this right, we should coalesce all the GSYM &
3860 // global symbols that have the
3861 // same address.
3862 is_gsym = true;
3863 sym[sym_idx].SetExternal(true);
3864
3865 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O') {
3866 llvm::StringRef symbol_name_ref(symbol_name);
3867 if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
3868 symbol_name_non_abi_mangled = symbol_name + 1;
3869 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3870 type = eSymbolTypeObjCClass;
3871 demangled_is_synthesized = true;
3872
3873 } else if (symbol_name_ref.startswith(
3874 g_objc_v2_prefix_metaclass)) {
3875 symbol_name_non_abi_mangled = symbol_name + 1;
3876 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3877 type = eSymbolTypeObjCMetaClass;
3878 demangled_is_synthesized = true;
3879 } else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) {
3880 symbol_name_non_abi_mangled = symbol_name + 1;
3881 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3882 type = eSymbolTypeObjCIVar;
3883 demangled_is_synthesized = true;
3884 }
3885 } else {
3886 if (nlist.n_value != 0)
3887 symbol_section =
3888 section_info.GetSection(nlist.n_sect, nlist.n_value);
3889 type = eSymbolTypeData;
3890 }
3891 break;
3892
3893 case N_FNAME:
3894 // procedure name (f77 kludge): name,,NO_SECT,0,0
3895 type = eSymbolTypeCompiler;
3896 break;
3897
3898 case N_FUN:
3899 // procedure: name,,n_sect,linenumber,address
3900 if (symbol_name) {
3901 type = eSymbolTypeCode;
3902 symbol_section =
3903 section_info.GetSection(nlist.n_sect, nlist.n_value);
3904
3905 N_FUN_addr_to_sym_idx.insert(
3906 std::make_pair(nlist.n_value, sym_idx));
3907 // We use the current number of symbols in the symbol table in
3908 // lieu of
3909 // using nlist_idx in case we ever start trimming entries out
3910 N_FUN_indexes.push_back(sym_idx);
3911 } else {
3912 type = eSymbolTypeCompiler;
3913
3914 if (!N_FUN_indexes.empty()) {
3915 // Copy the size of the function into the original STAB entry so
3916 // we don't have
3917 // to hunt for it later
3918 symtab->SymbolAtIndex(N_FUN_indexes.back())
3919 ->SetByteSize(nlist.n_value);
3920 N_FUN_indexes.pop_back();
3921 // We don't really need the end function STAB as it contains the
3922 // size which
3923 // we already placed with the original symbol, so don't add it
3924 // if we want a
3925 // minimal symbol table
3926 add_nlist = false;
3927 }
3928 }
3929 break;
3930
3931 case N_STSYM:
3932 // static symbol: name,,n_sect,type,address
3933 N_STSYM_addr_to_sym_idx.insert(
3934 std::make_pair(nlist.n_value, sym_idx));
3935 symbol_section =
3936 section_info.GetSection(nlist.n_sect, nlist.n_value);
3937 if (symbol_name && symbol_name[0]) {
3938 type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1,
3939 eSymbolTypeData);
3940 }
3941 break;
3942
3943 case N_LCSYM:
3944 // .lcomm symbol: name,,n_sect,type,address
3945 symbol_section =
3946 section_info.GetSection(nlist.n_sect, nlist.n_value);
3947 type = eSymbolTypeCommonBlock;
3948 break;
3949
3950 case N_BNSYM:
3951 // We use the current number of symbols in the symbol table in lieu
3952 // of
3953 // using nlist_idx in case we ever start trimming entries out
3954 // Skip these if we want minimal symbol tables
3955 add_nlist = false;
3956 break;
3957
3958 case N_ENSYM:
3959 // Set the size of the N_BNSYM to the terminating index of this
3960 // N_ENSYM
3961 // so that we can always skip the entire symbol if we need to
3962 // navigate
3963 // more quickly at the source level when parsing STABS
3964 // Skip these if we want minimal symbol tables
3965 add_nlist = false;
3966 break;
3967
3968 case N_OPT:
3969 // emitted with gcc2_compiled and in gcc source
3970 type = eSymbolTypeCompiler;
3971 break;
3972
3973 case N_RSYM:
3974 // register sym: name,,NO_SECT,type,register
3975 type = eSymbolTypeVariable;
3976 break;
3977
3978 case N_SLINE:
3979 // src line: 0,,n_sect,linenumber,address
3980 symbol_section =
3981 section_info.GetSection(nlist.n_sect, nlist.n_value);
3982 type = eSymbolTypeLineEntry;
3983 break;
3984
3985 case N_SSYM:
3986 // structure elt: name,,NO_SECT,type,struct_offset
3987 type = eSymbolTypeVariableType;
3988 break;
3989
3990 case N_SO:
3991 // source file name
3992 type = eSymbolTypeSourceFile;
3993 if (symbol_name == NULL__null) {
3994 add_nlist = false;
3995 if (N_SO_index != UINT32_MAX(4294967295U)) {
3996 // Set the size of the N_SO to the terminating index of this
3997 // N_SO
3998 // so that we can always skip the entire N_SO if we need to
3999 // navigate
4000 // more quickly at the source level when parsing STABS
4001 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
4002 symbol_ptr->SetByteSize(sym_idx);
4003 symbol_ptr->SetSizeIsSibling(true);
4004 }
4005 N_NSYM_indexes.clear();
4006 N_INCL_indexes.clear();
4007 N_BRAC_indexes.clear();
4008 N_COMM_indexes.clear();
4009 N_FUN_indexes.clear();
4010 N_SO_index = UINT32_MAX(4294967295U);
4011 } else {
4012 // We use the current number of symbols in the symbol table in
4013 // lieu of
4014 // using nlist_idx in case we ever start trimming entries out
4015 const bool N_SO_has_full_path = symbol_name[0] == '/';
4016 if (N_SO_has_full_path) {
4017 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) {
4018 // We have two consecutive N_SO entries where the first
4019 // contains a directory
4020 // and the second contains a full path.
4021 sym[sym_idx - 1].GetMangled().SetValue(
4022 ConstString(symbol_name), false);
4023 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
4024 add_nlist = false;
4025 } else {
4026 // This is the first entry in a N_SO that contains a directory
4027 // or
4028 // a full path to the source file
4029 N_SO_index = sym_idx;
4030 }
4031 } else if ((N_SO_index == sym_idx - 1) &&
4032 ((sym_idx - 1) < num_syms)) {
4033 // This is usually the second N_SO entry that contains just the
4034 // filename,
4035 // so here we combine it with the first one if we are minimizing
4036 // the symbol table
4037 const char *so_path =
4038 sym[sym_idx - 1]
4039 .GetMangled()
4040 .GetDemangledName(lldb::eLanguageTypeUnknown)
4041 .AsCString();
4042 if (so_path && so_path[0]) {
4043 std::string full_so_path(so_path);
4044 const size_t double_slash_pos = full_so_path.find("//");
4045 if (double_slash_pos != std::string::npos) {
4046 // The linker has been generating bad N_SO entries with
4047 // doubled up paths
4048 // in the format "%s%s" where the first string in the
4049 // DW_AT_comp_dir,
4050 // and the second is the directory for the source file so
4051 // you end up with
4052 // a path that looks like "/tmp/src//tmp/src/"
4053 FileSpec so_dir(so_path, false);
4054 if (!so_dir.Exists()) {
4055 so_dir.SetFile(&full_so_path[double_slash_pos + 1],
4056 false);
4057 if (so_dir.Exists()) {
4058 // Trim off the incorrect path
4059 full_so_path.erase(0, double_slash_pos + 1);
4060 }
4061 }
4062 }
4063 if (*full_so_path.rbegin() != '/')
4064 full_so_path += '/';
4065 full_so_path += symbol_name;
4066 sym[sym_idx - 1].GetMangled().SetValue(
4067 ConstString(full_so_path.c_str()), false);
4068 add_nlist = false;
4069 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
4070 }
4071 } else {
4072 // This could be a relative path to a N_SO
4073 N_SO_index = sym_idx;
4074 }
4075 }
4076 break;
4077
4078 case N_OSO:
4079 // object file name: name,,0,0,st_mtime
4080 type = eSymbolTypeObjectFile;
4081 break;
4082
4083 case N_LSYM:
4084 // local sym: name,,NO_SECT,type,offset
4085 type = eSymbolTypeLocal;
4086 break;
4087
4088 //----------------------------------------------------------------------
4089 // INCL scopes
4090 //----------------------------------------------------------------------
4091 case N_BINCL:
4092 // include file beginning: name,,NO_SECT,0,sum
4093 // We use the current number of symbols in the symbol table in lieu
4094 // of
4095 // using nlist_idx in case we ever start trimming entries out
4096 N_INCL_indexes.push_back(sym_idx);
4097 type = eSymbolTypeScopeBegin;
4098 break;
4099
4100 case N_EINCL:
4101 // include file end: name,,NO_SECT,0,0
4102 // Set the size of the N_BINCL to the terminating index of this
4103 // N_EINCL
4104 // so that we can always skip the entire symbol if we need to
4105 // navigate
4106 // more quickly at the source level when parsing STABS
4107 if (!N_INCL_indexes.empty()) {
4108 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
4109 symbol_ptr->SetByteSize(sym_idx + 1);
4110 symbol_ptr->SetSizeIsSibling(true);
4111 N_INCL_indexes.pop_back();
4112 }
4113 type = eSymbolTypeScopeEnd;
4114 break;
4115
4116 case N_SOL:
4117 // #included file name: name,,n_sect,0,address
4118 type = eSymbolTypeHeaderFile;
4119
4120 // We currently don't use the header files on darwin
4121 add_nlist = false;
4122 break;
4123
4124 case N_PARAMS:
4125 // compiler parameters: name,,NO_SECT,0,0
4126 type = eSymbolTypeCompiler;
4127 break;
4128
4129 case N_VERSION:
4130 // compiler version: name,,NO_SECT,0,0
4131 type = eSymbolTypeCompiler;
4132 break;
4133
4134 case N_OLEVEL:
4135 // compiler -O level: name,,NO_SECT,0,0
4136 type = eSymbolTypeCompiler;
4137 break;
4138
4139 case N_PSYM:
4140 // parameter: name,,NO_SECT,type,offset
4141 type = eSymbolTypeVariable;
4142 break;
4143
4144 case N_ENTRY:
4145 // alternate entry: name,,n_sect,linenumber,address
4146 symbol_section =
4147 section_info.GetSection(nlist.n_sect, nlist.n_value);
4148 type = eSymbolTypeLineEntry;
4149 break;
4150
4151 //----------------------------------------------------------------------
4152 // Left and Right Braces
4153 //----------------------------------------------------------------------
4154 case N_LBRAC:
4155 // left bracket: 0,,NO_SECT,nesting level,address
4156 // We use the current number of symbols in the symbol table in lieu
4157 // of
4158 // using nlist_idx in case we ever start trimming entries out
4159 symbol_section =
4160 section_info.GetSection(nlist.n_sect, nlist.n_value);
4161 N_BRAC_indexes.push_back(sym_idx);
4162 type = eSymbolTypeScopeBegin;
4163 break;
4164
4165 case N_RBRAC:
4166 // right bracket: 0,,NO_SECT,nesting level,address
4167 // Set the size of the N_LBRAC to the terminating index of this
4168 // N_RBRAC
4169 // so that we can always skip the entire symbol if we need to
4170 // navigate
4171 // more quickly at the source level when parsing STABS
4172 symbol_section =
4173 section_info.GetSection(nlist.n_sect, nlist.n_value);
4174 if (!N_BRAC_indexes.empty()) {
4175 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
4176 symbol_ptr->SetByteSize(sym_idx + 1);
4177 symbol_ptr->SetSizeIsSibling(true);
4178 N_BRAC_indexes.pop_back();
4179 }
4180 type = eSymbolTypeScopeEnd;
4181 break;
4182
4183 case N_EXCL:
4184 // deleted include file: name,,NO_SECT,0,sum
4185 type = eSymbolTypeHeaderFile;
4186 break;
4187
4188 //----------------------------------------------------------------------
4189 // COMM scopes
4190 //----------------------------------------------------------------------
4191 case N_BCOMM:
4192 // begin common: name,,NO_SECT,0,0
4193 // We use the current number of symbols in the symbol table in lieu
4194 // of
4195 // using nlist_idx in case we ever start trimming entries out
4196 type = eSymbolTypeScopeBegin;
4197 N_COMM_indexes.push_back(sym_idx);
4198 break;
4199
4200 case N_ECOML:
4201 // end common (local name): 0,,n_sect,0,address
4202 symbol_section =
4203 section_info.GetSection(nlist.n_sect, nlist.n_value);
4204 LLVM_FALLTHROUGH[[clang::fallthrough]];
4205
4206 case N_ECOMM:
4207 // end common: name,,n_sect,0,0
4208 // Set the size of the N_BCOMM to the terminating index of this
4209 // N_ECOMM/N_ECOML
4210 // so that we can always skip the entire symbol if we need to
4211 // navigate
4212 // more quickly at the source level when parsing STABS
4213 if (!N_COMM_indexes.empty()) {
4214 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
4215 symbol_ptr->SetByteSize(sym_idx + 1);
4216 symbol_ptr->SetSizeIsSibling(true);
4217 N_COMM_indexes.pop_back();
4218 }
4219 type = eSymbolTypeScopeEnd;
4220 break;
4221
4222 case N_LENG:
4223 // second stab entry with length information
4224 type = eSymbolTypeAdditional;
4225 break;
4226
4227 default:
4228 break;
4229 }
4230 } else {
4231 // uint8_t n_pext = N_PEXT & nlist.n_type;
4232 uint8_t n_type = N_TYPE & nlist.n_type;
4233 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
54
Assuming the condition is false
4234
4235 switch (n_type) {
55
Control jumps to 'case N_INDR:' at line 4236
4236 case N_INDR: {
4237 const char *reexport_name_cstr =
4238 strtab_data.PeekCStr(nlist.n_value);
4239 if (reexport_name_cstr && reexport_name_cstr[0]) {
56
Assuming 'reexport_name_cstr' is non-null
57
Assuming the condition is true
58
Taking true branch
4240 type = eSymbolTypeReExported;
4241 ConstString reexport_name(
4242 reexport_name_cstr +
4243 ((reexport_name_cstr[0] == '_') ? 1 : 0));
59
Assuming the condition is false
60
'?' condition is false
4244 sym[sym_idx].SetReExportedSymbolName(reexport_name);
4245 set_value = false;
4246 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4247 indirect_symbol_names.insert(
4248 ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
61
Array access (from variable 'symbol_name') results in a null pointer dereference
4249 } else
4250 type = eSymbolTypeUndefined;
4251 } break;
4252
4253 case N_UNDF:
4254 if (symbol_name && symbol_name[0]) {
4255 ConstString undefined_name(symbol_name +
4256 ((symbol_name[0] == '_') ? 1 : 0));
4257 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4258 }
4259 LLVM_FALLTHROUGH[[clang::fallthrough]];
4260
4261 case N_PBUD:
4262 type = eSymbolTypeUndefined;
4263 break;
4264
4265 case N_ABS:
4266 type = eSymbolTypeAbsolute;
4267 break;
4268
4269 case N_SECT: {
4270 symbol_section =
4271 section_info.GetSection(nlist.n_sect, nlist.n_value);
4272
4273 if (!symbol_section) {
4274 // TODO: warn about this?
4275 add_nlist = false;
4276 break;
4277 }
4278
4279 if (TEXT_eh_frame_sectID == nlist.n_sect) {
4280 type = eSymbolTypeException;
4281 } else {
4282 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
4283
4284 switch (section_type) {
4285 case S_CSTRING_LITERALS:
4286 type = eSymbolTypeData;
4287 break; // section with only literal C strings
4288 case S_4BYTE_LITERALS:
4289 type = eSymbolTypeData;
4290 break; // section with only 4 byte literals
4291 case S_8BYTE_LITERALS:
4292 type = eSymbolTypeData;
4293 break; // section with only 8 byte literals
4294 case S_LITERAL_POINTERS:
4295 type = eSymbolTypeTrampoline;
4296 break; // section with only pointers to literals
4297 case S_NON_LAZY_SYMBOL_POINTERS:
4298 type = eSymbolTypeTrampoline;
4299 break; // section with only non-lazy symbol pointers
4300 case S_LAZY_SYMBOL_POINTERS:
4301 type = eSymbolTypeTrampoline;
4302 break; // section with only lazy symbol pointers
4303 case S_SYMBOL_STUBS:
4304 type = eSymbolTypeTrampoline;
4305 break; // section with only symbol stubs, byte size of stub in
4306 // the reserved2 field
4307 case S_MOD_INIT_FUNC_POINTERS:
4308 type = eSymbolTypeCode;
4309 break; // section with only function pointers for initialization
4310 case S_MOD_TERM_FUNC_POINTERS:
4311 type = eSymbolTypeCode;
4312 break; // section with only function pointers for termination
4313 case S_INTERPOSING:
4314 type = eSymbolTypeTrampoline;
4315 break; // section with only pairs of function pointers for
4316 // interposing
4317 case S_16BYTE_LITERALS:
4318 type = eSymbolTypeData;
4319 break; // section with only 16 byte literals
4320 case S_DTRACE_DOF:
4321 type = eSymbolTypeInstrumentation;
4322 break;
4323 case S_LAZY_DYLIB_SYMBOL_POINTERS:
4324 type = eSymbolTypeTrampoline;
4325 break;
4326 default:
4327 switch (symbol_section->GetType()) {
4328 case lldb::eSectionTypeCode:
4329 type = eSymbolTypeCode;
4330 break;
4331 case eSectionTypeData:
4332 case eSectionTypeDataCString: // Inlined C string data
4333 case eSectionTypeDataCStringPointers: // Pointers to C string
4334 // data
4335 case eSectionTypeDataSymbolAddress: // Address of a symbol in
4336 // the symbol table
4337 case eSectionTypeData4:
4338 case eSectionTypeData8:
4339 case eSectionTypeData16:
4340 type = eSymbolTypeData;
4341 break;
4342 default:
4343 break;
4344 }
4345 break;
4346 }
4347
4348 if (type == eSymbolTypeInvalid) {
4349 const char *symbol_sect_name =
4350 symbol_section->GetName().AsCString();
4351 if (symbol_section->IsDescendant(text_section_sp.get())) {
4352 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4353 S_ATTR_SELF_MODIFYING_CODE |
4354 S_ATTR_SOME_INSTRUCTIONS))
4355 type = eSymbolTypeData;
4356 else
4357 type = eSymbolTypeCode;
4358 } else if (symbol_section->IsDescendant(
4359 data_section_sp.get()) ||
4360 symbol_section->IsDescendant(
4361 data_dirty_section_sp.get()) ||
4362 symbol_section->IsDescendant(
4363 data_const_section_sp.get())) {
4364 if (symbol_sect_name &&
4365 ::strstr(symbol_sect_name, "__objc") ==
4366 symbol_sect_name) {
4367 type = eSymbolTypeRuntime;
4368
4369 if (symbol_name) {
4370 llvm::StringRef symbol_name_ref(symbol_name);
4371 if (symbol_name_ref.startswith("_OBJC_")) {
4372 static const llvm::StringRef g_objc_v2_prefix_class(
4373 "_OBJC_CLASS_$_");
4374 static const llvm::StringRef g_objc_v2_prefix_metaclass(
4375 "_OBJC_METACLASS_$_");
4376 static const llvm::StringRef g_objc_v2_prefix_ivar(
4377 "_OBJC_IVAR_$_");
4378 if (symbol_name_ref.startswith(
4379 g_objc_v2_prefix_class)) {
4380 symbol_name_non_abi_mangled = symbol_name + 1;
4381 symbol_name =
4382 symbol_name + g_objc_v2_prefix_class.size();
4383 type = eSymbolTypeObjCClass;
4384 demangled_is_synthesized = true;
4385 } else if (symbol_name_ref.startswith(
4386 g_objc_v2_prefix_metaclass)) {
4387 symbol_name_non_abi_mangled = symbol_name + 1;
4388 symbol_name =
4389 symbol_name + g_objc_v2_prefix_metaclass.size();
4390 type = eSymbolTypeObjCMetaClass;
4391 demangled_is_synthesized = true;
4392 } else if (symbol_name_ref.startswith(
4393 g_objc_v2_prefix_ivar)) {
4394 symbol_name_non_abi_mangled = symbol_name + 1;
4395 symbol_name =
4396 symbol_name + g_objc_v2_prefix_ivar.size();
4397 type = eSymbolTypeObjCIVar;
4398 demangled_is_synthesized = true;
4399 }
4400 }
4401 }
4402 } else if (symbol_sect_name &&
4403 ::strstr(symbol_sect_name, "__gcc_except_tab") ==
4404 symbol_sect_name) {
4405 type = eSymbolTypeException;
4406 } else {
4407 type = eSymbolTypeData;
4408 }
4409 } else if (symbol_sect_name &&
4410 ::strstr(symbol_sect_name, "__IMPORT") ==
4411 symbol_sect_name) {
4412 type = eSymbolTypeTrampoline;
4413 } else if (symbol_section->IsDescendant(
4414 objc_section_sp.get())) {
4415 type = eSymbolTypeRuntime;
4416 if (symbol_name && symbol_name[0] == '.') {
4417 llvm::StringRef symbol_name_ref(symbol_name);
4418 static const llvm::StringRef g_objc_v1_prefix_class(
4419 ".objc_class_name_");
4420 if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) {
4421 symbol_name_non_abi_mangled = symbol_name;
4422 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4423 type = eSymbolTypeObjCClass;
4424 demangled_is_synthesized = true;
4425 }
4426 }
4427 }
4428 }
4429 }
4430 } break;
4431 }
4432 }
4433
4434 if (add_nlist) {
4435 uint64_t symbol_value = nlist.n_value;
4436
4437 if (symbol_name_non_abi_mangled) {
4438 sym[sym_idx].GetMangled().SetMangledName(
4439 ConstString(symbol_name_non_abi_mangled));
4440 sym[sym_idx].GetMangled().SetDemangledName(
4441 ConstString(symbol_name));
4442 } else {
4443 bool symbol_name_is_mangled = false;
4444
4445 if (symbol_name && symbol_name[0] == '_') {
4446 symbol_name_is_mangled = symbol_name[1] == '_';
4447 symbol_name++; // Skip the leading underscore
4448 }
4449
4450 if (symbol_name) {
4451 ConstString const_symbol_name(symbol_name);
4452 sym[sym_idx].GetMangled().SetValue(const_symbol_name,
4453 symbol_name_is_mangled);
4454 }
4455 }
4456
4457 if (is_gsym) {
4458 const char *gsym_name = sym[sym_idx]
4459 .GetMangled()
4460 .GetName(lldb::eLanguageTypeUnknown,
4461 Mangled::ePreferMangled)
4462 .GetCString();
4463 if (gsym_name)
4464 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4465 }
4466
4467 if (symbol_section) {
4468 const addr_t section_file_addr = symbol_section->GetFileAddress();
4469 if (symbol_byte_size == 0 && function_starts_count > 0) {
4470 addr_t symbol_lookup_file_addr = nlist.n_value;
4471 // Do an exact address match for non-ARM addresses, else get the
4472 // closest since
4473 // the symbol might be a thumb symbol which has an address with
4474 // bit zero set
4475 FunctionStarts::Entry *func_start_entry =
4476 function_starts.FindEntry(symbol_lookup_file_addr, !is_arm);
4477 if (is_arm && func_start_entry) {
4478 // Verify that the function start address is the symbol address
4479 // (ARM)
4480 // or the symbol address + 1 (thumb)
4481 if (func_start_entry->addr != symbol_lookup_file_addr &&
4482 func_start_entry->addr != (symbol_lookup_file_addr + 1)) {
4483 // Not the right entry, NULL it out...
4484 func_start_entry = NULL__null;
4485 }
4486 }
4487 if (func_start_entry) {
4488 func_start_entry->data = true;
4489
4490 addr_t symbol_file_addr = func_start_entry->addr;
4491 if (is_arm)
4492 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK0xfffffffffffffffeull;
4493
4494 const FunctionStarts::Entry *next_func_start_entry =
4495 function_starts.FindNextEntry(func_start_entry);
4496 const addr_t section_end_file_addr =
4497 section_file_addr + symbol_section->GetByteSize();
4498 if (next_func_start_entry) {
4499 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4500 // Be sure the clear the Thumb address bit when we calculate
4501 // the size
4502 // from the current and next address
4503 if (is_arm)
4504 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK0xfffffffffffffffeull;
4505 symbol_byte_size = std::min<lldb::addr_t>(
4506 next_symbol_file_addr - symbol_file_addr,
4507 section_end_file_addr - symbol_file_addr);
4508 } else {
4509 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4510 }
4511 }
4512 }
4513 symbol_value -= section_file_addr;
4514 }
4515
4516 if (is_debug == false) {
4517 if (type == eSymbolTypeCode) {
4518 // See if we can find a N_FUN entry for any code symbols.
4519 // If we do find a match, and the name matches, then we
4520 // can merge the two into just the function symbol to avoid
4521 // duplicate entries in the symbol table
4522 std::pair<ValueToSymbolIndexMap::const_iterator,
4523 ValueToSymbolIndexMap::const_iterator>
4524 range;
4525 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4526 if (range.first != range.second) {
4527 bool found_it = false;
4528 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4529 pos != range.second; ++pos) {
4530 if (sym[sym_idx].GetMangled().GetName(
4531 lldb::eLanguageTypeUnknown,
4532 Mangled::ePreferMangled) ==
4533 sym[pos->second].GetMangled().GetName(
4534 lldb::eLanguageTypeUnknown,
4535 Mangled::ePreferMangled)) {
4536 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4537 // We just need the flags from the linker symbol, so put
4538 // these flags
4539 // into the N_FUN flags to avoid duplicate symbols in the
4540 // symbol table
4541 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4542 sym[pos->second].SetFlags(nlist.n_type << 16 |
4543 nlist.n_desc);
4544 if (resolver_addresses.find(nlist.n_value) !=
4545 resolver_addresses.end())
4546 sym[pos->second].SetType(eSymbolTypeResolver);
4547 sym[sym_idx].Clear();
4548 found_it = true;
4549 break;
4550 }
4551 }
4552 if (found_it)
4553 continue;
4554 } else {
4555 if (resolver_addresses.find(nlist.n_value) !=
4556 resolver_addresses.end())
4557 type = eSymbolTypeResolver;
4558 }
4559 } else if (type == eSymbolTypeData ||
4560 type == eSymbolTypeObjCClass ||
4561 type == eSymbolTypeObjCMetaClass ||
4562 type == eSymbolTypeObjCIVar) {
4563 // See if we can find a N_STSYM entry for any data symbols.
4564 // If we do find a match, and the name matches, then we
4565 // can merge the two into just the Static symbol to avoid
4566 // duplicate entries in the symbol table
4567 std::pair<ValueToSymbolIndexMap::const_iterator,
4568 ValueToSymbolIndexMap::const_iterator>
4569 range;
4570 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4571 if (range.first != range.second) {
4572 bool found_it = false;
4573 for (ValueToSymbolIndexMap::const_iterator pos = range.first;
4574 pos != range.second; ++pos) {
4575 if (sym[sym_idx].GetMangled().GetName(
4576 lldb::eLanguageTypeUnknown,
4577 Mangled::ePreferMangled) ==
4578 sym[pos->second].GetMangled().GetName(
4579 lldb::eLanguageTypeUnknown,
4580 Mangled::ePreferMangled)) {
4581 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4582 // We just need the flags from the linker symbol, so put
4583 // these flags
4584 // into the N_STSYM flags to avoid duplicate symbols in the
4585 // symbol table
4586 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4587 sym[pos->second].SetFlags(nlist.n_type << 16 |
4588 nlist.n_desc);
4589 sym[sym_idx].Clear();
4590 found_it = true;
4591 break;
4592 }
4593 }
4594 if (found_it)
4595 continue;
4596 } else {
4597 // Combine N_GSYM stab entries with the non stab symbol
4598 const char *gsym_name = sym[sym_idx]
4599 .GetMangled()
4600 .GetName(lldb::eLanguageTypeUnknown,
4601 Mangled::ePreferMangled)
4602 .GetCString();
4603 if (gsym_name) {
4604 ConstNameToSymbolIndexMap::const_iterator pos =
4605 N_GSYM_name_to_sym_idx.find(gsym_name);
4606 if (pos != N_GSYM_name_to_sym_idx.end()) {
4607 const uint32_t GSYM_sym_idx = pos->second;
4608 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4609 // Copy the address, because often the N_GSYM address has an
4610 // invalid address of zero
4611 // when the global is a common symbol
4612 sym[GSYM_sym_idx].GetAddressRef().SetSection(
4613 symbol_section);
4614 sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value);
4615 // We just need the flags from the linker symbol, so put
4616 // these flags
4617 // into the N_GSYM flags to avoid duplicate symbols in the
4618 // symbol table
4619 sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 |
4620 nlist.n_desc);
4621 sym[sym_idx].Clear();
4622 continue;
4623 }
4624 }
4625 }
4626 }
4627 }
4628
4629 sym[sym_idx].SetID(nlist_idx);
4630 sym[sym_idx].SetType(type);
4631 if (set_value) {
4632 sym[sym_idx].GetAddressRef().SetSection(symbol_section);
4633 sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
4634 }
4635 sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
4636
4637 if (symbol_byte_size > 0)
4638 sym[sym_idx].SetByteSize(symbol_byte_size);
4639
4640 if (demangled_is_synthesized)
4641 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4642
4643 ++sym_idx;
4644 } else {
4645 sym[sym_idx].Clear();
4646 }
4647 }
4648
4649 for (const auto &pos : reexport_shlib_needs_fixup) {
4650 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4651 if (undef_pos != undefined_name_to_desc.end()) {
4652 const uint8_t dylib_ordinal =
4653 llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4654 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4655 sym[pos.first].SetReExportedSymbolSharedLibrary(
4656 dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
4657 }
4658 }
4659 }
4660
4661 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4662
4663 if (function_starts_count > 0) {
4664 uint32_t num_synthetic_function_symbols = 0;
4665 for (i = 0; i < function_starts_count; ++i) {
4666 if (function_starts.GetEntryRef(i).data == false)
4667 ++num_synthetic_function_symbols;
4668 }
4669
4670 if (num_synthetic_function_symbols > 0) {
4671 if (num_syms < sym_idx + num_synthetic_function_symbols) {
4672 num_syms = sym_idx + num_synthetic_function_symbols;
4673 sym = symtab->Resize(num_syms);
4674 }
4675 for (i = 0; i < function_starts_count; ++i) {
4676 const FunctionStarts::Entry *func_start_entry =
4677 function_starts.GetEntryAtIndex(i);
4678 if (func_start_entry->data == false) {
4679 addr_t symbol_file_addr = func_start_entry->addr;
4680 uint32_t symbol_flags = 0;
4681 if (is_arm) {
4682 if (symbol_file_addr & 1)
4683 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB0x0008;
4684 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK0xfffffffffffffffeull;
4685 }
4686 Address symbol_addr;
4687 if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
4688 SectionSP symbol_section(symbol_addr.GetSection());
4689 uint32_t symbol_byte_size = 0;
4690 if (symbol_section) {
4691 const addr_t section_file_addr =
4692 symbol_section->GetFileAddress();
4693 const FunctionStarts::Entry *next_func_start_entry =
4694 function_starts.FindNextEntry(func_start_entry);
4695 const addr_t section_end_file_addr =
4696 section_file_addr + symbol_section->GetByteSize();
4697 if (next_func_start_entry) {
4698 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4699 if (is_arm)
4700 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK0xfffffffffffffffeull;
4701 symbol_byte_size = std::min<lldb::addr_t>(
4702 next_symbol_file_addr - symbol_file_addr,
4703 section_end_file_addr - symbol_file_addr);
4704 } else {
4705 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4706 }
4707 sym[sym_idx].SetID(synthetic_sym_id++);
4708 sym[sym_idx].GetMangled().SetDemangledName(
4709 GetNextSyntheticSymbolName());
4710 sym[sym_idx].SetType(eSymbolTypeCode);
4711 sym[sym_idx].SetIsSynthetic(true);
4712 sym[sym_idx].GetAddressRef() = symbol_addr;
4713 if (symbol_flags)
4714 sym[sym_idx].SetFlags(symbol_flags);
4715 if (symbol_byte_size)
4716 sym[sym_idx].SetByteSize(symbol_byte_size);
4717 ++sym_idx;
4718 }
4719 }
4720 }
4721 }
4722 }
4723 }
4724
4725 // Trim our symbols down to just what we ended up with after
4726 // removing any symbols.
4727 if (sym_idx < num_syms) {
4728 num_syms = sym_idx;
4729 sym = symtab->Resize(num_syms);
4730 }
4731
4732 // Now synthesize indirect symbols
4733 if (m_dysymtab.nindirectsyms != 0) {
4734 if (indirect_symbol_index_data.GetByteSize()) {
4735 NListIndexToSymbolIndexMap::const_iterator end_index_pos =
4736 m_nlist_idx_to_sym_idx.end();
4737
4738 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size();
4739 ++sect_idx) {
4740 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) ==
4741 S_SYMBOL_STUBS) {
4742 uint32_t symbol_stub_byte_size =
4743 m_mach_sections[sect_idx].reserved2;
4744 if (symbol_stub_byte_size == 0)
4745 continue;
4746
4747 const uint32_t num_symbol_stubs =
4748 m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4749
4750 if (num_symbol_stubs == 0)
4751 continue;
4752
4753 const uint32_t symbol_stub_index_offset =
4754 m_mach_sections[sect_idx].reserved1;
4755 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs;
4756 ++stub_idx) {
4757 const uint32_t symbol_stub_index =
4758 symbol_stub_index_offset + stub_idx;
4759 const lldb::addr_t symbol_stub_addr =
4760 m_mach_sections[sect_idx].addr +
4761 (stub_idx * symbol_stub_byte_size);
4762 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
4763 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
4764 symbol_stub_offset, 4)) {
4765 const uint32_t stub_sym_id =
4766 indirect_symbol_index_data.GetU32(&symbol_stub_offset);
4767 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
4768 continue;
4769
4770 NListIndexToSymbolIndexMap::const_iterator index_pos =
4771 m_nlist_idx_to_sym_idx.find(stub_sym_id);
4772 Symbol *stub_symbol = NULL__null;
4773 if (index_pos != end_index_pos) {
4774 // We have a remapping from the original nlist index to
4775 // a current symbol index, so just look this up by index
4776 stub_symbol = symtab->SymbolAtIndex(index_pos->second);
4777 } else {
4778 // We need to lookup a symbol using the original nlist
4779 // symbol index since this index is coming from the
4780 // S_SYMBOL_STUBS
4781 stub_symbol = symtab->FindSymbolByID(stub_sym_id);
4782 }
4783
4784 if (stub_symbol) {
4785 Address so_addr(symbol_stub_addr, section_list);
4786
4787 if (stub_symbol->GetType() == eSymbolTypeUndefined) {
4788 // Change the external symbol into a trampoline that makes
4789 // sense
4790 // These symbols were N_UNDF N_EXT, and are useless to us,
4791 // so we
4792 // can re-use them so we don't have to make up a synthetic
4793 // symbol
4794 // for no good reason.
4795 if (resolver_addresses.find(symbol_stub_addr) ==
4796 resolver_addresses.end())
4797 stub_symbol->SetType(eSymbolTypeTrampoline);
4798 else
4799 stub_symbol->SetType(eSymbolTypeResolver);
4800 stub_symbol->SetExternal(false);
4801 stub_symbol->GetAddressRef() = so_addr;
4802 stub_symbol->SetByteSize(symbol_stub_byte_size);
4803 } else {
4804 // Make a synthetic symbol to describe the trampoline stub
4805 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
4806 if (sym_idx >= num_syms) {
4807 sym = symtab->Resize(++num_syms);
4808 stub_symbol = NULL__null; // this pointer no longer valid
4809 }
4810 sym[sym_idx].SetID(synthetic_sym_id++);
4811 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
4812 if (resolver_addresses.find(symbol_stub_addr) ==
4813 resolver_addresses.end())
4814 sym[sym_idx].SetType(eSymbolTypeTrampoline);
4815 else
4816 sym[sym_idx].SetType(eSymbolTypeResolver);
4817 sym[sym_idx].SetIsSynthetic(true);
4818 sym[sym_idx].GetAddressRef() = so_addr;
4819 sym[sym_idx].SetByteSize(symbol_stub_byte_size);
4820 ++sym_idx;
4821 }
4822 } else {
4823 if (log)
4824 log->Warning("symbol stub referencing symbol table symbol "
4825 "%u that isn't in our minimal symbol table, "
4826 "fix this!!!",
4827 stub_sym_id);
4828 }
4829 }
4830 }
4831 }
4832 }
4833 }
4834 }
4835
4836 if (!trie_entries.empty()) {
4837 for (const auto &e : trie_entries) {
4838 if (e.entry.import_name) {
4839 // Only add indirect symbols from the Trie entries if we
4840 // didn't have a N_INDR nlist entry for this already
4841 if (indirect_symbol_names.find(e.entry.name) ==
4842 indirect_symbol_names.end()) {
4843 // Make a synthetic symbol to describe re-exported symbol.
4844 if (sym_idx >= num_syms)
4845 sym = symtab->Resize(++num_syms);
4846 sym[sym_idx].SetID(synthetic_sym_id++);
4847 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4848 sym[sym_idx].SetType(eSymbolTypeReExported);
4849 sym[sym_idx].SetIsSynthetic(true);
4850 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4851 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
4852 sym[sym_idx].SetReExportedSymbolSharedLibrary(
4853 dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
4854 }
4855 ++sym_idx;
4856 }
4857 }
4858 }
4859 }
4860
4861 // StreamFile s(stdout, false);
4862 // s.Printf ("Symbol table before CalculateSymbolSizes():\n");
4863 // symtab->Dump(&s, NULL, eSortOrderNone);
4864 // Set symbol byte sizes correctly since mach-o nlist entries don't have
4865 // sizes
4866 symtab->CalculateSymbolSizes();
4867
4868 // s.Printf ("Symbol table after CalculateSymbolSizes():\n");
4869 // symtab->Dump(&s, NULL, eSortOrderNone);
4870
4871 return symtab->GetNumSymbols();
4872 }
4873 return 0;
4874}
4875
4876void ObjectFileMachO::Dump(Stream *s) {
4877 ModuleSP module_sp(GetModule());
4878 if (module_sp) {
4879 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
4880 s->Printf("%p: ", static_cast<void *>(this));
4881 s->Indent();
4882 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
4883 s->PutCString("ObjectFileMachO64");
4884 else
4885 s->PutCString("ObjectFileMachO32");
4886
4887 ArchSpec header_arch;
4888 GetArchitecture(header_arch);
4889
4890 *s << ", file = '" << m_file
4891 << "', arch = " << header_arch.GetArchitectureName() << "\n";
4892
4893 SectionList *sections = GetSectionList();
4894 if (sections)
4895 sections->Dump(s, NULL__null, true, UINT32_MAX(4294967295U));
4896
4897 if (m_symtab_ap.get())
4898 m_symtab_ap->Dump(s, NULL__null, eSortOrderNone);
4899 }
4900}
4901
4902bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
4903 const lldb_private::DataExtractor &data,
4904 lldb::offset_t lc_offset,
4905 lldb_private::UUID &uuid) {
4906 uint32_t i;
4907 struct uuid_command load_cmd;
4908
4909 lldb::offset_t offset = lc_offset;
4910 for (i = 0; i < header.ncmds; ++i) {
4911 const lldb::offset_t cmd_offset = offset;
4912 if (data.GetU32(&offset, &load_cmd, 2) == NULL__null)
4913 break;
4914
4915 if (load_cmd.cmd == LC_UUID) {
4916 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4917
4918 if (uuid_bytes) {
4919 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4920 // We pretend these object files have no UUID to prevent crashing.
4921
4922 const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8,
4923 0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63,
4924 0xbb, 0x14, 0xf0, 0x0d};
4925
4926 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4927 return false;
4928
4929 uuid.SetBytes(uuid_bytes);
4930 return true;
4931 }
4932 return false;
4933 }
4934 offset = cmd_offset + load_cmd.cmdsize;
4935 }
4936 return false;
4937}
4938
4939bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
4940 const lldb_private::DataExtractor &data,
4941 lldb::offset_t lc_offset,
4942 ArchSpec &arch) {
4943 arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);
4944
4945 if (arch.IsValid()) {
4946 llvm::Triple &triple = arch.GetTriple();
4947
4948 // Set OS to an unspecified unknown or a "*" so it can match any OS
4949 triple.setOS(llvm::Triple::UnknownOS);
4950 triple.setOSName(llvm::StringRef());
4951
4952 if (header.filetype == MH_PRELOAD) {
4953 if (header.cputype == CPU_TYPE_ARM) {
4954 // If this is a 32-bit arm binary, and it's a standalone binary,
4955 // force the Vendor to Apple so we don't accidentally pick up
4956 // the generic armv7 ABI at runtime. Apple's armv7 ABI always uses
4957 // r7 for the frame pointer register; most other armv7 ABIs use a
4958 // combination of r7 and r11.
4959 triple.setVendor(llvm::Triple::Apple);
4960 } else {
4961 // Set vendor to an unspecified unknown or a "*" so it can match any
4962 // vendor
4963 // This is required for correct behavior of EFI debugging on x86_64
4964 triple.setVendor(llvm::Triple::UnknownVendor);
4965 triple.setVendorName(llvm::StringRef());
4966 }
4967 return true;
4968 } else {
4969 struct load_command load_cmd;
4970
4971 lldb::offset_t offset = lc_offset;
4972 for (uint32_t i = 0; i < header.ncmds; ++i) {
4973 const lldb::offset_t cmd_offset = offset;
4974 if (data.GetU32(&offset, &load_cmd, 2) == NULL__null)
4975 break;
4976
4977 switch (load_cmd.cmd) {
4978 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
4979 triple.setOS(llvm::Triple::IOS);
4980 return true;
4981
4982 case llvm::MachO::LC_VERSION_MIN_MACOSX:
4983 triple.setOS(llvm::Triple::MacOSX);
4984 return true;
4985
4986 case llvm::MachO::LC_VERSION_MIN_TVOS:
4987 triple.setOS(llvm::Triple::TvOS);
4988 return true;
4989
4990 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4991 triple.setOS(llvm::Triple::WatchOS);
4992 return true;
4993
4994 default:
4995 break;
4996 }
4997
4998 offset = cmd_offset + load_cmd.cmdsize;
4999 }
5000
5001 if (header.filetype != MH_KEXT_BUNDLE) {
5002 // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT
5003 // so lets not say our Vendor is Apple, leave it as an unspecified
5004 // unknown
5005 triple.setVendor(llvm::Triple::UnknownVendor);
5006 triple.setVendorName(llvm::StringRef());
5007 }
5008 }
5009 }
5010 return arch.IsValid();
5011}
5012
5013bool ObjectFileMachO::GetUUID(lldb_private::UUID *uuid) {
5014 ModuleSP module_sp(GetModule());
5015 if (module_sp) {
5016 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5017 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5018 return GetUUID(m_header, m_data, offset, *uuid);
5019 }
5020 return false;
5021}
5022
5023uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
5024 uint32_t count = 0;
5025 ModuleSP module_sp(GetModule());
5026 if (module_sp) {
5027 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5028 struct load_command load_cmd;
5029 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5030 std::vector<std::string> rpath_paths;
5031 std::vector<std::string> rpath_relative_paths;
5032 std::vector<std::string> at_exec_relative_paths;
5033 const bool resolve_path = false; // Don't resolve the dependent file paths
5034 // since they may not reside on this system
5035 uint32_t i;
5036 for (i = 0; i < m_header.ncmds; ++i) {
5037 const uint32_t cmd_offset = offset;
5038 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL__null)
5039 break;
5040
5041 switch (load_cmd.cmd) {
5042 case LC_RPATH:
5043 case LC_LOAD_DYLIB:
5044 case LC_LOAD_WEAK_DYLIB:
5045 case LC_REEXPORT_DYLIB:
5046 case LC_LOAD_DYLINKER:
5047 case LC_LOADFVMLIB:
5048 case LC_LOAD_UPWARD_DYLIB: {
5049 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
5050 const char *path = m_data.PeekCStr(name_offset);
5051 if (path) {
5052 if (load_cmd.cmd == LC_RPATH)
5053 rpath_paths.push_back(path);
5054 else {
5055 if (path[0] == '@') {
5056 if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
5057 rpath_relative_paths.push_back(path + strlen("@rpath"));
5058 else if (strncmp(path, "@executable_path",
5059 strlen("@executable_path")) == 0)
5060 at_exec_relative_paths.push_back(path
5061 + strlen("@executable_path"));
5062 } else {
5063 FileSpec file_spec(path, resolve_path);
5064 if (files.AppendIfUnique(file_spec))
5065 count++;
5066 }
5067 }
5068 }
5069 } break;
5070
5071 default:
5072 break;
5073 }
5074 offset = cmd_offset + load_cmd.cmdsize;
5075 }
5076
5077 FileSpec this_file_spec(m_file);
5078 this_file_spec.ResolvePath();
5079
5080 if (!rpath_paths.empty()) {
5081 // Fixup all LC_RPATH values to be absolute paths
5082 std::string loader_path("@loader_path");
5083 std::string executable_path("@executable_path");
5084 for (auto &rpath : rpath_paths) {
5085 if (rpath.find(loader_path) == 0) {
5086 rpath.erase(0, loader_path.size());
5087 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
5088 } else if (rpath.find(executable_path) == 0) {
5089 rpath.erase(0, executable_path.size());
5090 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
5091 }
5092 }
5093
5094 for (const auto &rpath_relative_path : rpath_relative_paths) {
5095 for (const auto &rpath : rpath_paths) {
5096 std::string path = rpath;
5097 path += rpath_relative_path;
5098 // It is OK to resolve this path because we must find a file on
5099 // disk for us to accept it anyway if it is rpath relative.
5100 FileSpec file_spec(path, true);
5101 // Remove any redundant parts of the path (like "../foo") since
5102 // LC_RPATH values often contain "..".
5103 file_spec = file_spec.GetNormalizedPath();
5104 if (file_spec.Exists() && files.AppendIfUnique(file_spec)) {
5105 count++;
5106 break;
5107 }
5108 }
5109 }
5110 }
5111
5112 // We may have @executable_paths but no RPATHS. Figure those out here.
5113 // Only do this if this object file is the executable. We have no way to
5114 // get back to the actual executable otherwise, so we won't get the right
5115 // path.
5116 if (!at_exec_relative_paths.empty() && CalculateType() == eTypeExecutable) {
5117 FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent();
5118 for (const auto &at_exec_relative_path : at_exec_relative_paths) {
5119 FileSpec file_spec =
5120 exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
5121 file_spec = file_spec.GetNormalizedPath();
5122 if (file_spec.Exists() && files.AppendIfUnique(file_spec))
5123 count++;
5124 }
5125 }
5126 }
5127 return count;
5128}
5129
5130lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
5131 // If the object file is not an executable it can't hold the entry point.
5132 // m_entry_point_address
5133 // is initialized to an invalid address, so we can just return that.
5134 // If m_entry_point_address is valid it means we've found it already, so
5135 // return the cached value.
5136
5137 if (!IsExecutable() || m_entry_point_address.IsValid())
5138 return m_entry_point_address;
5139
5140 // Otherwise, look for the UnixThread or Thread command. The data for the
5141 // Thread command is given in
5142 // /usr/include/mach-o.h, but it is basically:
5143 //
5144 // uint32_t flavor - this is the flavor argument you would pass to
5145 // thread_get_state
5146 // uint32_t count - this is the count of longs in the thread state data
5147 // struct XXX_thread_state state - this is the structure from
5148 // <machine/thread_status.h> corresponding to the flavor.
5149 // <repeat this trio>
5150 //
5151 // So we just keep reading the various register flavors till we find the GPR
5152 // one, then read the PC out of there.
5153 // FIXME: We will need to have a "RegisterContext data provider" class at some
5154 // point that can get all the registers
5155 // out of data in this form & attach them to a given thread. That should
5156 // underlie the MacOS X User process plugin,
5157 // and we'll also need it for the MacOS X Core File process plugin. When we
5158 // have that we can also use it here.
5159 //
5160 // For now we hard-code the offsets and flavors we need:
5161 //
5162 //
5163
5164 ModuleSP module_sp(GetModule());
5165 if (module_sp) {
5166 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5167 struct load_command load_cmd;
5168 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5169 uint32_t i;
5170 lldb::addr_t start_address = LLDB_INVALID_ADDRESS(18446744073709551615UL);
5171 bool done = false;
5172
5173 for (i = 0; i < m_header.ncmds; ++i) {
5174 const lldb::offset_t cmd_offset = offset;
5175 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL__null)
5176 break;
5177
5178 switch (load_cmd.cmd) {
5179 case LC_UNIXTHREAD:
5180 case LC_THREAD: {
5181 while (offset < cmd_offset + load_cmd.cmdsize) {
5182 uint32_t flavor = m_data.GetU32(&offset);
5183 uint32_t count = m_data.GetU32(&offset);
5184 if (count == 0) {
5185 // We've gotten off somehow, log and exit;
5186 return m_entry_point_address;
5187 }
5188
5189 switch (m_header.cputype) {
5190 case llvm::MachO::CPU_TYPE_ARM:
5191 if (flavor == 1 ||
5192 flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from
5193 // mach/arm/thread_status.h
5194 {
5195 offset += 60; // This is the offset of pc in the GPR thread state
5196 // data structure.
5197 start_address = m_data.GetU32(&offset);
5198 done = true;
5199 }
5200 break;
5201 case llvm::MachO::CPU_TYPE_ARM64:
5202 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
5203 {
5204 offset += 256; // This is the offset of pc in the GPR thread state
5205 // data structure.
5206 start_address = m_data.GetU64(&offset);
5207 done = true;
5208 }
5209 break;
5210 case llvm::MachO::CPU_TYPE_I386:
5211 if (flavor ==
5212 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
5213 {
5214 offset += 40; // This is the offset of eip in the GPR thread state
5215 // data structure.
5216 start_address = m_data.GetU32(&offset);
5217 done = true;
5218 }
5219 break;
5220 case llvm::MachO::CPU_TYPE_X86_64:
5221 if (flavor ==
5222 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
5223 {
5224 offset += 16 * 8; // This is the offset of rip in the GPR thread
5225 // state data structure.
5226 start_address = m_data.GetU64(&offset);
5227 done = true;
5228 }
5229 break;
5230 default:
5231 return m_entry_point_address;
5232 }
5233 // Haven't found the GPR flavor yet, skip over the data for this
5234 // flavor:
5235 if (done)
5236 break;
5237 offset += count * 4;
5238 }
5239 } break;
5240 case LC_MAIN: {
5241 ConstString text_segment_name("__TEXT");
5242 uint64_t entryoffset = m_data.GetU64(&offset);
5243 SectionSP text_segment_sp =
5244 GetSectionList()->FindSectionByName(text_segment_name);
5245 if (text_segment_sp) {
5246 done = true;
5247 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5248 }
5249 } break;
5250
5251 default:
5252 break;
5253 }
5254 if (done)
5255 break;
5256
5257 // Go to the next load command:
5258 offset = cmd_offset + load_cmd.cmdsize;
5259 }
5260
5261 if (start_address != LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
5262 // We got the start address from the load commands, so now resolve that
5263 // address in the sections
5264 // of this ObjectFile:
5265 if (!m_entry_point_address.ResolveAddressUsingFileSections(
5266 start_address, GetSectionList())) {
5267 m_entry_point_address.Clear();
5268 }
5269 } else {
5270 // We couldn't read the UnixThread load command - maybe it wasn't there.
5271 // As a fallback look for the
5272 // "start" symbol in the main executable.
5273
5274 ModuleSP module_sp(GetModule());
5275
5276 if (module_sp) {
5277 SymbolContextList contexts;
5278 SymbolContext context;
5279 if (module_sp->FindSymbolsWithNameAndType(ConstString("start"),
5280 eSymbolTypeCode, contexts)) {
5281 if (contexts.GetContextAtIndex(0, context))
5282 m_entry_point_address = context.symbol->GetAddress();
5283 }
5284 }
5285 }
5286 }
5287
5288 return m_entry_point_address;
5289}
5290
5291lldb_private::Address ObjectFileMachO::GetHeaderAddress() {
5292 lldb_private::Address header_addr;
5293 SectionList *section_list = GetSectionList();
5294 if (section_list) {
5295 SectionSP text_segment_sp(
5296 section_list->FindSectionByName(GetSegmentNameTEXT()));
5297 if (text_segment_sp) {
5298 header_addr.SetSection(text_segment_sp);
5299 header_addr.SetOffset(0);
5300 }
5301 }
5302 return header_addr;
5303}
5304
5305uint32_t ObjectFileMachO::GetNumThreadContexts() {
5306 ModuleSP module_sp(GetModule());
5307 if (module_sp) {
5308 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5309 if (!m_thread_context_offsets_valid) {
5310 m_thread_context_offsets_valid = true;
5311 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5312 FileRangeArray::Entry file_range;
5313 thread_command thread_cmd;
5314 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5315 const uint32_t cmd_offset = offset;
5316 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL__null)
5317 break;
5318
5319 if (thread_cmd.cmd == LC_THREAD) {
5320 file_range.SetRangeBase(offset);
5321 file_range.SetByteSize(thread_cmd.cmdsize - 8);
5322 m_thread_context_offsets.Append(file_range);
5323 }
5324 offset = cmd_offset + thread_cmd.cmdsize;
5325 }
5326 }
5327 }
5328 return m_thread_context_offsets.GetSize();
5329}
5330
5331std::string ObjectFileMachO::GetIdentifierString() {
5332 std::string result;
5333 ModuleSP module_sp(GetModule());
5334 if (module_sp) {
5335 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5336
5337 // First, look over the load commands for an LC_NOTE load command
5338 // with data_owner string "kern ver str" & use that if found.
5339 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5340 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5341 const uint32_t cmd_offset = offset;
5342 load_command lc;
5343 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL__null)
5344 break;
5345 if (lc.cmd == LC_NOTE)
5346 {
5347 char data_owner[17];
5348 m_data.CopyData (offset, 16, data_owner);
5349 data_owner[16] = '\0';
5350 offset += 16;
5351 uint64_t fileoff = m_data.GetU64_unchecked (&offset);
5352 uint64_t size = m_data.GetU64_unchecked (&offset);
5353
5354 // "kern ver str" has a uint32_t version and then a
5355 // nul terminated c-string.
5356 if (strcmp ("kern ver str", data_owner) == 0)
5357 {
5358 offset = fileoff;
5359 uint32_t version;
5360 if (m_data.GetU32 (&offset, &version, 1) != nullptr)
5361 {
5362 if (version == 1)
5363 {
5364 uint32_t strsize = size - sizeof (uint32_t);
5365 char *buf = (char*) malloc (strsize);
5366 if (buf)
5367 {
5368 m_data.CopyData (offset, strsize, buf);
5369 buf[strsize - 1] = '\0';
5370 result = buf;
5371 if (buf)
5372 free (buf);
5373 return result;
5374 }
5375 }
5376 }
5377 }
5378 }
5379 offset = cmd_offset + lc.cmdsize;
5380 }
5381
5382 // Second, make a pass over the load commands looking for an
5383 // obsolete LC_IDENT load command.
5384 offset = MachHeaderSizeFromMagic(m_header.magic);
5385 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5386 const uint32_t cmd_offset = offset;
5387 struct ident_command ident_command;
5388 if (m_data.GetU32(&offset, &ident_command, 2) == NULL__null)
5389 break;
5390 if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
5391 char *buf = (char *) malloc (ident_command.cmdsize);
5392 if (buf != nullptr
5393 && m_data.CopyData (offset, ident_command.cmdsize, buf) == ident_command.cmdsize) {
5394 buf[ident_command.cmdsize - 1] = '\0';
5395 result = buf;
5396 }
5397 if (buf)
5398 free (buf);
5399 }
5400 offset = cmd_offset + ident_command.cmdsize;
5401 }
5402
5403 }
5404 return result;
5405}
5406
5407bool ObjectFileMachO::GetCorefileMainBinaryInfo (addr_t &address, UUID &uuid) {
5408 address = LLDB_INVALID_ADDRESS(18446744073709551615UL);
5409 uuid.Clear();
5410 ModuleSP module_sp(GetModule());
5411 if (module_sp) {
5412 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5413 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5414 for (uint32_t i = 0; i < m_header.ncmds; ++i) {
5415 const uint32_t cmd_offset = offset;
5416 load_command lc;
5417 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL__null)
5418 break;
5419 if (lc.cmd == LC_NOTE)
5420 {
5421 char data_owner[17];
5422 memset (data_owner, 0, sizeof (data_owner));
5423 m_data.CopyData (offset, 16, data_owner);
5424 offset += 16;
5425 uint64_t fileoff = m_data.GetU64_unchecked (&offset);
5426 uint64_t size = m_data.GetU64_unchecked (&offset);
5427
5428 // "main bin spec" (main binary specification) data payload is formatted:
5429 // uint32_t version [currently 1]
5430 // uint32_t type [0 == unspecified, 1 == kernel, 2 == user process]
5431 // uint64_t address [ UINT64_MAX if address not specified ]
5432 // uuid_t uuid [ all zero's if uuid not specified ]
5433 // uint32_t log2_pagesize [ process page size in log base 2, e.g. 4k pages are 12. 0 for unspecified ]
5434
5435 if (strcmp ("main bin spec", data_owner) == 0 && size >= 32)
5436 {
5437 offset = fileoff;
5438 uint32_t version;
5439 if (m_data.GetU32 (&offset, &version, 1) != nullptr && version == 1)
5440 {
5441 uint32_t type = 0;
5442 uuid_t raw_uuid;
5443 memset (raw_uuid, 0, sizeof (uuid_t));
5444
5445 if (m_data.GetU32 (&offset, &type, 1)
5446 && m_data.GetU64 (&offset, &address, 1)
5447 && m_data.CopyData (offset, sizeof (uuid_t), raw_uuid) != 0
5448 && uuid.SetBytes (raw_uuid, sizeof (uuid_t)))
5449 {
5450 return true;
5451 }
5452 }
5453 }
5454 }
5455 offset = cmd_offset + lc.cmdsize;
5456 }
5457 }
5458 return false;
5459}
5460
5461lldb::RegisterContextSP
5462ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,
5463 lldb_private::Thread &thread) {
5464 lldb::RegisterContextSP reg_ctx_sp;
5465
5466 ModuleSP module_sp(GetModule());
5467 if (module_sp) {
5468 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5469 if (!m_thread_context_offsets_valid)
5470 GetNumThreadContexts();
5471
5472 const FileRangeArray::Entry *thread_context_file_range =
5473 m_thread_context_offsets.GetEntryAtIndex(idx);
5474 if (thread_context_file_range) {
5475
5476 DataExtractor data(m_data, thread_context_file_range->GetRangeBase(),
5477 thread_context_file_range->GetByteSize());
5478
5479 switch (m_header.cputype) {
5480 case llvm::MachO::CPU_TYPE_ARM64:
5481 reg_ctx_sp.reset(new RegisterContextDarwin_arm64_Mach(thread, data));
5482 break;
5483
5484 case llvm::MachO::CPU_TYPE_ARM:
5485 reg_ctx_sp.reset(new RegisterContextDarwin_arm_Mach(thread, data));
5486 break;
5487
5488 case llvm::MachO::CPU_TYPE_I386:
5489 reg_ctx_sp.reset(new RegisterContextDarwin_i386_Mach(thread, data));
5490 break;
5491
5492 case llvm::MachO::CPU_TYPE_X86_64:
5493 reg_ctx_sp.reset(new RegisterContextDarwin_x86_64_Mach(thread, data));
5494 break;
5495 }
5496 }
5497 }
5498 return reg_ctx_sp;
5499}
5500
5501ObjectFile::Type ObjectFileMachO::CalculateType() {
5502 switch (m_header.filetype) {
5503 case MH_OBJECT: // 0x1u
5504 if (GetAddressByteSize() == 4) {
5505 // 32 bit kexts are just object files, but they do have a valid
5506 // UUID load command.
5507 UUID uuid;
5508 if (GetUUID(&uuid)) {
5509 // this checking for the UUID load command is not enough
5510 // we could eventually look for the symbol named
5511 // "OSKextGetCurrentIdentifier" as this is required of kexts
5512 if (m_strata == eStrataInvalid)
5513 m_strata = eStrataKernel;
5514 return eTypeSharedLibrary;
5515 }
5516 }
5517 return eTypeObjectFile;
5518
5519 case MH_EXECUTE:
5520 return eTypeExecutable; // 0x2u
5521 case MH_FVMLIB:
5522 return eTypeSharedLibrary; // 0x3u
5523 case MH_CORE:
5524 return eTypeCoreFile; // 0x4u
5525 case MH_PRELOAD:
5526 return eTypeSharedLibrary; // 0x5u
5527 case MH_DYLIB:
5528 return eTypeSharedLibrary; // 0x6u
5529 case MH_DYLINKER:
5530 return eTypeDynamicLinker; // 0x7u
5531 case MH_BUNDLE:
5532 return eTypeSharedLibrary; // 0x8u
5533 case MH_DYLIB_STUB:
5534 return eTypeStubLibrary; // 0x9u
5535 case MH_DSYM:
5536 return eTypeDebugInfo; // 0xAu
5537 case MH_KEXT_BUNDLE:
5538 return eTypeSharedLibrary; // 0xBu
5539 default:
5540 break;
5541 }
5542 return eTypeUnknown;
5543}
5544
5545ObjectFile::Strata ObjectFileMachO::CalculateStrata() {
5546 switch (m_header.filetype) {
5547 case MH_OBJECT: // 0x1u
5548 {
5549 // 32 bit kexts are just object files, but they do have a valid
5550 // UUID load command.
5551 UUID uuid;
5552 if (GetUUID(&uuid)) {
5553 // this checking for the UUID load command is not enough
5554 // we could eventually look for the symbol named
5555 // "OSKextGetCurrentIdentifier" as this is required of kexts
5556 if (m_type == eTypeInvalid)
5557 m_type = eTypeSharedLibrary;
5558
5559 return eStrataKernel;
5560 }
5561 }
5562 return eStrataUnknown;
5563
5564 case MH_EXECUTE: // 0x2u
5565 // Check for the MH_DYLDLINK bit in the flags
5566 if (m_header.flags & MH_DYLDLINK) {
5567 return eStrataUser;
5568 } else {
5569 SectionList *section_list = GetSectionList();
5570 if (section_list) {
5571 static ConstString g_kld_section_name("__KLD");
5572 if (section_list->FindSectionByName(g_kld_section_name))
5573 return eStrataKernel;
5574 }
5575 }
5576 return eStrataRawImage;
5577
5578 case MH_FVMLIB:
5579 return eStrataUser; // 0x3u
5580 case MH_CORE:
5581 return eStrataUnknown; // 0x4u
5582 case MH_PRELOAD:
5583 return eStrataRawImage; // 0x5u
5584 case MH_DYLIB:
5585 return eStrataUser; // 0x6u
5586 case MH_DYLINKER:
5587 return eStrataUser; // 0x7u
5588 case MH_BUNDLE:
5589 return eStrataUser; // 0x8u
5590 case MH_DYLIB_STUB:
5591 return eStrataUser; // 0x9u
5592 case MH_DSYM:
5593 return eStrataUnknown; // 0xAu
5594 case MH_KEXT_BUNDLE:
5595 return eStrataKernel; // 0xBu
5596 default:
5597 break;
5598 }
5599 return eStrataUnknown;
5600}
5601
5602uint32_t ObjectFileMachO::GetVersion(uint32_t *versions,
5603 uint32_t num_versions) {
5604 ModuleSP module_sp(GetModule());
5605 if (module_sp) {
5606 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5607 struct dylib_command load_cmd;
5608 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5609 uint32_t version_cmd = 0;
5610 uint64_t version = 0;
5611 uint32_t i;
5612 for (i = 0; i < m_header.ncmds; ++i) {
5613 const lldb::offset_t cmd_offset = offset;
5614 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL__null)
5615 break;
5616
5617 if (load_cmd.cmd == LC_ID_DYLIB) {
5618 if (version_cmd == 0) {
5619 version_cmd = load_cmd.cmd;
5620 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL__null)
5621 break;
5622 version = load_cmd.dylib.current_version;
5623 }
5624 break; // Break for now unless there is another more complete version
5625 // number load command in the future.
5626 }
5627 offset = cmd_offset + load_cmd.cmdsize;
5628 }
5629
5630 if (version_cmd == LC_ID_DYLIB) {
5631 if (versions != NULL__null && num_versions > 0) {
5632 if (num_versions > 0)
5633 versions[0] = (version & 0xFFFF0000ull) >> 16;
5634 if (num_versions > 1)
5635 versions[1] = (version & 0x0000FF00ull) >> 8;
5636 if (num_versions > 2)
5637 versions[2] = (version & 0x000000FFull);
5638 // Fill in an remaining version numbers with invalid values
5639 for (i = 3; i < num_versions; ++i)
5640 versions[i] = UINT32_MAX(4294967295U);
5641 }
5642 // The LC_ID_DYLIB load command has a version with 3 version numbers
5643 // in it, so always return 3
5644 return 3;
5645 }
5646 }
5647 return false;
5648}
5649
5650bool ObjectFileMachO::GetArchitecture(ArchSpec &arch) {
5651 ModuleSP module_sp(GetModule());
5652 if (module_sp) {
5653 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
5654 return GetArchitecture(m_header, m_data,
5655 MachHeaderSizeFromMagic(m_header.magic), arch);
5656 }
5657 return false;
5658}
5659
5660UUID ObjectFileMachO::GetProcessSharedCacheUUID(Process *process) {
5661 UUID uuid;
5662 if (process && process->GetDynamicLoader()) {
5663 DynamicLoader *dl = process->GetDynamicLoader();
5664 addr_t load_address;
5665 LazyBool using_shared_cache;
5666 LazyBool private_shared_cache;
5667 dl->GetSharedCacheInformation(load_address, uuid, using_shared_cache,
5668 private_shared_cache);
5669 }
5670 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS(1u << 20) | LIBLLDB_LOG_PROCESS(1u << 1)));
5671 if (log)
5672 log->Printf("inferior process shared cache has a UUID of %s", uuid.GetAsString().c_str());
5673 return uuid;
5674}
5675
5676UUID ObjectFileMachO::GetLLDBSharedCacheUUID() {
5677 UUID uuid;
5678#if defined(__APPLE__) && \
5679 (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
5680 uint8_t *(*dyld_get_all_image_infos)(void);
5681 dyld_get_all_image_infos =
5682 (uint8_t * (*)())dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos");
5683 if (dyld_get_all_image_infos) {
5684 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5685 if (dyld_all_image_infos_address) {
5686 uint32_t *version = (uint32_t *)
5687 dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5688 if (*version >= 13) {
5689 uuid_t *sharedCacheUUID_address = 0;
5690 int wordsize = sizeof(uint8_t *);
5691 if (wordsize == 8) {
5692 sharedCacheUUID_address =
5693 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5694 160); // sharedCacheUUID <mach-o/dyld_images.h>
5695 } else {
5696 sharedCacheUUID_address =
5697 (uuid_t *)((uint8_t *)dyld_all_image_infos_address +
5698 84); // sharedCacheUUID <mach-o/dyld_images.h>
5699 }
5700 uuid.SetBytes(sharedCacheUUID_address);
5701 }
5702 }
5703 } else {
5704 // Exists in macOS 10.12 and later, iOS 10.0 and later - dyld SPI
5705 bool *(*dyld_get_shared_cache_uuid)(uuid_t);
5706 dyld_get_shared_cache_uuid = (bool *(*)(uuid_t))
5707 dlsym(RTLD_DEFAULT, "_dyld_get_shared_cache_uuid");
5708 if (dyld_get_shared_cache_uuid) {
5709 uuid_t tmp_uuid;
5710 if (dyld_get_shared_cache_uuid(tmp_uuid))
5711 uuid.SetBytes(tmp_uuid);
5712 }
5713 }
5714 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS(1u << 20) | LIBLLDB_LOG_PROCESS(1u << 1)));
5715 if (log && uuid.IsValid())
5716 log->Printf("lldb's in-memory shared cache has a UUID of %s", uuid.GetAsString().c_str());
5717#endif
5718 return uuid;
5719}
5720
5721uint32_t ObjectFileMachO::GetMinimumOSVersion(uint32_t *versions,
5722 uint32_t num_versions) {
5723 if (m_min_os_versions.empty()) {
5724 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5725 bool success = false;
5726 for (uint32_t i = 0; success == false && i < m_header.ncmds; ++i) {
5727 const lldb::offset_t load_cmd_offset = offset;
5728
5729 version_min_command lc;
5730 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL__null)
5731 break;
5732 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
5733 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
5734 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
5735 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
5736 if (m_data.GetU32(&offset, &lc.version,
5737 (sizeof(lc) / sizeof(uint32_t)) - 2)) {
5738 const uint32_t xxxx = lc.version >> 16;
5739 const uint32_t yy = (lc.version >> 8) & 0xffu;
5740 const uint32_t zz = lc.version & 0xffu;
5741 if (xxxx) {
5742 m_min_os_versions.push_back(xxxx);
5743 m_min_os_versions.push_back(yy);
5744 m_min_os_versions.push_back(zz);
5745 }
5746 success = true;
5747 }
5748 }
5749 offset = load_cmd_offset + lc.cmdsize;
5750 }
5751
5752 if (success == false) {
5753 // Push an invalid value so we don't keep trying to
5754 m_min_os_versions.push_back(UINT32_MAX(4294967295U));
5755 }
5756 }
5757
5758 if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX(4294967295U)) {
5759 if (versions != NULL__null && num_versions > 0) {
5760 for (size_t i = 0; i < num_versions; ++i) {
5761 if (i < m_min_os_versions.size())
5762 versions[i] = m_min_os_versions[i];
5763 else
5764 versions[i] = 0;
5765 }
5766 }
5767 return m_min_os_versions.size();
5768 }
5769 // Call the superclasses version that will empty out the data
5770 return ObjectFile::GetMinimumOSVersion(versions, num_versions);
5771}
5772
5773uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
5774 uint32_t num_versions) {
5775 if (m_sdk_versions.empty()) {
5776 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5777 bool success = false;
5778 for (uint32_t i = 0; success == false && i < m_header.ncmds; ++i) {
5779 const lldb::offset_t load_cmd_offset = offset;
5780
5781 version_min_command lc;
5782 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL__null)
5783 break;
5784 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
5785 lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS ||
5786 lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS ||
5787 lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) {
5788 if (m_data.GetU32(&offset, &lc.version,
5789 (sizeof(lc) / sizeof(uint32_t)) - 2)) {
5790 const uint32_t xxxx = lc.sdk >> 16;
5791 const uint32_t yy = (lc.sdk >> 8) & 0xffu;
5792 const uint32_t zz = lc.sdk & 0xffu;
5793 if (xxxx) {
5794 m_sdk_versions.push_back(xxxx);
5795 m_sdk_versions.push_back(yy);
5796 m_sdk_versions.push_back(zz);
5797 }
5798 success = true;
5799 }
5800 }
5801 offset = load_cmd_offset + lc.cmdsize;
5802 }
5803
5804 if (success == false) {
5805 // Push an invalid value so we don't keep trying to
5806 m_sdk_versions.push_back(UINT32_MAX(4294967295U));
5807 }
5808 }
5809
5810 if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX(4294967295U)) {
5811 if (versions != NULL__null && num_versions > 0) {
5812 for (size_t i = 0; i < num_versions; ++i) {
5813 if (i < m_sdk_versions.size())
5814 versions[i] = m_sdk_versions[i];
5815 else
5816 versions[i] = 0;
5817 }
5818 }
5819 return m_sdk_versions.size();
5820 }
5821 // Call the superclasses version that will empty out the data
5822 return ObjectFile::GetSDKVersion(versions, num_versions);
5823}
5824
5825bool ObjectFileMachO::GetIsDynamicLinkEditor() {
5826 return m_header.filetype == llvm::MachO::MH_DYLINKER;
5827}
5828
5829bool ObjectFileMachO::AllowAssemblyEmulationUnwindPlans() {
5830 return m_allow_assembly_emulation_unwind_plans;
5831}
5832
5833//------------------------------------------------------------------
5834// PluginInterface protocol
5835//------------------------------------------------------------------
5836lldb_private::ConstString ObjectFileMachO::GetPluginName() {
5837 return GetPluginNameStatic();
5838}
5839
5840uint32_t ObjectFileMachO::GetPluginVersion() { return 1; }
5841
5842Section *ObjectFileMachO::GetMachHeaderSection() {
5843 // Find the first address of the mach header which is the first non-zero
5844 // file sized section whose file offset is zero. This is the base file address
5845 // of the mach-o file which can be subtracted from the vmaddr of the other
5846 // segments found in memory and added to the load address
5847 ModuleSP module_sp = GetModule();
5848 if (module_sp) {
5849 SectionList *section_list = GetSectionList();
5850 if (section_list) {
5851 lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS(18446744073709551615UL);
5852 const size_t num_sections = section_list->GetSize();
5853
5854 for (size_t sect_idx = 0; sect_idx < num_sections &&
5855 mach_base_file_addr == LLDB_INVALID_ADDRESS(18446744073709551615UL);
5856 ++sect_idx) {
5857 Section *section = section_list->GetSectionAtIndex(sect_idx).get();
5858 if (section && section->GetFileSize() > 0 &&
5859 section->GetFileOffset() == 0 &&
5860 section->IsThreadSpecific() == false &&
5861 module_sp.get() == section->GetModule().get()) {
5862 return section;
5863 }
5864 }
5865 }
5866 }
5867 return nullptr;
5868}
5869
5870lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
5871 lldb::addr_t mach_header_load_address, const Section *mach_header_section,
5872 const Section *section) {
5873 ModuleSP module_sp = GetModule();
5874 if (module_sp && mach_header_section && section &&
5875 mach_header_load_address != LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
5876 lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
5877 if (mach_header_file_addr != LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
5878 if (section && section->GetFileSize() > 0 &&
5879 section->IsThreadSpecific() == false &&
5880 module_sp.get() == section->GetModule().get()) {
5881 // Ignore __LINKEDIT and __DWARF segments
5882 if (section->GetName() == GetSegmentNameLINKEDIT()) {
5883 // Only map __LINKEDIT if we have an in memory image and this isn't
5884 // a kernel binary like a kext or mach_kernel.
5885 const bool is_memory_image = (bool)m_process_wp.lock();
5886 const Strata strata = GetStrata();
5887 if (is_memory_image == false || strata == eStrataKernel)
5888 return LLDB_INVALID_ADDRESS(18446744073709551615UL);
5889 }
5890 return section->GetFileAddress() - mach_header_file_addr +
5891 mach_header_load_address;
5892 }
5893 }
5894 }
5895 return LLDB_INVALID_ADDRESS(18446744073709551615UL);
5896}
5897
5898bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
5899 bool value_is_offset) {
5900 ModuleSP module_sp = GetModule();
5901 if (module_sp) {
5902 size_t num_loaded_sections = 0;
5903 SectionList *section_list = GetSectionList();
5904 if (section_list) {
5905 const size_t num_sections = section_list->GetSize();
5906
5907 if (value_is_offset) {
5908 // "value" is an offset to apply to each top level segment
5909 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5910 // Iterate through the object file sections to find all
5911 // of the sections that size on disk (to avoid __PAGEZERO)
5912 // and load them
5913 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
5914 if (section_sp && section_sp->GetFileSize() > 0 &&
5915 section_sp->IsThreadSpecific() == false &&
5916 module_sp.get() == section_sp->GetModule().get()) {
5917 // Ignore __LINKEDIT and __DWARF segments
5918 if (section_sp->GetName() == GetSegmentNameLINKEDIT()) {
5919 // Only map __LINKEDIT if we have an in memory image and this
5920 // isn't
5921 // a kernel binary like a kext or mach_kernel.
5922 const bool is_memory_image = (bool)m_process_wp.lock();
5923 const Strata strata = GetStrata();
5924 if (is_memory_image == false || strata == eStrataKernel)
5925 continue;
5926 }
5927 if (target.GetSectionLoadList().SetSectionLoadAddress(
5928 section_sp, section_sp->GetFileAddress() + value))
5929 ++num_loaded_sections;
5930 }
5931 }
5932 } else {
5933 // "value" is the new base address of the mach_header, adjust each
5934 // section accordingly
5935
5936 Section *mach_header_section = GetMachHeaderSection();
5937 if (mach_header_section) {
5938 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
5939 SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
5940
5941 lldb::addr_t section_load_addr =
5942 CalculateSectionLoadAddressForMemoryImage(
5943 value, mach_header_section, section_sp.get());
5944 if (section_load_addr != LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
5945 if (target.GetSectionLoadList().SetSectionLoadAddress(
5946 section_sp, section_load_addr))
5947 ++num_loaded_sections;
5948 }
5949 }
5950 }
5951 }
5952 }
5953 return num_loaded_sections > 0;
5954 }
5955 return false;
5956}
5957
5958bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
5959 const FileSpec &outfile, Status &error) {
5960 if (process_sp) {
5961 Target &target = process_sp->GetTarget();
5962 const ArchSpec target_arch = target.GetArchitecture();
5963 const llvm::Triple &target_triple = target_arch.GetTriple();
5964 if (target_triple.getVendor() == llvm::Triple::Apple &&
5965 (target_triple.getOS() == llvm::Triple::MacOSX ||
5966 target_triple.getOS() == llvm::Triple::IOS ||
5967 target_triple.getOS() == llvm::Triple::WatchOS ||
5968 target_triple.getOS() == llvm::Triple::TvOS)) {
5969 bool make_core = false;
5970 switch (target_arch.GetMachine()) {
5971 case llvm::Triple::aarch64:
5972 case llvm::Triple::arm:
5973 case llvm::Triple::thumb:
5974 case llvm::Triple::x86:
5975 case llvm::Triple::x86_64:
5976 make_core = true;
5977 break;
5978 default:
5979 error.SetErrorStringWithFormat("unsupported core architecture: %s",
5980 target_triple.str().c_str());
5981 break;
5982 }
5983
5984 if (make_core) {
5985 std::vector<segment_command_64> segment_load_commands;
5986 // uint32_t range_info_idx = 0;
5987 MemoryRegionInfo range_info;
5988 Status range_error = process_sp->GetMemoryRegionInfo(0, range_info);
5989 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
5990 const ByteOrder byte_order = target_arch.GetByteOrder();
5991 if (range_error.Success()) {
5992 while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
5993 const addr_t addr = range_info.GetRange().GetRangeBase();
5994 const addr_t size = range_info.GetRange().GetByteSize();
5995
5996 if (size == 0)
5997 break;
5998
5999 // Calculate correct protections
6000 uint32_t prot = 0;
6001 if (range_info.GetReadable() == MemoryRegionInfo::eYes)
6002 prot |= VM_PROT_READ;
6003 if (range_info.GetWritable() == MemoryRegionInfo::eYes)
6004 prot |= VM_PROT_WRITE;
6005 if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
6006 prot |= VM_PROT_EXECUTE;
6007
6008 // printf ("[%3u] [0x%16.16" PRIx64 " -
6009 // 0x%16.16" PRIx64 ") %c%c%c\n",
6010 // range_info_idx,
6011 // addr,
6012 // size,
6013 // (prot & VM_PROT_READ ) ? 'r' :
6014 // '-',
6015 // (prot & VM_PROT_WRITE ) ? 'w' :
6016 // '-',
6017 // (prot & VM_PROT_EXECUTE) ? 'x' :
6018 // '-');
6019
6020 if (prot != 0) {
6021 uint32_t cmd_type = LC_SEGMENT_64;
6022 uint32_t segment_size = sizeof(segment_command_64);
6023 if (addr_byte_size == 4) {
6024 cmd_type = LC_SEGMENT;
6025 segment_size = sizeof(segment_command);
6026 }
6027 segment_command_64 segment = {
6028 cmd_type, // uint32_t cmd;
6029 segment_size, // uint32_t cmdsize;
6030 {0}, // char segname[16];
6031 addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
6032 size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
6033 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
6034 size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
6035 prot, // uint32_t maxprot;
6036 prot, // uint32_t initprot;
6037 0, // uint32_t nsects;
6038 0}; // uint32_t flags;
6039 segment_load_commands.push_back(segment);
6040 } else {
6041 // No protections and a size of 1 used to be returned from old
6042 // debugservers when we asked about a region that was past the
6043 // last memory region and it indicates the end...
6044 if (size == 1)
6045 break;
6046 }
6047
6048 range_error = process_sp->GetMemoryRegionInfo(
6049 range_info.GetRange().GetRangeEnd(), range_info);
6050 if (range_error.Fail())
6051 break;
6052 }
6053
6054 StreamString buffer(Stream::eBinary, addr_byte_size, byte_order);
6055
6056 mach_header_64 mach_header;
6057 if (addr_byte_size == 8) {
6058 mach_header.magic = MH_MAGIC_64;
6059 } else {
6060 mach_header.magic = MH_MAGIC;
6061 }
6062 mach_header.cputype = target_arch.GetMachOCPUType();
6063 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
6064 mach_header.filetype = MH_CORE;
6065 mach_header.ncmds = segment_load_commands.size();
6066 mach_header.flags = 0;
6067 mach_header.reserved = 0;
6068 ThreadList &thread_list = process_sp->GetThreadList();
6069 const uint32_t num_threads = thread_list.GetSize();
6070
6071 // Make an array of LC_THREAD data items. Each one contains
6072 // the contents of the LC_THREAD load command. The data doesn't
6073 // contain the load command + load command size, we will
6074 // add the load command and load command size as we emit the data.
6075 std::vector<StreamString> LC_THREAD_datas(num_threads);
6076 for (auto &LC_THREAD_data : LC_THREAD_datas) {
6077 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
6078 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
6079 LC_THREAD_data.SetByteOrder(byte_order);
6080 }
6081 for (uint32_t thread_idx = 0; thread_idx < num_threads;
6082 ++thread_idx) {
6083 ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
6084 if (thread_sp) {
6085 switch (mach_header.cputype) {
6086 case llvm::MachO::CPU_TYPE_ARM64:
6087 RegisterContextDarwin_arm64_Mach::Create_LC_THREAD(
6088 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6089 break;
6090
6091 case llvm::MachO::CPU_TYPE_ARM:
6092 RegisterContextDarwin_arm_Mach::Create_LC_THREAD(
6093 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6094 break;
6095
6096 case llvm::MachO::CPU_TYPE_I386:
6097 RegisterContextDarwin_i386_Mach::Create_LC_THREAD(
6098 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6099 break;
6100
6101 case llvm::MachO::CPU_TYPE_X86_64:
6102 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
6103 thread_sp.get(), LC_THREAD_datas[thread_idx]);
6104 break;
6105 }
6106 }
6107 }
6108
6109 // The size of the load command is the size of the segments...
6110 if (addr_byte_size == 8) {
6111 mach_header.sizeofcmds = segment_load_commands.size() *
6112 sizeof(struct segment_command_64);
6113 } else {
6114 mach_header.sizeofcmds =
6115 segment_load_commands.size() * sizeof(struct segment_command);
6116 }
6117
6118 // and the size of all LC_THREAD load command
6119 for (const auto &LC_THREAD_data : LC_THREAD_datas) {
6120 ++mach_header.ncmds;
6121 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
6122 }
6123
6124 printf("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x "
6125 "0x%8.8x 0x%8.8x\n",
6126 mach_header.magic, mach_header.cputype, mach_header.cpusubtype,
6127 mach_header.filetype, mach_header.ncmds,
6128 mach_header.sizeofcmds, mach_header.flags,
6129 mach_header.reserved);
6130
6131 // Write the mach header
6132 buffer.PutHex32(mach_header.magic);
6133 buffer.PutHex32(mach_header.cputype);
6134 buffer.PutHex32(mach_header.cpusubtype);
6135 buffer.PutHex32(mach_header.filetype);
6136 buffer.PutHex32(mach_header.ncmds);
6137 buffer.PutHex32(mach_header.sizeofcmds);
6138 buffer.PutHex32(mach_header.flags);
6139 if (addr_byte_size == 8) {
6140 buffer.PutHex32(mach_header.reserved);
6141 }
6142
6143 // Skip the mach header and all load commands and align to the next
6144 // 0x1000 byte boundary
6145 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
6146 if (file_offset & 0x00000fff) {
6147 file_offset += 0x00001000ull;
6148 file_offset &= (~0x00001000ull + 1);
6149 }
6150
6151 for (auto &segment : segment_load_commands) {
6152 segment.fileoff = file_offset;
6153 file_offset += segment.filesize;
6154 }
6155
6156 // Write out all of the LC_THREAD load commands
6157 for (const auto &LC_THREAD_data : LC_THREAD_datas) {
6158 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
6159 buffer.PutHex32(LC_THREAD);
6160 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
6161 buffer.Write(LC_THREAD_data.GetString().data(),
6162 LC_THREAD_data_size);
6163 }
6164
6165 // Write out all of the segment load commands
6166 for (const auto &segment : segment_load_commands) {
6167 printf("0x%8.8x 0x%8.8x [0x%16.16" PRIx64"l" "x" " - 0x%16.16" PRIx64"l" "x"
6168 ") [0x%16.16" PRIx64"l" "x" " 0x%16.16" PRIx64"l" "x"
6169 ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n",
6170 segment.cmd, segment.cmdsize, segment.vmaddr,
6171 segment.vmaddr + segment.vmsize, segment.fileoff,
6172 segment.filesize, segment.maxprot, segment.initprot,
6173 segment.nsects, segment.flags);
6174
6175 buffer.PutHex32(segment.cmd);
6176 buffer.PutHex32(segment.cmdsize);
6177 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
6178 if (addr_byte_size == 8) {
6179 buffer.PutHex64(segment.vmaddr);
6180 buffer.PutHex64(segment.vmsize);
6181 buffer.PutHex64(segment.fileoff);
6182 buffer.PutHex64(segment.filesize);
6183 } else {
6184 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
6185 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
6186 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
6187 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
6188 }
6189 buffer.PutHex32(segment.maxprot);
6190 buffer.PutHex32(segment.initprot);
6191 buffer.PutHex32(segment.nsects);
6192 buffer.PutHex32(segment.flags);
6193 }
6194
6195 File core_file;
6196 std::string core_file_path(outfile.GetPath());
6197 error = core_file.Open(core_file_path.c_str(),
6198 File::eOpenOptionWrite |
6199 File::eOpenOptionTruncate |
6200 File::eOpenOptionCanCreate);
6201 if (error.Success()) {
6202 // Read 1 page at a time
6203 uint8_t bytes[0x1000];
6204 // Write the mach header and load commands out to the core file
6205 size_t bytes_written = buffer.GetString().size();
6206 error = core_file.Write(buffer.GetString().data(), bytes_written);
6207 if (error.Success()) {
6208 // Now write the file data for all memory segments in the process
6209 for (const auto &segment : segment_load_commands) {
6210 if (core_file.SeekFromStart(segment.fileoff) == -1) {
6211 error.SetErrorStringWithFormat(
6212 "unable to seek to offset 0x%" PRIx64"l" "x" " in '%s'",
6213 segment.fileoff, core_file_path.c_str());
6214 break;
6215 }
6216
6217 printf("Saving %" PRId64"l" "d"
6218 " bytes of data for memory region at 0x%" PRIx64"l" "x" "\n",
6219 segment.vmsize, segment.vmaddr);
6220 addr_t bytes_left = segment.vmsize;
6221 addr_t addr = segment.vmaddr;
6222 Status memory_read_error;
6223 while (bytes_left > 0 && error.Success()) {
6224 const size_t bytes_to_read =
6225 bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
6226 const size_t bytes_read = process_sp->ReadMemory(
6227 addr, bytes, bytes_to_read, memory_read_error);
6228 if (bytes_read == bytes_to_read) {
6229 size_t bytes_written = bytes_read;
6230 error = core_file.Write(bytes, bytes_written);
6231 bytes_left -= bytes_read;
6232 addr += bytes_read;
6233 } else {
6234 // Some pages within regions are not readable, those
6235 // should be zero filled
6236 memset(bytes, 0, bytes_to_read);
6237 size_t bytes_written = bytes_to_read;
6238 error = core_file.Write(bytes, bytes_written);
6239 bytes_left -= bytes_to_read;
6240 addr += bytes_to_read;
6241 }
6242 }
6243 }
6244 }
6245 }
6246 } else {
6247 error.SetErrorString(
6248 "process doesn't support getting memory region info");
6249 }
6250 }
6251 return true; // This is the right plug to handle saving core files for
6252 // this process
6253 }
6254 }
6255 return false;
6256}