blob: 2c4b241d1ae9d17942e97d63639d0679f0a7f681 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Jim Ingham46d005d2014-04-02 22:53:21 +000010#include "llvm/ADT/StringRef.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
Greg Clayton3f839a32012-09-05 01:38:55 +000012#include "lldb/lldb-private-log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include "lldb/Core/ArchSpec.h"
14#include "lldb/Core/DataBuffer.h"
Jason Molendaf6ce26f2013-04-10 05:58:57 +000015#include "lldb/Core/Debugger.h"
Greg Claytona2715cf2014-06-13 00:54:12 +000016#include "lldb/Core/Error.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Core/FileSpecList.h"
Greg Clayton3f839a32012-09-05 01:38:55 +000018#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/Module.h"
Greg Claytonf4d6de62013-04-24 22:29:28 +000020#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/PluginManager.h"
Greg Clayton1eac0c72012-04-24 03:06:13 +000022#include "lldb/Core/RangeMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/Section.h"
24#include "lldb/Core/StreamFile.h"
25#include "lldb/Core/StreamString.h"
26#include "lldb/Core/Timer.h"
27#include "lldb/Core/UUID.h"
Greg Claytone38a5ed2012-01-05 03:57:59 +000028#include "lldb/Host/Host.h"
29#include "lldb/Host/FileSpec.h"
Sean Callananb6d70eb2011-10-12 02:08:07 +000030#include "lldb/Symbol/ClangNamespaceDecl.h"
Jason Molenda5635f772013-03-21 03:36:01 +000031#include "lldb/Symbol/DWARFCallFrameInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Symbol/ObjectFile.h"
Greg Clayton26b47e22012-04-18 05:19:20 +000033#include "lldb/Target/Platform.h"
Greg Claytonc9660542012-02-05 02:38:54 +000034#include "lldb/Target/Process.h"
Greg Clayton7524e092014-02-06 20:10:16 +000035#include "lldb/Target/SectionLoadList.h"
Greg Clayton26b47e22012-04-18 05:19:20 +000036#include "lldb/Target/Target.h"
Greg Claytona2715cf2014-06-13 00:54:12 +000037#include "lldb/Target/Thread.h"
38#include "lldb/Target/ThreadList.h"
Greg Claytonc859e2d2012-02-13 23:10:39 +000039#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
Jason Molendaa3329782014-03-29 18:54:20 +000040#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
Greg Claytonc859e2d2012-02-13 23:10:39 +000041#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
Greg Claytonc3776bf2012-02-09 06:16:32 +000042#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043
Jim Ingham46d005d2014-04-02 22:53:21 +000044#include "lldb/Utility/SafeMachO.h"
45
46#include "ObjectFileMachO.h"
47
Todd Fiala013434e2014-07-09 01:29:05 +000048#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +000049// GetLLDBSharedCacheUUID() needs to call dlsym()
50#include <dlfcn.h>
51#endif
52
Daniel Maleaffeb4b62013-04-17 19:24:22 +000053#ifndef __APPLE__
54#include "Utility/UuidCompatibility.h"
55#endif
56
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057using namespace lldb;
58using namespace lldb_private;
Greg Claytone1a916a2010-07-21 22:12:05 +000059using namespace llvm::MachO;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060
Jason Molenda4e7511e2013-03-06 23:19:17 +000061class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
Greg Claytonc3776bf2012-02-09 06:16:32 +000062{
63public:
64 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
65 RegisterContextDarwin_x86_64 (thread, 0)
66 {
67 SetRegisterDataFrom_LC_THREAD (data);
68 }
69
70 virtual void
71 InvalidateAllRegisters ()
72 {
73 // Do nothing... registers are always valid...
74 }
75
76 void
77 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
78 {
Greg Claytonc7bece562013-01-25 18:06:21 +000079 lldb::offset_t offset = 0;
Greg Claytonc3776bf2012-02-09 06:16:32 +000080 SetError (GPRRegSet, Read, -1);
81 SetError (FPURegSet, Read, -1);
82 SetError (EXCRegSet, Read, -1);
Greg Claytonc859e2d2012-02-13 23:10:39 +000083 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +000084
Greg Claytonc859e2d2012-02-13 23:10:39 +000085 while (!done)
Greg Claytonc3776bf2012-02-09 06:16:32 +000086 {
Greg Claytonc859e2d2012-02-13 23:10:39 +000087 int flavor = data.GetU32 (&offset);
88 if (flavor == 0)
89 done = true;
90 else
Greg Claytonc3776bf2012-02-09 06:16:32 +000091 {
Greg Claytonc859e2d2012-02-13 23:10:39 +000092 uint32_t i;
93 uint32_t count = data.GetU32 (&offset);
94 switch (flavor)
95 {
96 case GPRRegSet:
97 for (i=0; i<count; ++i)
98 (&gpr.rax)[i] = data.GetU64(&offset);
99 SetError (GPRRegSet, Read, 0);
100 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000101
Greg Claytonc859e2d2012-02-13 23:10:39 +0000102 break;
103 case FPURegSet:
104 // TODO: fill in FPU regs....
105 //SetError (FPURegSet, Read, -1);
106 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000107
Greg Claytonc859e2d2012-02-13 23:10:39 +0000108 break;
109 case EXCRegSet:
110 exc.trapno = data.GetU32(&offset);
111 exc.err = data.GetU32(&offset);
112 exc.faultvaddr = data.GetU64(&offset);
113 SetError (EXCRegSet, Read, 0);
114 done = true;
115 break;
116 case 7:
117 case 8:
118 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000119 // fancy flavors that encapsulate of the above
120 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000121 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000122
Greg Claytonc859e2d2012-02-13 23:10:39 +0000123 default:
124 done = true;
125 break;
126 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000127 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000128 }
129 }
Greg Claytona2715cf2014-06-13 00:54:12 +0000130
Jason Molendad20359d2014-11-11 10:59:15 +0000131
Greg Claytona2715cf2014-06-13 00:54:12 +0000132 static size_t
133 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
134 {
135 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
136 if (reg_info == NULL)
137 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
138 if (reg_info)
139 {
140 lldb_private::RegisterValue reg_value;
141 if (reg_ctx->ReadRegister(reg_info, reg_value))
142 {
143 if (reg_info->byte_size >= reg_byte_size)
144 data.Write(reg_value.GetBytes(), reg_byte_size);
145 else
146 {
147 data.Write(reg_value.GetBytes(), reg_info->byte_size);
148 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
149 data.PutChar(0);
150 }
151 return reg_byte_size;
152 }
153 }
154 // Just write zeros if all else fails
155 for (size_t i=0; i<reg_byte_size; ++ i)
156 data.PutChar(0);
157 return reg_byte_size;
158 }
Jason Molendad20359d2014-11-11 10:59:15 +0000159
Greg Claytona2715cf2014-06-13 00:54:12 +0000160 static bool
161 Create_LC_THREAD (Thread *thread, Stream &data)
162 {
163 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
164 if (reg_ctx_sp)
165 {
166 RegisterContext *reg_ctx = reg_ctx_sp.get();
167
168 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000169 data.PutHex32 (GPRWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000170 WriteRegister (reg_ctx, "rax", NULL, 8, data);
171 WriteRegister (reg_ctx, "rbx", NULL, 8, data);
172 WriteRegister (reg_ctx, "rcx", NULL, 8, data);
173 WriteRegister (reg_ctx, "rdx", NULL, 8, data);
174 WriteRegister (reg_ctx, "rdi", NULL, 8, data);
175 WriteRegister (reg_ctx, "rsi", NULL, 8, data);
176 WriteRegister (reg_ctx, "rbp", NULL, 8, data);
177 WriteRegister (reg_ctx, "rsp", NULL, 8, data);
178 WriteRegister (reg_ctx, "r8", NULL, 8, data);
179 WriteRegister (reg_ctx, "r9", NULL, 8, data);
180 WriteRegister (reg_ctx, "r10", NULL, 8, data);
181 WriteRegister (reg_ctx, "r11", NULL, 8, data);
182 WriteRegister (reg_ctx, "r12", NULL, 8, data);
183 WriteRegister (reg_ctx, "r13", NULL, 8, data);
184 WriteRegister (reg_ctx, "r14", NULL, 8, data);
185 WriteRegister (reg_ctx, "r15", NULL, 8, data);
186 WriteRegister (reg_ctx, "rip", NULL, 8, data);
187 WriteRegister (reg_ctx, "rflags", NULL, 8, data);
188 WriteRegister (reg_ctx, "cs", NULL, 8, data);
189 WriteRegister (reg_ctx, "fs", NULL, 8, data);
190 WriteRegister (reg_ctx, "gs", NULL, 8, data);
191
192// // Write out the FPU registers
193// const size_t fpu_byte_size = sizeof(FPU);
194// size_t bytes_written = 0;
195// data.PutHex32 (FPURegSet);
196// data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
197// bytes_written += data.PutHex32(0); // uint32_t pad[0]
198// bytes_written += data.PutHex32(0); // uint32_t pad[1]
199// bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, data); // uint16_t fcw; // "fctrl"
200// bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, data); // uint16_t fsw; // "fstat"
201// bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, data); // uint8_t ftw; // "ftag"
202// bytes_written += data.PutHex8 (0); // uint8_t pad1;
203// bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, data); // uint16_t fop; // "fop"
204// bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, data); // uint32_t ip; // "fioff"
205// bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, data); // uint16_t cs; // "fiseg"
206// bytes_written += data.PutHex16 (0); // uint16_t pad2;
207// bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, data); // uint32_t dp; // "fooff"
208// bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, data); // uint16_t ds; // "foseg"
209// bytes_written += data.PutHex16 (0); // uint16_t pad3;
210// bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, data); // uint32_t mxcsr;
211// bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, 4, data);// uint32_t mxcsrmask;
212// bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, sizeof(MMSReg), data);
213// bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, sizeof(MMSReg), data);
214// bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, sizeof(MMSReg), data);
215// bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, sizeof(MMSReg), data);
216// bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, sizeof(MMSReg), data);
217// bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, sizeof(MMSReg), data);
218// bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, sizeof(MMSReg), data);
219// bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, sizeof(MMSReg), data);
220// bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, sizeof(XMMReg), data);
221// bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, sizeof(XMMReg), data);
222// bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, sizeof(XMMReg), data);
223// bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, sizeof(XMMReg), data);
224// bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, sizeof(XMMReg), data);
225// bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, sizeof(XMMReg), data);
226// bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, sizeof(XMMReg), data);
227// bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, sizeof(XMMReg), data);
228// bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, sizeof(XMMReg), data);
229// bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, sizeof(XMMReg), data);
230// bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, sizeof(XMMReg), data);
231// bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, sizeof(XMMReg), data);
232// bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, sizeof(XMMReg), data);
233// bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, sizeof(XMMReg), data);
234// bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, sizeof(XMMReg), data);
235// bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, sizeof(XMMReg), data);
236//
237// // Fill rest with zeros
238// for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ i)
239// data.PutChar(0);
240
241 // Write out the EXC registers
242 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000243 data.PutHex32 (EXCWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000244 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
245 WriteRegister (reg_ctx, "err", NULL, 4, data);
246 WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data);
247 return true;
248 }
249 return false;
250 }
251
Greg Claytonc859e2d2012-02-13 23:10:39 +0000252protected:
253 virtual int
254 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
255 {
256 return 0;
257 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000258
Greg Claytonc859e2d2012-02-13 23:10:39 +0000259 virtual int
260 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
261 {
262 return 0;
263 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000264
Greg Claytonc859e2d2012-02-13 23:10:39 +0000265 virtual int
266 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
267 {
268 return 0;
269 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000270
Greg Claytonc859e2d2012-02-13 23:10:39 +0000271 virtual int
272 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
273 {
274 return 0;
275 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000276
Greg Claytonc859e2d2012-02-13 23:10:39 +0000277 virtual int
278 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
279 {
280 return 0;
281 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000282
Greg Claytonc859e2d2012-02-13 23:10:39 +0000283 virtual int
284 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
285 {
286 return 0;
287 }
288};
Greg Claytonc3776bf2012-02-09 06:16:32 +0000289
Greg Claytonc859e2d2012-02-13 23:10:39 +0000290
Jason Molenda4e7511e2013-03-06 23:19:17 +0000291class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
Greg Claytonc859e2d2012-02-13 23:10:39 +0000292{
293public:
294 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
295 RegisterContextDarwin_i386 (thread, 0)
296 {
297 SetRegisterDataFrom_LC_THREAD (data);
298 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000299
Greg Claytonc859e2d2012-02-13 23:10:39 +0000300 virtual void
301 InvalidateAllRegisters ()
302 {
303 // Do nothing... registers are always valid...
304 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000305
Greg Claytonc859e2d2012-02-13 23:10:39 +0000306 void
307 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
308 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000309 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000310 SetError (GPRRegSet, Read, -1);
311 SetError (FPURegSet, Read, -1);
312 SetError (EXCRegSet, Read, -1);
313 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000314
Greg Claytonc859e2d2012-02-13 23:10:39 +0000315 while (!done)
316 {
317 int flavor = data.GetU32 (&offset);
318 if (flavor == 0)
319 done = true;
320 else
Greg Claytonc3776bf2012-02-09 06:16:32 +0000321 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000322 uint32_t i;
323 uint32_t count = data.GetU32 (&offset);
324 switch (flavor)
325 {
326 case GPRRegSet:
327 for (i=0; i<count; ++i)
328 (&gpr.eax)[i] = data.GetU32(&offset);
329 SetError (GPRRegSet, Read, 0);
330 done = true;
331
332 break;
333 case FPURegSet:
334 // TODO: fill in FPU regs....
335 //SetError (FPURegSet, Read, -1);
336 done = true;
337
338 break;
339 case EXCRegSet:
340 exc.trapno = data.GetU32(&offset);
341 exc.err = data.GetU32(&offset);
342 exc.faultvaddr = data.GetU32(&offset);
343 SetError (EXCRegSet, Read, 0);
344 done = true;
345 break;
346 case 7:
347 case 8:
348 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000349 // fancy flavors that encapsulate of the above
350 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000351 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000352
Greg Claytonc859e2d2012-02-13 23:10:39 +0000353 default:
354 done = true;
355 break;
356 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000357 }
358 }
359 }
Jason Molendad20359d2014-11-11 10:59:15 +0000360
361 static size_t
362 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
363 {
364 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
365 if (reg_info == NULL)
366 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
367 if (reg_info)
368 {
369 lldb_private::RegisterValue reg_value;
370 if (reg_ctx->ReadRegister(reg_info, reg_value))
371 {
372 if (reg_info->byte_size >= reg_byte_size)
373 data.Write(reg_value.GetBytes(), reg_byte_size);
374 else
375 {
376 data.Write(reg_value.GetBytes(), reg_info->byte_size);
377 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
378 data.PutChar(0);
379 }
380 return reg_byte_size;
381 }
382 }
383 // Just write zeros if all else fails
384 for (size_t i=0; i<reg_byte_size; ++ i)
385 data.PutChar(0);
386 return reg_byte_size;
387 }
388
389 static bool
390 Create_LC_THREAD (Thread *thread, Stream &data)
391 {
392 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
393 if (reg_ctx_sp)
394 {
395 RegisterContext *reg_ctx = reg_ctx_sp.get();
396
397 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000398 data.PutHex32 (GPRWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000399 WriteRegister (reg_ctx, "eax", NULL, 4, data);
400 WriteRegister (reg_ctx, "ebx", NULL, 4, data);
401 WriteRegister (reg_ctx, "ecx", NULL, 4, data);
402 WriteRegister (reg_ctx, "edx", NULL, 4, data);
403 WriteRegister (reg_ctx, "edi", NULL, 4, data);
404 WriteRegister (reg_ctx, "esi", NULL, 4, data);
405 WriteRegister (reg_ctx, "ebp", NULL, 4, data);
406 WriteRegister (reg_ctx, "esp", NULL, 4, data);
407 WriteRegister (reg_ctx, "ss", NULL, 4, data);
408 WriteRegister (reg_ctx, "eflags", NULL, 4, data);
409 WriteRegister (reg_ctx, "eip", NULL, 4, data);
410 WriteRegister (reg_ctx, "cs", NULL, 4, data);
411 WriteRegister (reg_ctx, "ds", NULL, 4, data);
412 WriteRegister (reg_ctx, "es", NULL, 4, data);
413 WriteRegister (reg_ctx, "fs", NULL, 4, data);
414 WriteRegister (reg_ctx, "gs", NULL, 4, data);
415
416 // Write out the EXC registers
417 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000418 data.PutHex32 (EXCWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000419 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
420 WriteRegister (reg_ctx, "err", NULL, 4, data);
Jason Molenda22952582014-11-12 01:11:36 +0000421 WriteRegister (reg_ctx, "faultvaddr", NULL, 4, data);
Jason Molendad20359d2014-11-11 10:59:15 +0000422 return true;
423 }
424 return false;
425 }
426
Greg Claytonc3776bf2012-02-09 06:16:32 +0000427protected:
428 virtual int
429 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
430 {
431 return 0;
432 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000433
Greg Claytonc3776bf2012-02-09 06:16:32 +0000434 virtual int
435 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
436 {
437 return 0;
438 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000439
Greg Claytonc3776bf2012-02-09 06:16:32 +0000440 virtual int
441 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
442 {
443 return 0;
444 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000445
Greg Claytonc3776bf2012-02-09 06:16:32 +0000446 virtual int
447 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
448 {
449 return 0;
450 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000451
Greg Claytonc3776bf2012-02-09 06:16:32 +0000452 virtual int
453 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
454 {
455 return 0;
456 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000457
Greg Claytonc3776bf2012-02-09 06:16:32 +0000458 virtual int
459 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
460 {
461 return 0;
462 }
463};
464
Jason Molenda4e7511e2013-03-06 23:19:17 +0000465class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000466{
467public:
468 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
Greg Claytonc2807462012-10-30 23:57:32 +0000469 RegisterContextDarwin_arm (thread, 0)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000470 {
471 SetRegisterDataFrom_LC_THREAD (data);
472 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000473
Greg Claytonc859e2d2012-02-13 23:10:39 +0000474 virtual void
475 InvalidateAllRegisters ()
476 {
477 // Do nothing... registers are always valid...
478 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000479
Greg Claytonc859e2d2012-02-13 23:10:39 +0000480 void
481 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
482 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000483 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000484 SetError (GPRRegSet, Read, -1);
485 SetError (FPURegSet, Read, -1);
486 SetError (EXCRegSet, Read, -1);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000487 bool done = false;
488
489 while (!done)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000490 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000491 int flavor = data.GetU32 (&offset);
492 uint32_t count = data.GetU32 (&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000493 lldb::offset_t next_thread_state = offset + (count * 4);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000494 switch (flavor)
495 {
496 case GPRRegSet:
497 for (uint32_t i=0; i<count; ++i)
Jason Molendaddf91772013-05-14 04:50:47 +0000498 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000499 gpr.r[i] = data.GetU32(&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000500 }
501
502 // Note that gpr.cpsr is also copied by the above loop; this loop technically extends
503 // one element past the end of the gpr.r[] array.
504
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000505 SetError (GPRRegSet, Read, 0);
Jason Molendaddf91772013-05-14 04:50:47 +0000506 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000507 break;
508
509 case FPURegSet:
510 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000511 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0];
512 const int fpu_reg_buf_size = sizeof (fpu.floats);
513 if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000514 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000515 offset += fpu_reg_buf_size;
516 fpu.fpscr = data.GetU32(&offset);
517 SetError (FPURegSet, Read, 0);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000518 }
Jason Molenda663d2e12013-05-14 03:52:22 +0000519 else
520 {
521 done = true;
522 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000523 }
Jason Molendaddf91772013-05-14 04:50:47 +0000524 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000525 break;
526
527 case EXCRegSet:
Jason Molendaddf91772013-05-14 04:50:47 +0000528 if (count == 3)
529 {
530 exc.exception = data.GetU32(&offset);
531 exc.fsr = data.GetU32(&offset);
532 exc.far = data.GetU32(&offset);
533 SetError (EXCRegSet, Read, 0);
534 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000535 done = true;
Jason Molendaddf91772013-05-14 04:50:47 +0000536 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000537 break;
538
539 // Unknown register set flavor, stop trying to parse.
540 default:
541 done = true;
542 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000543 }
544 }
Jason Molenda22952582014-11-12 01:11:36 +0000545
546 static size_t
547 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
548 {
549 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
550 if (reg_info == NULL)
551 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
552 if (reg_info)
553 {
554 lldb_private::RegisterValue reg_value;
555 if (reg_ctx->ReadRegister(reg_info, reg_value))
556 {
557 if (reg_info->byte_size >= reg_byte_size)
558 data.Write(reg_value.GetBytes(), reg_byte_size);
559 else
560 {
561 data.Write(reg_value.GetBytes(), reg_info->byte_size);
562 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
563 data.PutChar(0);
564 }
565 return reg_byte_size;
566 }
567 }
568 // Just write zeros if all else fails
569 for (size_t i=0; i<reg_byte_size; ++ i)
570 data.PutChar(0);
571 return reg_byte_size;
572 }
573
574 static bool
575 Create_LC_THREAD (Thread *thread, Stream &data)
576 {
577 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
578 if (reg_ctx_sp)
579 {
580 RegisterContext *reg_ctx = reg_ctx_sp.get();
581
582 data.PutHex32 (GPRRegSet); // Flavor
583 data.PutHex32 (GPRWordCount);
584 WriteRegister (reg_ctx, "r0", NULL, 4, data);
585 WriteRegister (reg_ctx, "r1", NULL, 4, data);
586 WriteRegister (reg_ctx, "r2", NULL, 4, data);
587 WriteRegister (reg_ctx, "r3", NULL, 4, data);
588 WriteRegister (reg_ctx, "r4", NULL, 4, data);
589 WriteRegister (reg_ctx, "r5", NULL, 4, data);
590 WriteRegister (reg_ctx, "r6", NULL, 4, data);
591 WriteRegister (reg_ctx, "r7", NULL, 4, data);
592 WriteRegister (reg_ctx, "r8", NULL, 4, data);
593 WriteRegister (reg_ctx, "r9", NULL, 4, data);
594 WriteRegister (reg_ctx, "r10", NULL, 4, data);
595 WriteRegister (reg_ctx, "r11", NULL, 4, data);
596 WriteRegister (reg_ctx, "r12", NULL, 4, data);
597 WriteRegister (reg_ctx, "sp", NULL, 4, data);
598 WriteRegister (reg_ctx, "lr", NULL, 4, data);
599 WriteRegister (reg_ctx, "pc", NULL, 4, data);
600 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
601
602 // Write out the EXC registers
603// data.PutHex32 (EXCRegSet);
604// data.PutHex32 (EXCWordCount);
605// WriteRegister (reg_ctx, "exception", NULL, 4, data);
606// WriteRegister (reg_ctx, "fsr", NULL, 4, data);
607// WriteRegister (reg_ctx, "far", NULL, 4, data);
608 return true;
609 }
610 return false;
611 }
612
Greg Claytonc859e2d2012-02-13 23:10:39 +0000613protected:
614 virtual int
615 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
616 {
Jason Molendaddf91772013-05-14 04:50:47 +0000617 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000618 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000619
Greg Claytonc859e2d2012-02-13 23:10:39 +0000620 virtual int
621 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
622 {
Jason Molendaddf91772013-05-14 04:50:47 +0000623 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000624 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000625
Greg Claytonc859e2d2012-02-13 23:10:39 +0000626 virtual int
627 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
628 {
Jason Molendaddf91772013-05-14 04:50:47 +0000629 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000630 }
Greg Claytonc2807462012-10-30 23:57:32 +0000631
632 virtual int
633 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
634 {
635 return -1;
636 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000637
Greg Claytonc859e2d2012-02-13 23:10:39 +0000638 virtual int
639 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
640 {
641 return 0;
642 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000643
Greg Claytonc859e2d2012-02-13 23:10:39 +0000644 virtual int
645 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
646 {
647 return 0;
648 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000649
Greg Claytonc859e2d2012-02-13 23:10:39 +0000650 virtual int
651 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
652 {
653 return 0;
654 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000655
Greg Claytonc2807462012-10-30 23:57:32 +0000656 virtual int
657 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
658 {
659 return -1;
660 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000661};
662
Jason Molendaa3329782014-03-29 18:54:20 +0000663class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
664{
665public:
666 RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
667 RegisterContextDarwin_arm64 (thread, 0)
668 {
669 SetRegisterDataFrom_LC_THREAD (data);
670 }
671
672 virtual void
673 InvalidateAllRegisters ()
674 {
675 // Do nothing... registers are always valid...
676 }
677
678 void
679 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
680 {
681 lldb::offset_t offset = 0;
682 SetError (GPRRegSet, Read, -1);
683 SetError (FPURegSet, Read, -1);
684 SetError (EXCRegSet, Read, -1);
685 bool done = false;
686 while (!done)
687 {
688 int flavor = data.GetU32 (&offset);
689 uint32_t count = data.GetU32 (&offset);
690 lldb::offset_t next_thread_state = offset + (count * 4);
691 switch (flavor)
692 {
693 case GPRRegSet:
694 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
695 if (count >= (33 * 2) + 1)
696 {
697 for (uint32_t i=0; i<33; ++i)
698 gpr.x[i] = data.GetU64(&offset);
699 gpr.cpsr = data.GetU32(&offset);
700 SetError (GPRRegSet, Read, 0);
701 }
702 offset = next_thread_state;
703 break;
704 case FPURegSet:
705 {
706 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
707 const int fpu_reg_buf_size = sizeof (fpu);
708 if (fpu_reg_buf_size == count
709 && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
710 {
711 SetError (FPURegSet, Read, 0);
712 }
713 else
714 {
715 done = true;
716 }
717 }
718 offset = next_thread_state;
719 break;
720 case EXCRegSet:
721 if (count == 4)
722 {
723 exc.far = data.GetU64(&offset);
724 exc.esr = data.GetU32(&offset);
725 exc.exception = data.GetU32(&offset);
726 SetError (EXCRegSet, Read, 0);
727 }
728 offset = next_thread_state;
729 break;
730 default:
731 done = true;
732 break;
733 }
734 }
735 }
Jason Molenda22952582014-11-12 01:11:36 +0000736
737 static size_t
738 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
739 {
740 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
741 if (reg_info == NULL)
742 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
743 if (reg_info)
744 {
745 lldb_private::RegisterValue reg_value;
746 if (reg_ctx->ReadRegister(reg_info, reg_value))
747 {
748 if (reg_info->byte_size >= reg_byte_size)
749 data.Write(reg_value.GetBytes(), reg_byte_size);
750 else
751 {
752 data.Write(reg_value.GetBytes(), reg_info->byte_size);
753 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
754 data.PutChar(0);
755 }
756 return reg_byte_size;
757 }
758 }
759 // Just write zeros if all else fails
760 for (size_t i=0; i<reg_byte_size; ++ i)
761 data.PutChar(0);
762 return reg_byte_size;
763 }
764
765 static bool
766 Create_LC_THREAD (Thread *thread, Stream &data)
767 {
768 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
769 if (reg_ctx_sp)
770 {
771 RegisterContext *reg_ctx = reg_ctx_sp.get();
772
773 data.PutHex32 (GPRRegSet); // Flavor
774 data.PutHex32 (GPRWordCount);
775 WriteRegister (reg_ctx, "x0", NULL, 8, data);
776 WriteRegister (reg_ctx, "x1", NULL, 8, data);
777 WriteRegister (reg_ctx, "x2", NULL, 8, data);
778 WriteRegister (reg_ctx, "x3", NULL, 8, data);
779 WriteRegister (reg_ctx, "x4", NULL, 8, data);
780 WriteRegister (reg_ctx, "x5", NULL, 8, data);
781 WriteRegister (reg_ctx, "x6", NULL, 8, data);
782 WriteRegister (reg_ctx, "x7", NULL, 8, data);
783 WriteRegister (reg_ctx, "x8", NULL, 8, data);
784 WriteRegister (reg_ctx, "x9", NULL, 8, data);
785 WriteRegister (reg_ctx, "x10", NULL, 8, data);
786 WriteRegister (reg_ctx, "x11", NULL, 8, data);
787 WriteRegister (reg_ctx, "x12", NULL, 8, data);
788 WriteRegister (reg_ctx, "x13", NULL, 8, data);
789 WriteRegister (reg_ctx, "x14", NULL, 8, data);
790 WriteRegister (reg_ctx, "x15", NULL, 8, data);
791 WriteRegister (reg_ctx, "x16", NULL, 8, data);
792 WriteRegister (reg_ctx, "x17", NULL, 8, data);
793 WriteRegister (reg_ctx, "x18", NULL, 8, data);
794 WriteRegister (reg_ctx, "x19", NULL, 8, data);
795 WriteRegister (reg_ctx, "x20", NULL, 8, data);
796 WriteRegister (reg_ctx, "x21", NULL, 8, data);
797 WriteRegister (reg_ctx, "x22", NULL, 8, data);
798 WriteRegister (reg_ctx, "x23", NULL, 8, data);
799 WriteRegister (reg_ctx, "x24", NULL, 8, data);
800 WriteRegister (reg_ctx, "x25", NULL, 8, data);
801 WriteRegister (reg_ctx, "x26", NULL, 8, data);
802 WriteRegister (reg_ctx, "x27", NULL, 8, data);
803 WriteRegister (reg_ctx, "x28", NULL, 8, data);
804 WriteRegister (reg_ctx, "fp", NULL, 8, data);
805 WriteRegister (reg_ctx, "lr", NULL, 8, data);
806 WriteRegister (reg_ctx, "sp", NULL, 8, data);
807 WriteRegister (reg_ctx, "pc", NULL, 8, data);
808 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
809
810 // Write out the EXC registers
811// data.PutHex32 (EXCRegSet);
812// data.PutHex32 (EXCWordCount);
813// WriteRegister (reg_ctx, "far", NULL, 8, data);
814// WriteRegister (reg_ctx, "esr", NULL, 4, data);
815// WriteRegister (reg_ctx, "exception", NULL, 4, data);
816 return true;
817 }
818 return false;
819 }
820
Jason Molendaa3329782014-03-29 18:54:20 +0000821protected:
822 virtual int
823 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
824 {
825 return -1;
826 }
827
828 virtual int
829 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
830 {
831 return -1;
832 }
833
834 virtual int
835 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
836 {
837 return -1;
838 }
839
840 virtual int
841 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
842 {
843 return -1;
844 }
845
846 virtual int
847 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
848 {
849 return 0;
850 }
851
852 virtual int
853 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
854 {
855 return 0;
856 }
857
858 virtual int
859 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
860 {
861 return 0;
862 }
863
864 virtual int
865 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
866 {
867 return -1;
868 }
869};
870
Greg Clayton9aae0a12013-05-15 19:52:08 +0000871static uint32_t
872MachHeaderSizeFromMagic(uint32_t magic)
873{
874 switch (magic)
875 {
Charles Davis510938e2013-08-27 05:04:57 +0000876 case MH_MAGIC:
877 case MH_CIGAM:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000878 return sizeof(struct mach_header);
879
Charles Davis510938e2013-08-27 05:04:57 +0000880 case MH_MAGIC_64:
881 case MH_CIGAM_64:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000882 return sizeof(struct mach_header_64);
883 break;
884
885 default:
886 break;
887 }
888 return 0;
889}
890
Greg Claytonded470d2011-03-19 01:12:21 +0000891#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892
893void
894ObjectFileMachO::Initialize()
895{
896 PluginManager::RegisterPlugin (GetPluginNameStatic(),
897 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000898 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000899 CreateMemoryInstance,
Greg Claytona2715cf2014-06-13 00:54:12 +0000900 GetModuleSpecifications,
901 SaveCore);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000902}
903
904void
905ObjectFileMachO::Terminate()
906{
907 PluginManager::UnregisterPlugin (CreateInstance);
908}
909
910
Greg Clayton57abc5d2013-05-10 21:47:16 +0000911lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000912ObjectFileMachO::GetPluginNameStatic()
913{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000914 static ConstString g_name("mach-o");
915 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916}
917
918const char *
919ObjectFileMachO::GetPluginDescriptionStatic()
920{
921 return "Mach-o object file reader (32 and 64 bit)";
922}
923
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924ObjectFile *
Greg Clayton5ce9c562013-02-06 17:22:03 +0000925ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
926 DataBufferSP& data_sp,
927 lldb::offset_t data_offset,
928 const FileSpec* file,
929 lldb::offset_t file_offset,
930 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000932 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000933 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000934 data_sp = file->MemoryMapFileContents(file_offset, length);
935 data_offset = 0;
936 }
937
938 if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
939 {
940 // Update the data to contain the entire file if it doesn't already
941 if (data_sp->GetByteSize() < length)
942 {
943 data_sp = file->MemoryMapFileContents(file_offset, length);
944 data_offset = 0;
945 }
Greg Clayton7b0992d2013-04-18 22:45:39 +0000946 std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000947 if (objfile_ap.get() && objfile_ap->ParseHeader())
948 return objfile_ap.release();
949 }
950 return NULL;
951}
952
Greg Claytonc9660542012-02-05 02:38:54 +0000953ObjectFile *
Jason Molenda4e7511e2013-03-06 23:19:17 +0000954ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
955 DataBufferSP& data_sp,
956 const ProcessSP &process_sp,
Greg Claytonc9660542012-02-05 02:38:54 +0000957 lldb::addr_t header_addr)
958{
959 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
960 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000961 std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonc9660542012-02-05 02:38:54 +0000962 if (objfile_ap.get() && objfile_ap->ParseHeader())
963 return objfile_ap.release();
964 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000965 return NULL;
Greg Claytonc9660542012-02-05 02:38:54 +0000966}
967
Greg Claytonf4d6de62013-04-24 22:29:28 +0000968size_t
969ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
970 lldb::DataBufferSP& data_sp,
971 lldb::offset_t data_offset,
972 lldb::offset_t file_offset,
973 lldb::offset_t length,
974 lldb_private::ModuleSpecList &specs)
975{
976 const size_t initial_count = specs.GetSize();
977
978 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
979 {
980 DataExtractor data;
981 data.SetData(data_sp);
982 llvm::MachO::mach_header header;
983 if (ParseHeader (data, &data_offset, header))
984 {
Jason Molenda48cd3332014-04-22 04:52:30 +0000985 size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
986 if (header_and_load_cmds >= data_sp->GetByteSize())
Greg Claytonf4d6de62013-04-24 22:29:28 +0000987 {
Jason Molenda48cd3332014-04-22 04:52:30 +0000988 data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);
Greg Clayton2540a8a2013-07-12 22:07:46 +0000989 data.SetData(data_sp);
990 data_offset = MachHeaderSizeFromMagic(header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000991 }
992 if (data_sp)
993 {
994 ModuleSpec spec;
995 spec.GetFileSpec() = file;
Greg Clayton7ab7f892014-05-29 21:33:45 +0000996 spec.SetObjectOffset(file_offset);
997
998 if (GetArchitecture (header, data, data_offset, spec.GetArchitecture()))
Jason Molendab000e4d2013-08-27 02:22:06 +0000999 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001000 if (spec.GetArchitecture().IsValid())
1001 {
1002 GetUUID (header, data, data_offset, spec.GetUUID());
1003 specs.Append(spec);
1004 }
Greg Claytonf4d6de62013-04-24 22:29:28 +00001005 }
1006 }
1007 }
1008 }
1009 return specs.GetSize() - initial_count;
1010}
1011
1012
Greg Claytonc9660542012-02-05 02:38:54 +00001013
1014const ConstString &
1015ObjectFileMachO::GetSegmentNameTEXT()
1016{
1017 static ConstString g_segment_name_TEXT ("__TEXT");
1018 return g_segment_name_TEXT;
1019}
1020
1021const ConstString &
1022ObjectFileMachO::GetSegmentNameDATA()
1023{
1024 static ConstString g_segment_name_DATA ("__DATA");
1025 return g_segment_name_DATA;
1026}
1027
1028const ConstString &
1029ObjectFileMachO::GetSegmentNameOBJC()
1030{
1031 static ConstString g_segment_name_OBJC ("__OBJC");
1032 return g_segment_name_OBJC;
1033}
1034
1035const ConstString &
1036ObjectFileMachO::GetSegmentNameLINKEDIT()
1037{
1038 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
1039 return g_section_name_LINKEDIT;
1040}
1041
1042const ConstString &
1043ObjectFileMachO::GetSectionNameEHFrame()
1044{
1045 static ConstString g_section_name_eh_frame ("__eh_frame");
1046 return g_section_name_eh_frame;
1047}
1048
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049bool
Jason Molenda4e7511e2013-03-06 23:19:17 +00001050ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
1051 lldb::addr_t data_offset,
Greg Clayton44435ed2012-01-12 05:25:17 +00001052 lldb::addr_t data_length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053{
Greg Clayton44435ed2012-01-12 05:25:17 +00001054 DataExtractor data;
1055 data.SetData (data_sp, data_offset, data_length);
Greg Claytonc7bece562013-01-25 18:06:21 +00001056 lldb::offset_t offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057 uint32_t magic = data.GetU32(&offset);
1058 return MachHeaderSizeFromMagic(magic) != 0;
1059}
1060
1061
Greg Clayton5ce9c562013-02-06 17:22:03 +00001062ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
1063 DataBufferSP& data_sp,
1064 lldb::offset_t data_offset,
1065 const FileSpec* file,
1066 lldb::offset_t file_offset,
1067 lldb::offset_t length) :
1068 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001069 m_mach_segments(),
1070 m_mach_sections(),
1071 m_entry_point_address(),
1072 m_thread_context_offsets(),
1073 m_thread_context_offsets_valid(false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074{
Greg Clayton72b77eb2011-02-04 21:13:05 +00001075 ::memset (&m_header, 0, sizeof(m_header));
1076 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077}
1078
Greg Claytone72dfb32012-02-24 01:59:29 +00001079ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonc9660542012-02-05 02:38:54 +00001080 lldb::DataBufferSP& header_data_sp,
1081 const lldb::ProcessSP &process_sp,
1082 lldb::addr_t header_addr) :
Greg Claytone72dfb32012-02-24 01:59:29 +00001083 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001084 m_mach_segments(),
1085 m_mach_sections(),
1086 m_entry_point_address(),
1087 m_thread_context_offsets(),
1088 m_thread_context_offsets_valid(false)
Greg Claytonc9660542012-02-05 02:38:54 +00001089{
1090 ::memset (&m_header, 0, sizeof(m_header));
1091 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1092}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093
1094ObjectFileMachO::~ObjectFileMachO()
1095{
1096}
1097
Greg Claytonf4d6de62013-04-24 22:29:28 +00001098bool
1099ObjectFileMachO::ParseHeader (DataExtractor &data,
1100 lldb::offset_t *data_offset_ptr,
1101 llvm::MachO::mach_header &header)
1102{
1103 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1104 // Leave magic in the original byte order
1105 header.magic = data.GetU32(data_offset_ptr);
1106 bool can_parse = false;
1107 bool is_64_bit = false;
1108 switch (header.magic)
1109 {
Charles Davis510938e2013-08-27 05:04:57 +00001110 case MH_MAGIC:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001111 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1112 data.SetAddressByteSize(4);
1113 can_parse = true;
1114 break;
1115
Charles Davis510938e2013-08-27 05:04:57 +00001116 case MH_MAGIC_64:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001117 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1118 data.SetAddressByteSize(8);
1119 can_parse = true;
1120 is_64_bit = true;
1121 break;
1122
Charles Davis510938e2013-08-27 05:04:57 +00001123 case MH_CIGAM:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001124 data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1125 data.SetAddressByteSize(4);
1126 can_parse = true;
1127 break;
1128
Charles Davis510938e2013-08-27 05:04:57 +00001129 case MH_CIGAM_64:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001130 data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1131 data.SetAddressByteSize(8);
1132 is_64_bit = true;
1133 can_parse = true;
1134 break;
1135
1136 default:
1137 break;
1138 }
1139
1140 if (can_parse)
1141 {
1142 data.GetU32(data_offset_ptr, &header.cputype, 6);
1143 if (is_64_bit)
1144 *data_offset_ptr += 4;
1145 return true;
1146 }
1147 else
1148 {
1149 memset(&header, 0, sizeof(header));
1150 }
1151 return false;
1152}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001153
1154bool
1155ObjectFileMachO::ParseHeader ()
1156{
Greg Claytona1743492012-03-13 23:14:29 +00001157 ModuleSP module_sp(GetModule());
1158 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001159 {
Greg Claytona1743492012-03-13 23:14:29 +00001160 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1161 bool can_parse = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00001162 lldb::offset_t offset = 0;
Greg Clayton7fb56d02011-02-01 01:31:41 +00001163 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001164 // Leave magic in the original byte order
1165 m_header.magic = m_data.GetU32(&offset);
1166 switch (m_header.magic)
Greg Claytonc9660542012-02-05 02:38:54 +00001167 {
Charles Davis510938e2013-08-27 05:04:57 +00001168 case MH_MAGIC:
Greg Claytona1743492012-03-13 23:14:29 +00001169 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
1170 m_data.SetAddressByteSize(4);
1171 can_parse = true;
1172 break;
1173
Charles Davis510938e2013-08-27 05:04:57 +00001174 case MH_MAGIC_64:
Greg Claytona1743492012-03-13 23:14:29 +00001175 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
1176 m_data.SetAddressByteSize(8);
1177 can_parse = true;
1178 break;
1179
Charles Davis510938e2013-08-27 05:04:57 +00001180 case MH_CIGAM:
Greg Claytona1743492012-03-13 23:14:29 +00001181 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1182 m_data.SetAddressByteSize(4);
1183 can_parse = true;
1184 break;
1185
Charles Davis510938e2013-08-27 05:04:57 +00001186 case MH_CIGAM_64:
Greg Claytona1743492012-03-13 23:14:29 +00001187 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1188 m_data.SetAddressByteSize(8);
1189 can_parse = true;
1190 break;
1191
1192 default:
1193 break;
Greg Claytonc9660542012-02-05 02:38:54 +00001194 }
Greg Claytona1743492012-03-13 23:14:29 +00001195
1196 if (can_parse)
1197 {
1198 m_data.GetU32(&offset, &m_header.cputype, 6);
1199
Greg Clayton7ab7f892014-05-29 21:33:45 +00001200
1201 ArchSpec mach_arch;
1202
1203 if (GetArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001204 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001205 // Check if the module has a required architecture
1206 const ArchSpec &module_arch = module_sp->GetArchitecture();
1207 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
1208 return false;
1209
1210 if (SetModulesArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001211 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001212 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
1213 if (m_data.GetByteSize() < header_and_lc_size)
Greg Claytona1743492012-03-13 23:14:29 +00001214 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001215 DataBufferSP data_sp;
1216 ProcessSP process_sp (m_process_wp.lock());
1217 if (process_sp)
1218 {
1219 data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
1220 }
1221 else
1222 {
1223 // Read in all only the load command data from the file on disk
1224 data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
1225 if (data_sp->GetByteSize() != header_and_lc_size)
1226 return false;
1227 }
1228 if (data_sp)
1229 m_data.SetData (data_sp);
Greg Claytona1743492012-03-13 23:14:29 +00001230 }
Greg Claytona1743492012-03-13 23:14:29 +00001231 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00001232 return true;
Greg Claytona1743492012-03-13 23:14:29 +00001233 }
Greg Claytona1743492012-03-13 23:14:29 +00001234 }
1235 else
1236 {
1237 memset(&m_header, 0, sizeof(struct mach_header));
1238 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001239 }
1240 return false;
1241}
1242
1243
1244ByteOrder
1245ObjectFileMachO::GetByteOrder () const
1246{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001247 return m_data.GetByteOrder ();
1248}
1249
Jim Ingham5aee1622010-08-09 23:31:02 +00001250bool
1251ObjectFileMachO::IsExecutable() const
1252{
Charles Davis510938e2013-08-27 05:04:57 +00001253 return m_header.filetype == MH_EXECUTE;
Jim Ingham5aee1622010-08-09 23:31:02 +00001254}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255
Greg Claytonc7bece562013-01-25 18:06:21 +00001256uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001257ObjectFileMachO::GetAddressByteSize () const
1258{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259 return m_data.GetAddressByteSize ();
1260}
1261
Greg Claytone0d378b2011-03-24 21:19:54 +00001262AddressClass
Greg Claytonded470d2011-03-19 01:12:21 +00001263ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
1264{
1265 Symtab *symtab = GetSymtab();
1266 if (symtab)
1267 {
1268 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
1269 if (symbol)
1270 {
Greg Claytone7612132012-03-07 21:03:09 +00001271 if (symbol->ValueIsAddress())
Greg Claytonded470d2011-03-19 01:12:21 +00001272 {
Greg Claytone7612132012-03-07 21:03:09 +00001273 SectionSP section_sp (symbol->GetAddress().GetSection());
Greg Claytone72dfb32012-02-24 01:59:29 +00001274 if (section_sp)
Greg Claytonded470d2011-03-19 01:12:21 +00001275 {
Charles Davis510938e2013-08-27 05:04:57 +00001276 const lldb::SectionType section_type = section_sp->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001277 switch (section_type)
1278 {
1279 case eSectionTypeInvalid: return eAddressClassUnknown;
1280 case eSectionTypeCode:
Charles Davis510938e2013-08-27 05:04:57 +00001281 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001282 {
1283 // For ARM we have a bit in the n_desc field of the symbol
1284 // that tells us ARM/Thumb which is bit 0x0008.
1285 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1286 return eAddressClassCodeAlternateISA;
1287 }
1288 return eAddressClassCode;
1289
1290 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton5009f9d2011-10-27 17:55:14 +00001291 case eSectionTypeData:
1292 case eSectionTypeDataCString:
1293 case eSectionTypeDataCStringPointers:
1294 case eSectionTypeDataSymbolAddress:
1295 case eSectionTypeData4:
1296 case eSectionTypeData8:
1297 case eSectionTypeData16:
1298 case eSectionTypeDataPointers:
1299 case eSectionTypeZeroFill:
1300 case eSectionTypeDataObjCMessageRefs:
1301 case eSectionTypeDataObjCCFStrings:
1302 return eAddressClassData;
1303 case eSectionTypeDebug:
1304 case eSectionTypeDWARFDebugAbbrev:
1305 case eSectionTypeDWARFDebugAranges:
1306 case eSectionTypeDWARFDebugFrame:
1307 case eSectionTypeDWARFDebugInfo:
1308 case eSectionTypeDWARFDebugLine:
1309 case eSectionTypeDWARFDebugLoc:
1310 case eSectionTypeDWARFDebugMacInfo:
1311 case eSectionTypeDWARFDebugPubNames:
1312 case eSectionTypeDWARFDebugPubTypes:
1313 case eSectionTypeDWARFDebugRanges:
1314 case eSectionTypeDWARFDebugStr:
1315 case eSectionTypeDWARFAppleNames:
1316 case eSectionTypeDWARFAppleTypes:
1317 case eSectionTypeDWARFAppleNamespaces:
1318 case eSectionTypeDWARFAppleObjC:
1319 return eAddressClassDebug;
Greg Claytonded470d2011-03-19 01:12:21 +00001320 case eSectionTypeEHFrame: return eAddressClassRuntime;
Michael Sartaina7499c92013-07-01 19:45:50 +00001321 case eSectionTypeELFSymbolTable:
1322 case eSectionTypeELFDynamicSymbols:
1323 case eSectionTypeELFRelocationEntries:
1324 case eSectionTypeELFDynamicLinkInfo:
Greg Claytonded470d2011-03-19 01:12:21 +00001325 case eSectionTypeOther: return eAddressClassUnknown;
1326 }
1327 }
1328 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001329
Greg Claytone0d378b2011-03-24 21:19:54 +00001330 const SymbolType symbol_type = symbol->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001331 switch (symbol_type)
1332 {
1333 case eSymbolTypeAny: return eAddressClassUnknown;
1334 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Jason Molenda4e7511e2013-03-06 23:19:17 +00001335
Greg Claytonded470d2011-03-19 01:12:21 +00001336 case eSymbolTypeCode:
1337 case eSymbolTypeTrampoline:
Greg Clayton059f7242013-02-27 21:16:04 +00001338 case eSymbolTypeResolver:
Charles Davis510938e2013-08-27 05:04:57 +00001339 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001340 {
1341 // For ARM we have a bit in the n_desc field of the symbol
1342 // that tells us ARM/Thumb which is bit 0x0008.
1343 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1344 return eAddressClassCodeAlternateISA;
1345 }
1346 return eAddressClassCode;
1347
1348 case eSymbolTypeData: return eAddressClassData;
1349 case eSymbolTypeRuntime: return eAddressClassRuntime;
1350 case eSymbolTypeException: return eAddressClassRuntime;
1351 case eSymbolTypeSourceFile: return eAddressClassDebug;
1352 case eSymbolTypeHeaderFile: return eAddressClassDebug;
1353 case eSymbolTypeObjectFile: return eAddressClassDebug;
1354 case eSymbolTypeCommonBlock: return eAddressClassDebug;
1355 case eSymbolTypeBlock: return eAddressClassDebug;
1356 case eSymbolTypeLocal: return eAddressClassData;
1357 case eSymbolTypeParam: return eAddressClassData;
1358 case eSymbolTypeVariable: return eAddressClassData;
1359 case eSymbolTypeVariableType: return eAddressClassDebug;
1360 case eSymbolTypeLineEntry: return eAddressClassDebug;
1361 case eSymbolTypeLineHeader: return eAddressClassDebug;
1362 case eSymbolTypeScopeBegin: return eAddressClassDebug;
1363 case eSymbolTypeScopeEnd: return eAddressClassDebug;
1364 case eSymbolTypeAdditional: return eAddressClassUnknown;
1365 case eSymbolTypeCompiler: return eAddressClassDebug;
1366 case eSymbolTypeInstrumentation:return eAddressClassDebug;
1367 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton456809c2011-12-03 02:30:59 +00001368 case eSymbolTypeObjCClass: return eAddressClassRuntime;
1369 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
1370 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Clayton9191db42013-10-21 18:40:51 +00001371 case eSymbolTypeReExported: return eAddressClassRuntime;
Greg Claytonded470d2011-03-19 01:12:21 +00001372 }
1373 }
1374 }
1375 return eAddressClassUnknown;
1376}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001377
1378Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001379ObjectFileMachO::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380{
Greg Claytona1743492012-03-13 23:14:29 +00001381 ModuleSP module_sp(GetModule());
1382 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001383 {
Greg Claytona1743492012-03-13 23:14:29 +00001384 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1385 if (m_symtab_ap.get() == NULL)
1386 {
1387 m_symtab_ap.reset(new Symtab(this));
1388 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
Greg Clayton3046e662013-07-10 01:23:25 +00001389 ParseSymtab ();
Greg Claytona1743492012-03-13 23:14:29 +00001390 m_symtab_ap->Finalize ();
1391 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001392 }
1393 return m_symtab_ap.get();
1394}
1395
Greg Clayton3046e662013-07-10 01:23:25 +00001396bool
1397ObjectFileMachO::IsStripped ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001398{
Greg Clayton3046e662013-07-10 01:23:25 +00001399 if (m_dysymtab.cmd == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001400 {
Greg Clayton3046e662013-07-10 01:23:25 +00001401 ModuleSP module_sp(GetModule());
1402 if (module_sp)
Greg Claytona1743492012-03-13 23:14:29 +00001403 {
Greg Clayton3046e662013-07-10 01:23:25 +00001404 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1405 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton4d78c402012-05-25 18:09:55 +00001406 {
Greg Clayton3046e662013-07-10 01:23:25 +00001407 const lldb::offset_t load_cmd_offset = offset;
1408
1409 load_command lc;
1410 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
1411 break;
Charles Davis510938e2013-08-27 05:04:57 +00001412 if (lc.cmd == LC_DYSYMTAB)
Greg Clayton4d78c402012-05-25 18:09:55 +00001413 {
Greg Clayton3046e662013-07-10 01:23:25 +00001414 m_dysymtab.cmd = lc.cmd;
1415 m_dysymtab.cmdsize = lc.cmdsize;
1416 if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
1417 {
1418 // Clear m_dysymtab if we were unable to read all items from the load command
1419 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1420 }
Greg Clayton4d78c402012-05-25 18:09:55 +00001421 }
Greg Clayton3046e662013-07-10 01:23:25 +00001422 offset = load_cmd_offset + lc.cmdsize;
Greg Clayton4d78c402012-05-25 18:09:55 +00001423 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001424 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001425 }
Greg Clayton3046e662013-07-10 01:23:25 +00001426 if (m_dysymtab.cmd)
Greg Clayton93e28612013-10-11 22:03:48 +00001427 return m_dysymtab.nlocalsym <= 1;
Greg Clayton3046e662013-07-10 01:23:25 +00001428 return false;
1429}
Greg Clayton1eac0c72012-04-24 03:06:13 +00001430
Greg Clayton3046e662013-07-10 01:23:25 +00001431void
1432ObjectFileMachO::CreateSections (SectionList &unified_section_list)
1433{
1434 if (!m_sections_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001435 {
Greg Clayton3046e662013-07-10 01:23:25 +00001436 m_sections_ap.reset(new SectionList());
1437
Charles Davis510938e2013-08-27 05:04:57 +00001438 const bool is_dsym = (m_header.filetype == MH_DSYM);
Greg Clayton3046e662013-07-10 01:23:25 +00001439 lldb::user_id_t segID = 0;
1440 lldb::user_id_t sectID = 0;
1441 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1442 uint32_t i;
1443 const bool is_core = GetType() == eTypeCoreFile;
1444 //bool dump_sections = false;
1445 ModuleSP module_sp (GetModule());
1446 // First look up any LC_ENCRYPTION_INFO load commands
1447 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
1448 EncryptedFileRanges encrypted_file_ranges;
1449 encryption_info_command encryption_cmd;
1450 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001451 {
Greg Clayton3046e662013-07-10 01:23:25 +00001452 const lldb::offset_t load_cmd_offset = offset;
1453 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
1454 break;
1455
Charles Davis510938e2013-08-27 05:04:57 +00001456 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001457 {
Greg Clayton3046e662013-07-10 01:23:25 +00001458 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001459 {
Greg Clayton3046e662013-07-10 01:23:25 +00001460 if (encryption_cmd.cryptid != 0)
Greg Claytond37d6922013-04-16 16:51:19 +00001461 {
Greg Clayton3046e662013-07-10 01:23:25 +00001462 EncryptedFileRanges::Entry entry;
1463 entry.SetRangeBase(encryption_cmd.cryptoff);
1464 entry.SetByteSize(encryption_cmd.cryptsize);
1465 encrypted_file_ranges.Append(entry);
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001466 }
1467 }
Greg Clayton3046e662013-07-10 01:23:25 +00001468 }
1469 offset = load_cmd_offset + encryption_cmd.cmdsize;
1470 }
1471
Jason Molenda05a09c62014-08-22 02:46:46 +00001472 bool section_file_addresses_changed = false;
1473
Greg Clayton3046e662013-07-10 01:23:25 +00001474 offset = MachHeaderSizeFromMagic(m_header.magic);
1475
1476 struct segment_command_64 load_cmd;
1477 for (i=0; i<m_header.ncmds; ++i)
1478 {
1479 const lldb::offset_t load_cmd_offset = offset;
1480 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1481 break;
1482
Charles Davis510938e2013-08-27 05:04:57 +00001483 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
Greg Clayton3046e662013-07-10 01:23:25 +00001484 {
1485 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001486 {
Greg Clayton3046e662013-07-10 01:23:25 +00001487 bool add_section = true;
1488 bool add_to_unified = true;
1489 ConstString const_segname (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
Jason Molenda4e7511e2013-03-06 23:19:17 +00001490
Greg Clayton3046e662013-07-10 01:23:25 +00001491 SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
1492 if (is_dsym && unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001493 {
Greg Clayton3046e662013-07-10 01:23:25 +00001494 if (const_segname == GetSegmentNameLINKEDIT())
1495 {
1496 // We need to keep the __LINKEDIT segment private to this object file only
1497 add_to_unified = false;
1498 }
1499 else
1500 {
1501 // This is the dSYM file and this section has already been created by
1502 // the object file, no need to create it.
1503 add_section = false;
1504 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001505 }
Greg Clayton3046e662013-07-10 01:23:25 +00001506 load_cmd.vmaddr = m_data.GetAddress(&offset);
1507 load_cmd.vmsize = m_data.GetAddress(&offset);
1508 load_cmd.fileoff = m_data.GetAddress(&offset);
1509 load_cmd.filesize = m_data.GetAddress(&offset);
1510 if (m_length != 0 && load_cmd.filesize != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001511 {
Greg Clayton3046e662013-07-10 01:23:25 +00001512 if (load_cmd.fileoff > m_length)
1513 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001514 // We have a load command that says it extends past the end of the file. This is likely
Greg Clayton3046e662013-07-10 01:23:25 +00001515 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001516 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001517 // is null out the SectionList vector and if a process has been set up, dump a message
1518 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001519 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001520 module_sp->ReportWarning("load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), ignoring this section",
Jason Molenda20eb31b2013-08-16 03:20:42 +00001521 i,
1522 lc_segment_name,
1523 load_cmd.fileoff,
1524 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001525
1526 load_cmd.fileoff = 0;
1527 load_cmd.filesize = 0;
1528 }
1529
1530 if (load_cmd.fileoff + load_cmd.filesize > m_length)
1531 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001532 // We have a load command that says it extends past the end of the file. This is likely
Greg Clayton3046e662013-07-10 01:23:25 +00001533 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001534 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001535 // is null out the SectionList vector and if a process has been set up, dump a message
1536 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001537 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001538 GetModule()->ReportWarning("load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated to match",
Charles Davis510938e2013-08-27 05:04:57 +00001539 i,
1540 lc_segment_name,
1541 load_cmd.fileoff + load_cmd.filesize,
1542 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001543
1544 // Tuncase the length
1545 load_cmd.filesize = m_length - load_cmd.fileoff;
1546 }
1547 }
1548 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
1549 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001550
Charles Davis510938e2013-08-27 05:04:57 +00001551 const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001552
Greg Clayton3046e662013-07-10 01:23:25 +00001553 // Keep a list of mach segments around in case we need to
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001554 // get at data that isn't stored in the abstracted Sections.
Greg Clayton3046e662013-07-10 01:23:25 +00001555 m_mach_segments.push_back (load_cmd);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001556
Greg Clayton3046e662013-07-10 01:23:25 +00001557 // Use a segment ID of the segment index shifted left by 8 so they
1558 // never conflict with any of the sections.
1559 SectionSP segment_sp;
1560 if (add_section && (const_segname || is_core))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001561 {
Greg Clayton3046e662013-07-10 01:23:25 +00001562 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
1563 this, // Object file to which this sections belongs
1564 ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
1565 const_segname, // Name of this section
1566 eSectionTypeContainer, // This section is a container of other sections.
1567 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
1568 load_cmd.vmsize, // VM size in bytes of this section
1569 load_cmd.fileoff, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001570 load_cmd.filesize, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001571 0, // Segments have no alignment information
Greg Clayton3046e662013-07-10 01:23:25 +00001572 load_cmd.flags)); // Flags for this section
Greg Clayton8d38ac42010-06-28 23:51:11 +00001573
Greg Clayton3046e662013-07-10 01:23:25 +00001574 segment_sp->SetIsEncrypted (segment_is_encrypted);
1575 m_sections_ap->AddSection(segment_sp);
1576 if (add_to_unified)
1577 unified_section_list.AddSection(segment_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001578 }
Greg Clayton3046e662013-07-10 01:23:25 +00001579 else if (unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001580 {
Jason Molenda20eb31b2013-08-16 03:20:42 +00001581 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr)
1582 {
1583 // Check to see if the module was read from memory?
1584 if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid())
1585 {
1586 // We have a module that is in memory and needs to have its
1587 // file address adjusted. We need to do this because when we
1588 // load a file from memory, its addresses will be slid already,
1589 // yet the addresses in the new symbol file will still be unslid.
1590 // Since everything is stored as section offset, this shouldn't
1591 // cause any problems.
Jason Molenda5894a732013-08-17 03:39:52 +00001592
1593 // Make sure we've parsed the symbol table from the
1594 // ObjectFile before we go around changing its Sections.
1595 module_sp->GetObjectFile()->GetSymtab();
1596 // eh_frame would present the same problems but we parse that on
1597 // a per-function basis as-needed so it's more difficult to
1598 // remove its use of the Sections. Realistically, the environments
1599 // where this code path will be taken will not have eh_frame sections.
1600
Jason Molenda20eb31b2013-08-16 03:20:42 +00001601 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
Jason Molenda05a09c62014-08-22 02:46:46 +00001602
1603 // Notify the module that the section addresses have been changed once
1604 // we're done so any file-address caches can be updated.
1605 section_file_addresses_changed = true;
Jason Molenda20eb31b2013-08-16 03:20:42 +00001606 }
1607 }
Greg Clayton3046e662013-07-10 01:23:25 +00001608 m_sections_ap->AddSection(unified_section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001609 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001610
Greg Clayton3046e662013-07-10 01:23:25 +00001611 struct section_64 sect64;
1612 ::memset (&sect64, 0, sizeof(sect64));
1613 // Push a section into our mach sections for the section at
Charles Davis510938e2013-08-27 05:04:57 +00001614 // index zero (NO_SECT) if we don't have any mach sections yet...
Greg Clayton3046e662013-07-10 01:23:25 +00001615 if (m_mach_sections.empty())
1616 m_mach_sections.push_back(sect64);
1617 uint32_t segment_sect_idx;
1618 const lldb::user_id_t first_segment_sectID = sectID + 1;
1619
1620
Charles Davis510938e2013-08-27 05:04:57 +00001621 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
Greg Clayton3046e662013-07-10 01:23:25 +00001622 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001623 {
Greg Clayton3046e662013-07-10 01:23:25 +00001624 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
Greg Clayton89411422010-10-08 00:21:05 +00001625 break;
Greg Clayton3046e662013-07-10 01:23:25 +00001626 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
1627 break;
1628 sect64.addr = m_data.GetAddress(&offset);
1629 sect64.size = m_data.GetAddress(&offset);
1630
1631 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
1632 break;
1633
1634 // Keep a list of mach sections around in case we need to
1635 // get at data that isn't stored in the abstracted Sections.
1636 m_mach_sections.push_back (sect64);
1637
1638 if (add_section)
1639 {
1640 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
1641 if (!const_segname)
1642 {
1643 // We have a segment with no name so we need to conjure up
1644 // segments that correspond to the section's segname if there
1645 // isn't already such a section. If there is such a section,
1646 // we resize the section so that it spans all sections.
1647 // We also mark these sections as fake so address matches don't
1648 // hit if they land in the gaps between the child sections.
1649 const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
1650 segment_sp = unified_section_list.FindSectionByName (const_segname);
1651 if (segment_sp.get())
1652 {
1653 Section *segment = segment_sp.get();
1654 // Grow the section size as needed.
1655 const lldb::addr_t sect64_min_addr = sect64.addr;
1656 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1657 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
1658 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
1659 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
1660 if (sect64_min_addr >= curr_seg_min_addr)
1661 {
1662 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
1663 // Only grow the section size if needed
1664 if (new_seg_byte_size > curr_seg_byte_size)
1665 segment->SetByteSize (new_seg_byte_size);
1666 }
1667 else
1668 {
1669 // We need to change the base address of the segment and
1670 // adjust the child section offsets for all existing children.
1671 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
1672 segment->Slide(slide_amount, false);
1673 segment->GetChildren().Slide(-slide_amount, false);
1674 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
1675 }
1676
1677 // Grow the section size as needed.
1678 if (sect64.offset)
1679 {
1680 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
1681 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
1682
1683 const lldb::addr_t section_min_file_offset = sect64.offset;
1684 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
1685 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
1686 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
1687 segment->SetFileOffset (new_file_offset);
1688 segment->SetFileSize (new_file_size);
1689 }
1690 }
1691 else
1692 {
1693 // Create a fake section for the section's named segment
1694 segment_sp.reset(new Section (segment_sp, // Parent section
1695 module_sp, // Module to which this section belongs
1696 this, // Object file to which this section belongs
1697 ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
1698 const_segname, // Name of this section
1699 eSectionTypeContainer, // This section is a container of other sections.
1700 sect64.addr, // File VM address == addresses as they are found in the object file
1701 sect64.size, // VM size in bytes of this section
1702 sect64.offset, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001703 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001704 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001705 load_cmd.flags)); // Flags for this section
1706 segment_sp->SetIsFake(true);
1707
1708 m_sections_ap->AddSection(segment_sp);
1709 if (add_to_unified)
1710 unified_section_list.AddSection(segment_sp);
1711 segment_sp->SetIsEncrypted (segment_is_encrypted);
1712 }
1713 }
1714 assert (segment_sp.get());
1715
Charles Davis510938e2013-08-27 05:04:57 +00001716 lldb::SectionType sect_type = eSectionTypeOther;
Greg Clayton3046e662013-07-10 01:23:25 +00001717
Greg Clayton38f9cc42014-06-16 22:53:16 +00001718 if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1719 sect_type = eSectionTypeCode;
1720 else
Greg Clayton3046e662013-07-10 01:23:25 +00001721 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001722 uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
1723 static ConstString g_sect_name_objc_data ("__objc_data");
1724 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
1725 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
1726 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
1727 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
1728 static ConstString g_sect_name_objc_const ("__objc_const");
1729 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
1730 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton3046e662013-07-10 01:23:25 +00001731
Greg Clayton38f9cc42014-06-16 22:53:16 +00001732 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
1733 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
1734 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
1735 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
1736 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
1737 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
1738 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
1739 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
1740 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
1741 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
1742 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
1743 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
1744 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
1745 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
1746 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
1747 static ConstString g_sect_name_eh_frame ("__eh_frame");
1748 static ConstString g_sect_name_text ("__text");
1749 static ConstString g_sect_name_data ("__data");
1750
1751
1752 if (section_name == g_sect_name_dwarf_debug_abbrev)
1753 sect_type = eSectionTypeDWARFDebugAbbrev;
1754 else if (section_name == g_sect_name_dwarf_debug_aranges)
1755 sect_type = eSectionTypeDWARFDebugAranges;
1756 else if (section_name == g_sect_name_dwarf_debug_frame)
1757 sect_type = eSectionTypeDWARFDebugFrame;
1758 else if (section_name == g_sect_name_dwarf_debug_info)
1759 sect_type = eSectionTypeDWARFDebugInfo;
1760 else if (section_name == g_sect_name_dwarf_debug_line)
1761 sect_type = eSectionTypeDWARFDebugLine;
1762 else if (section_name == g_sect_name_dwarf_debug_loc)
1763 sect_type = eSectionTypeDWARFDebugLoc;
1764 else if (section_name == g_sect_name_dwarf_debug_macinfo)
1765 sect_type = eSectionTypeDWARFDebugMacInfo;
1766 else if (section_name == g_sect_name_dwarf_debug_pubnames)
1767 sect_type = eSectionTypeDWARFDebugPubNames;
1768 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
1769 sect_type = eSectionTypeDWARFDebugPubTypes;
1770 else if (section_name == g_sect_name_dwarf_debug_ranges)
1771 sect_type = eSectionTypeDWARFDebugRanges;
1772 else if (section_name == g_sect_name_dwarf_debug_str)
1773 sect_type = eSectionTypeDWARFDebugStr;
1774 else if (section_name == g_sect_name_dwarf_apple_names)
1775 sect_type = eSectionTypeDWARFAppleNames;
1776 else if (section_name == g_sect_name_dwarf_apple_types)
1777 sect_type = eSectionTypeDWARFAppleTypes;
1778 else if (section_name == g_sect_name_dwarf_apple_namespaces)
1779 sect_type = eSectionTypeDWARFAppleNamespaces;
1780 else if (section_name == g_sect_name_dwarf_apple_objc)
1781 sect_type = eSectionTypeDWARFAppleObjC;
1782 else if (section_name == g_sect_name_objc_selrefs)
1783 sect_type = eSectionTypeDataCStringPointers;
1784 else if (section_name == g_sect_name_objc_msgrefs)
1785 sect_type = eSectionTypeDataObjCMessageRefs;
1786 else if (section_name == g_sect_name_eh_frame)
1787 sect_type = eSectionTypeEHFrame;
1788 else if (section_name == g_sect_name_cfstring)
1789 sect_type = eSectionTypeDataObjCCFStrings;
1790 else if (section_name == g_sect_name_objc_data ||
1791 section_name == g_sect_name_objc_classrefs ||
1792 section_name == g_sect_name_objc_superrefs ||
1793 section_name == g_sect_name_objc_const ||
1794 section_name == g_sect_name_objc_classlist)
Greg Clayton3046e662013-07-10 01:23:25 +00001795 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001796 sect_type = eSectionTypeDataPointers;
1797 }
1798
1799 if (sect_type == eSectionTypeOther)
1800 {
1801 switch (mach_sect_type)
1802 {
1803 // TODO: categorize sections by other flags for regular sections
1804 case S_REGULAR:
1805 if (section_name == g_sect_name_text)
1806 sect_type = eSectionTypeCode;
1807 else if (section_name == g_sect_name_data)
1808 sect_type = eSectionTypeData;
1809 else
1810 sect_type = eSectionTypeOther;
1811 break;
1812 case S_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1813 case S_CSTRING_LITERALS: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1814 case S_4BYTE_LITERALS: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1815 case S_8BYTE_LITERALS: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1816 case S_LITERAL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1817 case S_NON_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1818 case S_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1819 case S_SYMBOL_STUBS: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1820 case S_MOD_INIT_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1821 case S_MOD_TERM_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1822 case S_COALESCED: sect_type = eSectionTypeOther; break;
1823 case S_GB_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1824 case S_INTERPOSING: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1825 case S_16BYTE_LITERALS: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1826 case S_DTRACE_DOF: sect_type = eSectionTypeDebug; break;
1827 case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break;
1828 default: break;
1829 }
Greg Clayton3046e662013-07-10 01:23:25 +00001830 }
1831 }
1832
1833 SectionSP section_sp(new Section (segment_sp,
1834 module_sp,
1835 this,
1836 ++sectID,
1837 section_name,
1838 sect_type,
1839 sect64.addr - segment_sp->GetFileAddress(),
1840 sect64.size,
1841 sect64.offset,
1842 sect64.offset == 0 ? 0 : sect64.size,
Greg Clayton48672af2014-06-24 22:22:43 +00001843 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001844 sect64.flags));
1845 // Set the section to be encrypted to match the segment
1846
1847 bool section_is_encrypted = false;
1848 if (!segment_is_encrypted && load_cmd.filesize != 0)
1849 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
1850
1851 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
1852 segment_sp->GetChildren().AddSection(section_sp);
1853
1854 if (segment_sp->IsFake())
1855 {
1856 segment_sp.reset();
1857 const_segname.Clear();
1858 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001859 }
1860 }
Greg Clayton3046e662013-07-10 01:23:25 +00001861 if (segment_sp && is_dsym)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001862 {
Greg Clayton3046e662013-07-10 01:23:25 +00001863 if (first_segment_sectID <= sectID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001864 {
Greg Clayton3046e662013-07-10 01:23:25 +00001865 lldb::user_id_t sect_uid;
1866 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001867 {
Greg Clayton3046e662013-07-10 01:23:25 +00001868 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1869 SectionSP next_section_sp;
1870 if (sect_uid + 1 <= sectID)
1871 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1872
1873 if (curr_section_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001874 {
Greg Clayton3046e662013-07-10 01:23:25 +00001875 if (curr_section_sp->GetByteSize() == 0)
1876 {
1877 if (next_section_sp.get() != NULL)
1878 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1879 else
1880 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1881 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001882 }
1883 }
1884 }
1885 }
1886 }
1887 }
1888 }
Charles Davis510938e2013-08-27 05:04:57 +00001889 else if (load_cmd.cmd == LC_DYSYMTAB)
Greg Clayton3046e662013-07-10 01:23:25 +00001890 {
1891 m_dysymtab.cmd = load_cmd.cmd;
1892 m_dysymtab.cmdsize = load_cmd.cmdsize;
1893 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1894 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001895
Greg Clayton3046e662013-07-10 01:23:25 +00001896 offset = load_cmd_offset + load_cmd.cmdsize;
1897 }
Jason Molenda05a09c62014-08-22 02:46:46 +00001898
1899
1900 if (section_file_addresses_changed && module_sp.get())
1901 {
1902 module_sp->SectionFileAddressesChanged();
1903 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001904 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001905}
1906
1907class MachSymtabSectionInfo
1908{
1909public:
1910
1911 MachSymtabSectionInfo (SectionList *section_list) :
1912 m_section_list (section_list),
1913 m_section_infos()
1914 {
1915 // Get the number of sections down to a depth of 1 to include
1916 // all segments and their sections, but no other sections that
1917 // may be added for debug map or
1918 m_section_infos.resize(section_list->GetNumSections(1));
1919 }
1920
1921
Greg Claytone72dfb32012-02-24 01:59:29 +00001922 SectionSP
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001923 GetSection (uint8_t n_sect, addr_t file_addr)
1924 {
1925 if (n_sect == 0)
Greg Claytone72dfb32012-02-24 01:59:29 +00001926 return SectionSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001927 if (n_sect < m_section_infos.size())
1928 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001929 if (!m_section_infos[n_sect].section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001930 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001931 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1932 m_section_infos[n_sect].section_sp = section_sp;
Sean Callanan9a028512012-08-09 00:50:26 +00001933 if (section_sp)
Greg Claytondda0d122011-07-10 17:32:33 +00001934 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001935 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1936 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Claytondda0d122011-07-10 17:32:33 +00001937 }
1938 else
1939 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00001940 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Claytondda0d122011-07-10 17:32:33 +00001941 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001942 }
1943 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton8f258512011-08-26 20:01:35 +00001944 {
1945 // Symbol is in section.
Greg Claytone72dfb32012-02-24 01:59:29 +00001946 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001947 }
1948 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1949 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1950 {
1951 // Symbol is in section with zero size, but has the same start
1952 // address as the section. This can happen with linker symbols
1953 // (symbols that start with the letter 'l' or 'L'.
Greg Claytone72dfb32012-02-24 01:59:29 +00001954 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001955 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001956 }
Greg Claytone72dfb32012-02-24 01:59:29 +00001957 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001958 }
1959
1960protected:
1961 struct SectionInfo
1962 {
1963 SectionInfo () :
1964 vm_range(),
Greg Claytone72dfb32012-02-24 01:59:29 +00001965 section_sp ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001966 {
1967 }
1968
1969 VMRange vm_range;
Greg Claytone72dfb32012-02-24 01:59:29 +00001970 SectionSP section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001971 };
1972 SectionList *m_section_list;
1973 std::vector<SectionInfo> m_section_infos;
1974};
1975
Greg Clayton9191db42013-10-21 18:40:51 +00001976struct TrieEntry
1977{
1978 TrieEntry () :
1979 name(),
1980 address(LLDB_INVALID_ADDRESS),
1981 flags (0),
1982 other(0),
1983 import_name()
1984 {
1985 }
1986
1987 void
1988 Clear ()
1989 {
1990 name.Clear();
1991 address = LLDB_INVALID_ADDRESS;
1992 flags = 0;
1993 other = 0;
1994 import_name.Clear();
1995 }
1996
1997 void
1998 Dump () const
1999 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002000 printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2001 static_cast<unsigned long long>(address),
2002 static_cast<unsigned long long>(flags),
2003 static_cast<unsigned long long>(other), name.GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +00002004 if (import_name)
2005 printf (" -> \"%s\"\n", import_name.GetCString());
2006 else
2007 printf ("\n");
2008 }
2009 ConstString name;
2010 uint64_t address;
2011 uint64_t flags;
2012 uint64_t other;
2013 ConstString import_name;
2014};
2015
2016struct TrieEntryWithOffset
2017{
2018 lldb::offset_t nodeOffset;
2019 TrieEntry entry;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002020
Greg Clayton9191db42013-10-21 18:40:51 +00002021 TrieEntryWithOffset (lldb::offset_t offset) :
2022 nodeOffset (offset),
2023 entry()
2024 {
2025 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002026
Greg Clayton9191db42013-10-21 18:40:51 +00002027 void
2028 Dump (uint32_t idx) const
2029 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002030 printf ("[%3u] 0x%16.16llx: ", idx,
2031 static_cast<unsigned long long>(nodeOffset));
Greg Clayton9191db42013-10-21 18:40:51 +00002032 entry.Dump();
2033 }
2034
2035 bool
2036 operator<(const TrieEntryWithOffset& other) const
2037 {
2038 return ( nodeOffset < other.nodeOffset );
2039 }
2040};
2041
2042static void
2043ParseTrieEntries (DataExtractor &data,
2044 lldb::offset_t offset,
2045 std::vector<llvm::StringRef> &nameSlices,
2046 std::set<lldb::addr_t> &resolver_addresses,
2047 std::vector<TrieEntryWithOffset>& output)
2048{
2049 if (!data.ValidOffset(offset))
2050 return;
2051
2052 const uint64_t terminalSize = data.GetULEB128(&offset);
2053 lldb::offset_t children_offset = offset + terminalSize;
2054 if ( terminalSize != 0 ) {
2055 TrieEntryWithOffset e (offset);
2056 e.entry.flags = data.GetULEB128(&offset);
2057 const char *import_name = NULL;
2058 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
2059 e.entry.address = 0;
2060 e.entry.other = data.GetULEB128(&offset); // dylib ordinal
2061 import_name = data.GetCStr(&offset);
2062 }
2063 else {
2064 e.entry.address = data.GetULEB128(&offset);
2065 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
2066 {
Jim Inghamea3ac272014-01-10 22:55:37 +00002067 //resolver_addresses.insert(e.entry.address);
Greg Clayton9191db42013-10-21 18:40:51 +00002068 e.entry.other = data.GetULEB128(&offset);
Jim Inghamea3ac272014-01-10 22:55:37 +00002069 resolver_addresses.insert(e.entry.other);
Greg Clayton9191db42013-10-21 18:40:51 +00002070 }
2071 else
2072 e.entry.other = 0;
2073 }
2074 // Only add symbols that are reexport symbols with a valid import name
2075 if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
2076 {
2077 std::string name;
2078 if (!nameSlices.empty())
2079 {
2080 for (auto name_slice: nameSlices)
2081 name.append(name_slice.data(), name_slice.size());
2082 }
2083 if (name.size() > 1)
2084 {
2085 // Skip the leading '_'
2086 e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
2087 }
2088 if (import_name)
2089 {
2090 // Skip the leading '_'
2091 e.entry.import_name.SetCString(import_name+1);
2092 }
2093 output.push_back(e);
2094 }
2095 }
2096
2097 const uint8_t childrenCount = data.GetU8(&children_offset);
2098 for (uint8_t i=0; i < childrenCount; ++i) {
2099 nameSlices.push_back(data.GetCStr(&children_offset));
2100 lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
2101 if (childNodeOffset)
2102 {
2103 ParseTrieEntries(data,
2104 childNodeOffset,
2105 nameSlices,
2106 resolver_addresses,
2107 output);
2108 }
2109 nameSlices.pop_back();
2110 }
2111}
2112
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002113size_t
Greg Clayton3046e662013-07-10 01:23:25 +00002114ObjectFileMachO::ParseSymtab ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002115{
2116 Timer scoped_timer(__PRETTY_FUNCTION__,
2117 "ObjectFileMachO::ParseSymtab () module = %s",
2118 m_file.GetFilename().AsCString(""));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002119 ModuleSP module_sp (GetModule());
2120 if (!module_sp)
2121 return 0;
2122
2123 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
2124 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
Greg Clayton9191db42013-10-21 18:40:51 +00002125 struct dyld_info_command dyld_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002126 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
2127 FunctionStarts function_starts;
Greg Claytonc7bece562013-01-25 18:06:21 +00002128 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002129 uint32_t i;
Greg Clayton9191db42013-10-21 18:40:51 +00002130 FileSpecList dylib_files;
Greg Clayton5160ce52013-03-27 23:08:40 +00002131 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
Greg Clayton77ccca72011-12-30 00:32:24 +00002132
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002133 for (i=0; i<m_header.ncmds; ++i)
2134 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002135 const lldb::offset_t cmd_offset = offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002136 // Read in the load command and load command size
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002137 struct load_command lc;
2138 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002139 break;
2140 // Watch for the symbol table load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002141 switch (lc.cmd)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002142 {
Charles Davis510938e2013-08-27 05:04:57 +00002143 case LC_SYMTAB:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002144 symtab_load_command.cmd = lc.cmd;
2145 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002146 // Read in the rest of the symtab load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002147 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
2148 return 0;
2149 if (symtab_load_command.symoff == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002150 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002151 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002152 module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002153 return 0;
2154 }
2155
2156 if (symtab_load_command.stroff == 0)
2157 {
2158 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002159 module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002160 return 0;
2161 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002162
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002163 if (symtab_load_command.nsyms == 0)
2164 {
2165 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002166 module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002167 return 0;
2168 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002169
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002170 if (symtab_load_command.strsize == 0)
2171 {
2172 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002173 module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002174 return 0;
2175 }
2176 break;
2177
Greg Clayton9191db42013-10-21 18:40:51 +00002178 case LC_DYLD_INFO:
2179 case LC_DYLD_INFO_ONLY:
2180 if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
2181 {
2182 dyld_info.cmd = lc.cmd;
2183 dyld_info.cmdsize = lc.cmdsize;
2184 }
2185 else
2186 {
2187 memset (&dyld_info, 0, sizeof(dyld_info));
2188 }
2189 break;
2190
2191 case LC_LOAD_DYLIB:
2192 case LC_LOAD_WEAK_DYLIB:
2193 case LC_REEXPORT_DYLIB:
2194 case LC_LOADFVMLIB:
2195 case LC_LOAD_UPWARD_DYLIB:
2196 {
2197 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2198 const char *path = m_data.PeekCStr(name_offset);
2199 if (path)
2200 {
2201 FileSpec file_spec(path, false);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002202 // Strip the path if there is @rpath, @executable, etc so we just use the basename
Greg Clayton9191db42013-10-21 18:40:51 +00002203 if (path[0] == '@')
2204 file_spec.GetDirectory().Clear();
Jim Inghamfbe0b9a2014-05-21 03:58:03 +00002205
2206 if (lc.cmd == LC_REEXPORT_DYLIB)
2207 {
2208 m_reexported_dylibs.AppendIfUnique(file_spec);
2209 }
Greg Clayton9191db42013-10-21 18:40:51 +00002210
2211 dylib_files.Append(file_spec);
2212 }
2213 }
2214 break;
2215
Charles Davis510938e2013-08-27 05:04:57 +00002216 case LC_FUNCTION_STARTS:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002217 function_starts_load_command.cmd = lc.cmd;
2218 function_starts_load_command.cmdsize = lc.cmdsize;
2219 if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
Virgile Bellob2f1fb22013-08-23 12:44:05 +00002220 memset (&function_starts_load_command, 0, sizeof(function_starts_load_command));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002221 break;
2222
2223 default:
2224 break;
2225 }
2226 offset = cmd_offset + lc.cmdsize;
2227 }
2228
2229 if (symtab_load_command.cmd)
2230 {
2231 Symtab *symtab = m_symtab_ap.get();
2232 SectionList *section_list = GetSectionList();
2233 if (section_list == NULL)
2234 return 0;
2235
Greg Claytonc7bece562013-01-25 18:06:21 +00002236 const uint32_t addr_byte_size = m_data.GetAddressByteSize();
2237 const ByteOrder byte_order = m_data.GetByteOrder();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002238 bool bit_width_32 = addr_byte_size == 4;
2239 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
2240
Greg Claytonc7bece562013-01-25 18:06:21 +00002241 DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
2242 DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
2243 DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
Jason Molendad34e6522013-02-05 22:31:24 +00002244 DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002245 DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);
Jason Molenda4e7511e2013-03-06 23:19:17 +00002246
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002247 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
2248 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Clayton4c82d422012-05-18 23:20:01 +00002249 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
Greg Claytonfd814c52013-08-13 01:42:25 +00002250
2251 ProcessSP process_sp (m_process_wp.lock());
2252 Process *process = process_sp.get();
2253
Greg Clayton86eac942013-08-13 21:32:34 +00002254 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
2255
Greg Clayton48672af2014-06-24 22:22:43 +00002256 if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002257 {
Greg Clayton4c82d422012-05-18 23:20:01 +00002258 Target &target = process->GetTarget();
Greg Claytonfd814c52013-08-13 01:42:25 +00002259
Greg Clayton86eac942013-08-13 21:32:34 +00002260 memory_module_load_level = target.GetMemoryModuleLoadLevel();
Greg Claytonfd814c52013-08-13 01:42:25 +00002261
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002262 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2263 // Reading mach file from memory in a process or core file...
2264
2265 if (linkedit_section_sp)
2266 {
2267 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
2268 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2269 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Clayton4c82d422012-05-18 23:20:01 +00002270 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton26b47e22012-04-18 05:19:20 +00002271
2272 bool data_was_read = false;
2273
Todd Fiala013434e2014-07-09 01:29:05 +00002274#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa3329782014-03-29 18:54:20 +00002275 if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
Greg Clayton77ccca72011-12-30 00:32:24 +00002276 {
Greg Clayton26b47e22012-04-18 05:19:20 +00002277 // This mach-o memory file is in the dyld shared cache. If this
2278 // program is not remote and this is iOS, then this process will
2279 // share the same shared cache as the process we are debugging and
2280 // we can read the entire __LINKEDIT from the address space in this
2281 // process. This is a needed optimization that is used for local iOS
2282 // debugging only since all shared libraries in the shared cache do
2283 // not have corresponding files that exist in the file system of the
2284 // device. They have been combined into a single file. This means we
2285 // always have to load these files from memory. All of the symbol and
2286 // string tables from all of the __LINKEDIT sections from the shared
2287 // libraries in the shared cache have been merged into a single large
2288 // symbol and string table. Reading all of this symbol and string table
2289 // data across can slow down debug launch times, so we optimize this by
2290 // reading the memory for the __LINKEDIT section from this process.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002291
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() && lldb_shared_cache != process_shared_cache)
2296 {
2297 use_lldb_cache = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002298 ModuleSP module_sp (GetModule());
2299 if (module_sp)
2300 module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow.");
2301
Jason Molenda0e0954c2013-04-16 06:24:42 +00002302 }
2303
Greg Clayton26b47e22012-04-18 05:19:20 +00002304 PlatformSP platform_sp (target.GetPlatform());
Jason Molenda0e0954c2013-04-16 06:24:42 +00002305 if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
Greg Clayton26b47e22012-04-18 05:19:20 +00002306 {
2307 data_was_read = true;
2308 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Clayton4c82d422012-05-18 23:20:01 +00002309 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton26b47e22012-04-18 05:19:20 +00002310 if (function_starts_load_command.cmd)
2311 {
2312 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2313 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
2314 }
2315 }
2316 }
2317#endif
2318
2319 if (!data_was_read)
2320 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002321 if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
Jason Molendad34e6522013-02-05 22:31:24 +00002322 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002323 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
2324 if (nlist_data_sp)
2325 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2326 // Load strings individually from memory when loading from memory since shared cache
2327 // string tables contain strings for all symbols from all shared cached libraries
2328 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
2329 //if (strtab_data_sp)
2330 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
2331 if (m_dysymtab.nindirectsyms != 0)
2332 {
2333 const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
2334 DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
2335 if (indirect_syms_data_sp)
2336 indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2337 }
Jason Molendad34e6522013-02-05 22:31:24 +00002338 }
Greg Claytonfd814c52013-08-13 01:42:25 +00002339
2340 if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
Greg Clayton26b47e22012-04-18 05:19:20 +00002341 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002342 if (function_starts_load_command.cmd)
2343 {
2344 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2345 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
2346 if (func_start_data_sp)
2347 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
2348 }
Greg Clayton26b47e22012-04-18 05:19:20 +00002349 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002350 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002351 }
2352 }
2353 else
2354 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002355 nlist_data.SetData (m_data,
2356 symtab_load_command.symoff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002357 nlist_data_byte_size);
2358 strtab_data.SetData (m_data,
Jason Molenda4e7511e2013-03-06 23:19:17 +00002359 symtab_load_command.stroff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002360 strtab_data_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002361
2362 if (dyld_info.export_size > 0)
2363 {
2364 dyld_trie_data.SetData (m_data,
2365 dyld_info.export_off,
2366 dyld_info.export_size);
2367 }
2368
Jason Molendad34e6522013-02-05 22:31:24 +00002369 if (m_dysymtab.nindirectsyms != 0)
2370 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002371 indirect_symbol_index_data.SetData (m_data,
2372 m_dysymtab.indirectsymoff,
Jason Molendad34e6522013-02-05 22:31:24 +00002373 m_dysymtab.nindirectsyms * 4);
2374 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002375 if (function_starts_load_command.cmd)
2376 {
2377 function_starts_data.SetData (m_data,
2378 function_starts_load_command.dataoff,
2379 function_starts_load_command.datasize);
2380 }
2381 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002382
Greg Clayton86eac942013-08-13 21:32:34 +00002383 if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete)
2384 {
2385 if (log)
2386 module_sp->LogMessage(log, "failed to read nlist data");
2387 return 0;
2388 }
2389
2390
Greg Claytondebb8812012-05-25 17:04:00 +00002391 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2392 if (!have_strtab_data)
Greg Clayton4c82d422012-05-18 23:20:01 +00002393 {
Greg Claytondebb8812012-05-25 17:04:00 +00002394 if (process)
2395 {
2396 if (strtab_addr == LLDB_INVALID_ADDRESS)
2397 {
2398 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002399 module_sp->LogMessage(log, "failed to locate the strtab in memory");
Greg Claytondebb8812012-05-25 17:04:00 +00002400 return 0;
2401 }
2402 }
2403 else
Greg Clayton4c82d422012-05-18 23:20:01 +00002404 {
2405 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002406 module_sp->LogMessage(log, "failed to read strtab data");
Greg Clayton4c82d422012-05-18 23:20:01 +00002407 return 0;
2408 }
2409 }
Greg Clayton4c82d422012-05-18 23:20:01 +00002410
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002411 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
2412 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
2413 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
2414 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
2415 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
2416 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
2417 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
2418 SectionSP eh_frame_section_sp;
2419 if (text_section_sp.get())
2420 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
2421 else
2422 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
2423
Charles Davis510938e2013-08-27 05:04:57 +00002424 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
Jason Molenda5635f772013-03-21 03:36:01 +00002425
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002426 // lldb works best if it knows the start address of all functions in a module.
Jason Molenda5635f772013-03-21 03:36:01 +00002427 // Linker symbols or debug info are normally the best source of information for start addr / size but
2428 // they may be stripped in a released binary.
Jason Molendad63d3c72013-04-16 00:18:44 +00002429 // Two additional sources of information exist in Mach-O binaries:
Jason Molenda5635f772013-03-21 03:36:01 +00002430 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
2431 // binary, relative to the text section.
2432 // eh_frame - the eh_frame FDEs have the start addr & size of each function
2433 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
2434 // Binaries built to run on older releases may need to use eh_frame information.
2435
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002436 if (text_section_sp && function_starts_data.GetByteSize())
2437 {
2438 FunctionStarts::Entry function_start_entry;
2439 function_start_entry.data = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00002440 lldb::offset_t function_start_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002441 function_start_entry.addr = text_section_sp->GetFileAddress();
2442 uint64_t delta;
2443 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
2444 {
2445 // Now append the current entry
2446 function_start_entry.addr += delta;
2447 function_starts.Append(function_start_entry);
2448 }
Jason Molendad63d3c72013-04-16 00:18:44 +00002449 }
Jason Molenda5635f772013-03-21 03:36:01 +00002450 else
2451 {
Jason Molenda584ce2f2013-03-22 00:38:45 +00002452 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
2453 // but it doesn't actually have the eh_frame content. And if we have a dSYM, we don't need to do any
2454 // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
2455 // the module.
2456 if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
Jason Molenda5635f772013-03-21 03:36:01 +00002457 {
2458 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindGCC, true);
2459 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
2460 eh_frame.GetFunctionAddressAndSizeVector (functions);
2461 addr_t text_base_addr = text_section_sp->GetFileAddress();
2462 size_t count = functions.GetSize();
2463 for (size_t i = 0; i < count; ++i)
2464 {
2465 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
2466 if (func)
2467 {
2468 FunctionStarts::Entry function_start_entry;
2469 function_start_entry.addr = func->base - text_base_addr;
2470 function_starts.Append(function_start_entry);
2471 }
2472 }
2473 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002474 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002475
Greg Claytonc7bece562013-01-25 18:06:21 +00002476 const size_t function_starts_count = function_starts.GetSize();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002477
Saleem Abdulrasoolb5c128b2014-07-23 01:53:52 +00002478 const user_id_t TEXT_eh_frame_sectID =
2479 eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
2480 : static_cast<user_id_t>(NO_SECT);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002481
Greg Claytonc7bece562013-01-25 18:06:21 +00002482 lldb::offset_t nlist_data_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002483
2484 uint32_t N_SO_index = UINT32_MAX;
2485
2486 MachSymtabSectionInfo section_info (section_list);
2487 std::vector<uint32_t> N_FUN_indexes;
2488 std::vector<uint32_t> N_NSYM_indexes;
2489 std::vector<uint32_t> N_INCL_indexes;
2490 std::vector<uint32_t> N_BRAC_indexes;
2491 std::vector<uint32_t> N_COMM_indexes;
Greg Claytond81088c2014-01-16 01:38:29 +00002492 typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002493 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
Greg Claytondacc4a92013-05-14 22:19:37 +00002494 typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002495 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2496 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
Greg Claytondacc4a92013-05-14 22:19:37 +00002497 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002498 // Any symbols that get merged into another will get an entry
2499 // in this map so we know
2500 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2501 uint32_t nlist_idx = 0;
2502 Symbol *symbol_ptr = NULL;
2503
2504 uint32_t sym_idx = 0;
Jason Molendaa5609c82012-06-21 01:51:02 +00002505 Symbol *sym = NULL;
Greg Claytonc7bece562013-01-25 18:06:21 +00002506 size_t num_syms = 0;
Greg Clayton4c82d422012-05-18 23:20:01 +00002507 std::string memory_symbol_name;
Jason Molendaa5609c82012-06-21 01:51:02 +00002508 uint32_t unmapped_local_symbols_found = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002509
Jim Inghamea3ac272014-01-10 22:55:37 +00002510 std::vector<TrieEntryWithOffset> trie_entries;
2511 std::set<lldb::addr_t> resolver_addresses;
2512
2513 if (dyld_trie_data.GetByteSize() > 0)
2514 {
2515 std::vector<llvm::StringRef> nameSlices;
2516 ParseTrieEntries (dyld_trie_data,
2517 0,
2518 nameSlices,
2519 resolver_addresses,
2520 trie_entries);
2521
2522 ConstString text_segment_name ("__TEXT");
2523 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2524 if (text_segment_sp)
2525 {
2526 const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
2527 if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
2528 {
2529 for (auto &e : trie_entries)
2530 e.entry.address += text_segment_file_addr;
2531 }
2532 }
2533 }
2534
Todd Fiala013434e2014-07-09 01:29:05 +00002535#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa5609c82012-06-21 01:51:02 +00002536
2537 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
2538 // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
2539 // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
2540 // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
2541 // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
2542 // nlist parser to ignore all LOCAL symbols.
2543
2544 if (m_header.flags & 0x80000000u)
2545 {
2546 // Before we can start mapping the DSC, we need to make certain the target process is actually
2547 // using the cache we can find.
2548
Jason Molendaa5609c82012-06-21 01:51:02 +00002549 // Next we need to determine the correct path for the dyld shared cache.
2550
Greg Clayton7ab7f892014-05-29 21:33:45 +00002551 ArchSpec header_arch;
2552 GetArchitecture(header_arch);
Jason Molendaa5609c82012-06-21 01:51:02 +00002553 char dsc_path[PATH_MAX];
2554
2555 snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
Jason Molenda4e7511e2013-03-06 23:19:17 +00002556 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
2557 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
Jason Molendaa5609c82012-06-21 01:51:02 +00002558 header_arch.GetArchitectureName());
2559
2560 FileSpec dsc_filespec(dsc_path, false);
2561
2562 // We need definitions of two structures in the on-disk DSC, copy them here manually
Jason Molendad63d3c72013-04-16 00:18:44 +00002563 struct lldb_copy_dyld_cache_header_v0
Greg Clayton946f8902012-09-05 22:30:51 +00002564 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002565 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2566 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2567 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
Jason Molenda4e7511e2013-03-06 23:19:17 +00002568 uint32_t imagesOffset;
2569 uint32_t imagesCount;
2570 uint64_t dyldBaseAddress;
2571 uint64_t codeSignatureOffset;
2572 uint64_t codeSignatureSize;
2573 uint64_t slideInfoOffset;
2574 uint64_t slideInfoSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002575 uint64_t localSymbolsOffset; // file offset of where local symbols are stored
2576 uint64_t localSymbolsSize; // size of local symbols information
2577 };
2578 struct lldb_copy_dyld_cache_header_v1
2579 {
2580 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2581 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2582 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
2583 uint32_t imagesOffset;
2584 uint32_t imagesCount;
2585 uint64_t dyldBaseAddress;
2586 uint64_t codeSignatureOffset;
2587 uint64_t codeSignatureSize;
2588 uint64_t slideInfoOffset;
2589 uint64_t slideInfoSize;
Jason Molenda4e7511e2013-03-06 23:19:17 +00002590 uint64_t localSymbolsOffset;
2591 uint64_t localSymbolsSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002592 uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later
Greg Clayton946f8902012-09-05 22:30:51 +00002593 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002594
Jason Molendad63d3c72013-04-16 00:18:44 +00002595 struct lldb_copy_dyld_cache_mapping_info
2596 {
2597 uint64_t address;
2598 uint64_t size;
2599 uint64_t fileOffset;
2600 uint32_t maxProt;
2601 uint32_t initProt;
2602 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002603
Greg Clayton946f8902012-09-05 22:30:51 +00002604 struct lldb_copy_dyld_cache_local_symbols_info
2605 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002606 uint32_t nlistOffset;
2607 uint32_t nlistCount;
2608 uint32_t stringsOffset;
2609 uint32_t stringsSize;
2610 uint32_t entriesOffset;
2611 uint32_t entriesCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002612 };
2613 struct lldb_copy_dyld_cache_local_symbols_entry
2614 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002615 uint32_t dylibOffset;
2616 uint32_t nlistStartIndex;
2617 uint32_t nlistCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002618 };
Jason Molendaa5609c82012-06-21 01:51:02 +00002619
Jason Molendaf8130862012-06-22 03:28:35 +00002620 /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
2621 The dyld_cache_local_symbols_info structure gives us three things:
2622 1. The start and count of the nlist records in the dyld_shared_cache file
2623 2. The start and size of the strings for these nlist records
2624 3. The start and count of dyld_cache_local_symbols_entry entries
2625
2626 There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
2627 The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
Jason Molenda4e7511e2013-03-06 23:19:17 +00002628 The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
Jason Molendaf8130862012-06-22 03:28:35 +00002629 and the count of how many nlist records there are for this dylib/framework.
2630 */
2631
Jason Molendaa5609c82012-06-21 01:51:02 +00002632 // Process the dsc header to find the unmapped symbols
2633 //
2634 // Save some VM space, do not map the entire cache in one shot.
2635
Jason Molenda255f9bb2013-03-06 23:17:36 +00002636 DataBufferSP dsc_data_sp;
2637 dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
2638
2639 if (dsc_data_sp)
Jason Molendaa5609c82012-06-21 01:51:02 +00002640 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002641 DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002642
Jason Molenda255f9bb2013-03-06 23:17:36 +00002643 char version_str[17];
2644 int version = -1;
2645 lldb::offset_t offset = 0;
2646 memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16);
2647 version_str[16] = '\0';
2648 if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6]))
2649 {
2650 int v;
2651 if (::sscanf (version_str + 6, "%d", &v) == 1)
2652 {
2653 version = v;
2654 }
2655 }
2656
Jason Molenda0e0954c2013-04-16 06:24:42 +00002657 UUID dsc_uuid;
2658 if (version >= 1)
2659 {
2660 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
2661 uint8_t uuid_bytes[sizeof (uuid_t)];
2662 memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
2663 dsc_uuid.SetBytes (uuid_bytes);
2664 }
2665
2666 bool uuid_match = true;
2667 if (dsc_uuid.IsValid() && process)
2668 {
2669 UUID shared_cache_uuid(GetProcessSharedCacheUUID(process));
2670
2671 if (shared_cache_uuid.IsValid() && dsc_uuid != shared_cache_uuid)
2672 {
2673 // The on-disk dyld_shared_cache file is not the same as the one in this
2674 // process' memory, don't use it.
2675 uuid_match = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002676 ModuleSP module_sp (GetModule());
2677 if (module_sp)
2678 module_sp->ReportWarning ("process shared cache does not match on-disk dyld_shared_cache file, some symbol names will be missing.");
Jason Molenda0e0954c2013-04-16 06:24:42 +00002679 }
2680 }
2681
Jason Molenda4e7511e2013-03-06 23:19:17 +00002682 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);
Jason Molenda255f9bb2013-03-06 23:17:36 +00002683
Jason Molendaa5609c82012-06-21 01:51:02 +00002684 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
2685
2686 // If the mappingOffset points to a location inside the header, we've
2687 // opened an old dyld shared cache, and should not proceed further.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002688 if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
Jason Molendaa5609c82012-06-21 01:51:02 +00002689 {
2690
Jason Molenda255f9bb2013-03-06 23:17:36 +00002691 DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContents(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
2692 DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
2693 offset = 0;
2694
2695 // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
2696 // in the shared library cache need to be adjusted by an offset to match up with the
2697 // dylibOffset identifying field in the dyld_cache_local_symbol_entry's. This offset is
2698 // recorded in mapping_offset_value.
2699 const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
2700
2701 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
Jason Molendaa5609c82012-06-21 01:51:02 +00002702 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
2703 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
2704
Jason Molenda4e7511e2013-03-06 23:19:17 +00002705 if (localSymbolsOffset && localSymbolsSize)
Jason Molendaa5609c82012-06-21 01:51:02 +00002706 {
2707 // Map the local symbols
Jason Molenda4e7511e2013-03-06 23:19:17 +00002708 if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
Jason Molendaa5609c82012-06-21 01:51:02 +00002709 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002710 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002711
2712 offset = 0;
2713
2714 // Read the local_symbols_infos struct in one shot
2715 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
2716 dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
2717
Jason Molendaa5609c82012-06-21 01:51:02 +00002718 SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
2719
Jason Molenda255f9bb2013-03-06 23:17:36 +00002720 uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00002721
2722 offset = local_symbols_info.entriesOffset;
2723 for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
2724 {
2725 struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
2726 local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
2727 local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
2728 local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
2729
Jason Molenda4e7511e2013-03-06 23:19:17 +00002730 if (header_file_offset == local_symbols_entry.dylibOffset)
Jason Molendaa5609c82012-06-21 01:51:02 +00002731 {
2732 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
2733
2734 // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
2735 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2736 num_syms = symtab->GetNumSymbols();
2737
2738 nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
2739 uint32_t string_table_offset = local_symbols_info.stringsOffset;
2740
Jason Molenda4e7511e2013-03-06 23:19:17 +00002741 for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
Jason Molendaa5609c82012-06-21 01:51:02 +00002742 {
2743 /////////////////////////////
2744 {
2745 struct nlist_64 nlist;
2746 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2747 break;
2748
2749 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
2750 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2751 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2752 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
2753 nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
2754
2755 SymbolType type = eSymbolTypeInvalid;
2756 const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
2757
2758 if (symbol_name == NULL)
2759 {
2760 // No symbol should be NULL, even the symbols with no
2761 // string values should have an offset zero which points
2762 // to an empty C-string
2763 Host::SystemLog (Host::eSystemLogError,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002764 "error: DSC unmapped local symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
Jason Molendaa5609c82012-06-21 01:51:02 +00002765 entry_index,
2766 nlist.n_strx,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002767 module_sp->GetFileSpec().GetPath().c_str());
Jason Molendaa5609c82012-06-21 01:51:02 +00002768 continue;
2769 }
2770 if (symbol_name[0] == '\0')
2771 symbol_name = NULL;
2772
2773 const char *symbol_name_non_abi_mangled = NULL;
2774
2775 SectionSP symbol_section;
2776 uint32_t symbol_byte_size = 0;
2777 bool add_nlist = true;
Charles Davis510938e2013-08-27 05:04:57 +00002778 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002779 bool demangled_is_synthesized = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00002780 bool is_gsym = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002781
2782 assert (sym_idx < num_syms);
2783
2784 sym[sym_idx].SetDebug (is_debug);
2785
2786 if (is_debug)
2787 {
2788 switch (nlist.n_type)
2789 {
Charles Davis510938e2013-08-27 05:04:57 +00002790 case N_GSYM:
2791 // global symbol: name,,NO_SECT,type,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002792 // Sometimes the N_GSYM value contains the address.
2793
2794 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
2795 // have the same address, but we want to ensure that we always find only the real symbol,
2796 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
2797 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
2798 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
2799 // same address.
2800
2801 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
2802 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
2803 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
2804 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
2805 add_nlist = false;
2806 else
2807 {
Greg Claytondacc4a92013-05-14 22:19:37 +00002808 is_gsym = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00002809 sym[sym_idx].SetExternal(true);
2810 if (nlist.n_value != 0)
2811 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2812 type = eSymbolTypeData;
2813 }
2814 break;
2815
Charles Davis510938e2013-08-27 05:04:57 +00002816 case N_FNAME:
2817 // procedure name (f77 kludge): name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002818 type = eSymbolTypeCompiler;
2819 break;
2820
Charles Davis510938e2013-08-27 05:04:57 +00002821 case N_FUN:
2822 // procedure: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002823 if (symbol_name)
2824 {
2825 type = eSymbolTypeCode;
2826 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2827
Greg Claytond81088c2014-01-16 01:38:29 +00002828 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002829 // We use the current number of symbols in the symbol table in lieu of
2830 // using nlist_idx in case we ever start trimming entries out
2831 N_FUN_indexes.push_back(sym_idx);
2832 }
2833 else
2834 {
2835 type = eSymbolTypeCompiler;
2836
2837 if ( !N_FUN_indexes.empty() )
2838 {
2839 // Copy the size of the function into the original STAB entry so we don't have
2840 // to hunt for it later
2841 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
2842 N_FUN_indexes.pop_back();
2843 // We don't really need the end function STAB as it contains the size which
2844 // we already placed with the original symbol, so don't add it if we want a
2845 // minimal symbol table
Greg Clayton3046e662013-07-10 01:23:25 +00002846 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002847 }
2848 }
2849 break;
2850
Charles Davis510938e2013-08-27 05:04:57 +00002851 case N_STSYM:
2852 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00002853 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002854 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2855 type = eSymbolTypeData;
2856 break;
2857
Charles Davis510938e2013-08-27 05:04:57 +00002858 case N_LCSYM:
2859 // .lcomm symbol: name,,n_sect,type,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002860 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2861 type = eSymbolTypeCommonBlock;
2862 break;
2863
Charles Davis510938e2013-08-27 05:04:57 +00002864 case N_BNSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002865 // We use the current number of symbols in the symbol table in lieu of
2866 // using nlist_idx in case we ever start trimming entries out
Greg Clayton3046e662013-07-10 01:23:25 +00002867 // Skip these if we want minimal symbol tables
2868 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002869 break;
2870
Charles Davis510938e2013-08-27 05:04:57 +00002871 case N_ENSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002872 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
2873 // so that we can always skip the entire symbol if we need to navigate
2874 // more quickly at the source level when parsing STABS
Greg Clayton3046e662013-07-10 01:23:25 +00002875 // Skip these if we want minimal symbol tables
2876 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002877 break;
2878
2879
Charles Davis510938e2013-08-27 05:04:57 +00002880 case N_OPT:
2881 // emitted with gcc2_compiled and in gcc source
Jason Molendaa5609c82012-06-21 01:51:02 +00002882 type = eSymbolTypeCompiler;
2883 break;
2884
Charles Davis510938e2013-08-27 05:04:57 +00002885 case N_RSYM:
2886 // register sym: name,,NO_SECT,type,register
Jason Molendaa5609c82012-06-21 01:51:02 +00002887 type = eSymbolTypeVariable;
2888 break;
2889
Charles Davis510938e2013-08-27 05:04:57 +00002890 case N_SLINE:
2891 // src line: 0,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002892 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2893 type = eSymbolTypeLineEntry;
2894 break;
2895
Charles Davis510938e2013-08-27 05:04:57 +00002896 case N_SSYM:
2897 // structure elt: name,,NO_SECT,type,struct_offset
Jason Molendaa5609c82012-06-21 01:51:02 +00002898 type = eSymbolTypeVariableType;
2899 break;
2900
Charles Davis510938e2013-08-27 05:04:57 +00002901 case N_SO:
2902 // source file name
Jason Molendaa5609c82012-06-21 01:51:02 +00002903 type = eSymbolTypeSourceFile;
2904 if (symbol_name == NULL)
2905 {
Greg Clayton3046e662013-07-10 01:23:25 +00002906 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002907 if (N_SO_index != UINT32_MAX)
2908 {
2909 // Set the size of the N_SO to the terminating index of this N_SO
2910 // so that we can always skip the entire N_SO if we need to navigate
2911 // more quickly at the source level when parsing STABS
2912 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
Greg Clayton3046e662013-07-10 01:23:25 +00002913 symbol_ptr->SetByteSize(sym_idx);
Jason Molendaa5609c82012-06-21 01:51:02 +00002914 symbol_ptr->SetSizeIsSibling(true);
2915 }
2916 N_NSYM_indexes.clear();
2917 N_INCL_indexes.clear();
2918 N_BRAC_indexes.clear();
2919 N_COMM_indexes.clear();
2920 N_FUN_indexes.clear();
2921 N_SO_index = UINT32_MAX;
2922 }
2923 else
2924 {
2925 // We use the current number of symbols in the symbol table in lieu of
2926 // using nlist_idx in case we ever start trimming entries out
2927 const bool N_SO_has_full_path = symbol_name[0] == '/';
2928 if (N_SO_has_full_path)
2929 {
Greg Clayton3046e662013-07-10 01:23:25 +00002930 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00002931 {
2932 // We have two consecutive N_SO entries where the first contains a directory
2933 // and the second contains a full path.
Jason Molendad9d5cf52012-07-20 03:35:44 +00002934 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00002935 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2936 add_nlist = false;
2937 }
2938 else
2939 {
2940 // This is the first entry in a N_SO that contains a directory or
2941 // a full path to the source file
2942 N_SO_index = sym_idx;
2943 }
2944 }
Greg Clayton3046e662013-07-10 01:23:25 +00002945 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00002946 {
2947 // This is usually the second N_SO entry that contains just the filename,
2948 // so here we combine it with the first one if we are minimizing the symbol table
2949 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
2950 if (so_path && so_path[0])
2951 {
2952 std::string full_so_path (so_path);
Greg Clayton0662d962012-09-07 20:29:13 +00002953 const size_t double_slash_pos = full_so_path.find("//");
2954 if (double_slash_pos != std::string::npos)
2955 {
2956 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00002957 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Clayton0662d962012-09-07 20:29:13 +00002958 // and the second is the directory for the source file so you end up with
2959 // a path that looks like "/tmp/src//tmp/src/"
2960 FileSpec so_dir(so_path, false);
2961 if (!so_dir.Exists())
2962 {
2963 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
2964 if (so_dir.Exists())
2965 {
2966 // Trim off the incorrect path
2967 full_so_path.erase(0, double_slash_pos + 1);
2968 }
2969 }
2970 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002971 if (*full_so_path.rbegin() != '/')
2972 full_so_path += '/';
2973 full_so_path += symbol_name;
Jason Molendad9d5cf52012-07-20 03:35:44 +00002974 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00002975 add_nlist = false;
2976 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2977 }
2978 }
Greg Clayton946f8902012-09-05 22:30:51 +00002979 else
2980 {
2981 // This could be a relative path to a N_SO
2982 N_SO_index = sym_idx;
2983 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002984 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002985 break;
2986
Charles Davis510938e2013-08-27 05:04:57 +00002987 case N_OSO:
2988 // object file name: name,,0,0,st_mtime
Jason Molendaa5609c82012-06-21 01:51:02 +00002989 type = eSymbolTypeObjectFile;
2990 break;
2991
Charles Davis510938e2013-08-27 05:04:57 +00002992 case N_LSYM:
2993 // local sym: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00002994 type = eSymbolTypeLocal;
2995 break;
2996
2997 //----------------------------------------------------------------------
2998 // INCL scopes
2999 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003000 case N_BINCL:
3001 // include file beginning: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003002 // We use the current number of symbols in the symbol table in lieu of
3003 // using nlist_idx in case we ever start trimming entries out
3004 N_INCL_indexes.push_back(sym_idx);
3005 type = eSymbolTypeScopeBegin;
3006 break;
3007
Charles Davis510938e2013-08-27 05:04:57 +00003008 case N_EINCL:
3009 // include file end: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003010 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3011 // so that we can always skip the entire symbol if we need to navigate
3012 // more quickly at the source level when parsing STABS
3013 if ( !N_INCL_indexes.empty() )
3014 {
3015 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3016 symbol_ptr->SetByteSize(sym_idx + 1);
3017 symbol_ptr->SetSizeIsSibling(true);
3018 N_INCL_indexes.pop_back();
3019 }
3020 type = eSymbolTypeScopeEnd;
3021 break;
3022
Charles Davis510938e2013-08-27 05:04:57 +00003023 case N_SOL:
3024 // #included file name: name,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003025 type = eSymbolTypeHeaderFile;
3026
3027 // We currently don't use the header files on darwin
Greg Clayton3046e662013-07-10 01:23:25 +00003028 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00003029 break;
3030
Charles Davis510938e2013-08-27 05:04:57 +00003031 case N_PARAMS:
3032 // compiler parameters: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003033 type = eSymbolTypeCompiler;
3034 break;
3035
Charles Davis510938e2013-08-27 05:04:57 +00003036 case N_VERSION:
3037 // compiler version: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003038 type = eSymbolTypeCompiler;
3039 break;
3040
Charles Davis510938e2013-08-27 05:04:57 +00003041 case N_OLEVEL:
3042 // compiler -O level: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003043 type = eSymbolTypeCompiler;
3044 break;
3045
Charles Davis510938e2013-08-27 05:04:57 +00003046 case N_PSYM:
3047 // parameter: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003048 type = eSymbolTypeVariable;
3049 break;
3050
Charles Davis510938e2013-08-27 05:04:57 +00003051 case N_ENTRY:
3052 // alternate entry: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003053 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3054 type = eSymbolTypeLineEntry;
3055 break;
3056
3057 //----------------------------------------------------------------------
3058 // Left and Right Braces
3059 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003060 case N_LBRAC:
3061 // left bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003062 // We use the current number of symbols in the symbol table in lieu of
3063 // using nlist_idx in case we ever start trimming entries out
3064 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3065 N_BRAC_indexes.push_back(sym_idx);
3066 type = eSymbolTypeScopeBegin;
3067 break;
3068
Charles Davis510938e2013-08-27 05:04:57 +00003069 case N_RBRAC:
3070 // right bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003071 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
3072 // so that we can always skip the entire symbol if we need to navigate
3073 // more quickly at the source level when parsing STABS
3074 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3075 if ( !N_BRAC_indexes.empty() )
3076 {
3077 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
3078 symbol_ptr->SetByteSize(sym_idx + 1);
3079 symbol_ptr->SetSizeIsSibling(true);
3080 N_BRAC_indexes.pop_back();
3081 }
3082 type = eSymbolTypeScopeEnd;
3083 break;
3084
Charles Davis510938e2013-08-27 05:04:57 +00003085 case N_EXCL:
3086 // deleted include file: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003087 type = eSymbolTypeHeaderFile;
3088 break;
3089
3090 //----------------------------------------------------------------------
3091 // COMM scopes
3092 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003093 case N_BCOMM:
3094 // begin common: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003095 // We use the current number of symbols in the symbol table in lieu of
3096 // using nlist_idx in case we ever start trimming entries out
3097 type = eSymbolTypeScopeBegin;
3098 N_COMM_indexes.push_back(sym_idx);
3099 break;
3100
Charles Davis510938e2013-08-27 05:04:57 +00003101 case N_ECOML:
3102 // end common (local name): 0,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003103 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3104 // Fall through
3105
Charles Davis510938e2013-08-27 05:04:57 +00003106 case N_ECOMM:
3107 // end common: name,,n_sect,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003108 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
3109 // so that we can always skip the entire symbol if we need to navigate
3110 // more quickly at the source level when parsing STABS
3111 if ( !N_COMM_indexes.empty() )
3112 {
3113 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
3114 symbol_ptr->SetByteSize(sym_idx + 1);
3115 symbol_ptr->SetSizeIsSibling(true);
3116 N_COMM_indexes.pop_back();
3117 }
3118 type = eSymbolTypeScopeEnd;
3119 break;
3120
Charles Davis510938e2013-08-27 05:04:57 +00003121 case N_LENG:
3122 // second stab entry with length information
Jason Molendaa5609c82012-06-21 01:51:02 +00003123 type = eSymbolTypeAdditional;
3124 break;
3125
3126 default: break;
3127 }
3128 }
3129 else
3130 {
Charles Davis510938e2013-08-27 05:04:57 +00003131 //uint8_t n_pext = N_PEXT & nlist.n_type;
3132 uint8_t n_type = N_TYPE & nlist.n_type;
3133 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Jason Molendaa5609c82012-06-21 01:51:02 +00003134
3135 switch (n_type)
3136 {
Charles Davis510938e2013-08-27 05:04:57 +00003137 case N_INDR: // Fall through
3138 case N_PBUD: // Fall through
3139 case N_UNDF:
Jason Molendaa5609c82012-06-21 01:51:02 +00003140 type = eSymbolTypeUndefined;
3141 break;
3142
Charles Davis510938e2013-08-27 05:04:57 +00003143 case N_ABS:
Jason Molendaa5609c82012-06-21 01:51:02 +00003144 type = eSymbolTypeAbsolute;
3145 break;
3146
Charles Davis510938e2013-08-27 05:04:57 +00003147 case N_SECT:
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003148 {
3149 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00003150
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003151 if (symbol_section == NULL)
Jason Molendaa5609c82012-06-21 01:51:02 +00003152 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003153 // TODO: warn about this?
3154 add_nlist = false;
3155 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003156 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003157
3158 if (TEXT_eh_frame_sectID == nlist.n_sect)
Jason Molendaa5609c82012-06-21 01:51:02 +00003159 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003160 type = eSymbolTypeException;
3161 }
3162 else
3163 {
Charles Davis510938e2013-08-27 05:04:57 +00003164 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003165
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003166 switch (section_type)
Jason Molendaa5609c82012-06-21 01:51:02 +00003167 {
Charles Davis510938e2013-08-27 05:04:57 +00003168 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
3169 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
3170 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
3171 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
3172 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
3173 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
3174 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
3175 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
3176 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00003177 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
3178 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
3179 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
3180 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00003181 default:
3182 switch (symbol_section->GetType())
3183 {
3184 case lldb::eSectionTypeCode:
3185 type = eSymbolTypeCode;
3186 break;
3187 case eSectionTypeData:
3188 case eSectionTypeDataCString: // Inlined C string data
3189 case eSectionTypeDataCStringPointers: // Pointers to C string data
3190 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
3191 case eSectionTypeData4:
3192 case eSectionTypeData8:
3193 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00003194 type = eSymbolTypeData;
3195 break;
3196 default:
3197 break;
3198 }
3199 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003200 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003201
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003202 if (type == eSymbolTypeInvalid)
3203 {
3204 const char *symbol_sect_name = symbol_section->GetName().AsCString();
3205 if (symbol_section->IsDescendant (text_section_sp.get()))
3206 {
Charles Davis510938e2013-08-27 05:04:57 +00003207 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3208 S_ATTR_SELF_MODIFYING_CODE |
3209 S_ATTR_SOME_INSTRUCTIONS))
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003210 type = eSymbolTypeData;
3211 else
3212 type = eSymbolTypeCode;
3213 }
3214 else if (symbol_section->IsDescendant(data_section_sp.get()))
Jason Molendaa5609c82012-06-21 01:51:02 +00003215 {
3216 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
3217 {
3218 type = eSymbolTypeRuntime;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003219
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003220 if (symbol_name &&
3221 symbol_name[0] == '_' &&
3222 symbol_name[1] == 'O' &&
Jason Molendaa5609c82012-06-21 01:51:02 +00003223 symbol_name[2] == 'B')
3224 {
3225 llvm::StringRef symbol_name_ref(symbol_name);
3226 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
3227 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
3228 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
3229 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3230 {
3231 symbol_name_non_abi_mangled = symbol_name + 1;
3232 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3233 type = eSymbolTypeObjCClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003234 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003235 }
3236 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3237 {
3238 symbol_name_non_abi_mangled = symbol_name + 1;
3239 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3240 type = eSymbolTypeObjCMetaClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003241 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003242 }
3243 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3244 {
3245 symbol_name_non_abi_mangled = symbol_name + 1;
3246 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3247 type = eSymbolTypeObjCIVar;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003248 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003249 }
3250 }
3251 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003252 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
Jason Molendaa5609c82012-06-21 01:51:02 +00003253 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003254 type = eSymbolTypeException;
Jason Molendaa5609c82012-06-21 01:51:02 +00003255 }
3256 else
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003257 {
3258 type = eSymbolTypeData;
3259 }
3260 }
3261 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
3262 {
3263 type = eSymbolTypeTrampoline;
3264 }
3265 else if (symbol_section->IsDescendant(objc_section_sp.get()))
3266 {
3267 type = eSymbolTypeRuntime;
3268 if (symbol_name && symbol_name[0] == '.')
3269 {
3270 llvm::StringRef symbol_name_ref(symbol_name);
3271 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
3272 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
Jason Molendaa5609c82012-06-21 01:51:02 +00003273 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003274 symbol_name_non_abi_mangled = symbol_name;
3275 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
3276 type = eSymbolTypeObjCClass;
3277 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003278 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003279 }
3280 }
3281 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003282 }
3283 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003284 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003285 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003286 }
3287
3288 if (add_nlist)
3289 {
3290 uint64_t symbol_value = nlist.n_value;
Jason Molendaa5609c82012-06-21 01:51:02 +00003291 if (symbol_name_non_abi_mangled)
3292 {
Jason Molendad9d5cf52012-07-20 03:35:44 +00003293 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
3294 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Jason Molendaa5609c82012-06-21 01:51:02 +00003295 }
3296 else
3297 {
Greg Clayton3046e662013-07-10 01:23:25 +00003298 bool symbol_name_is_mangled = false;
3299
Jason Molendaa5609c82012-06-21 01:51:02 +00003300 if (symbol_name && symbol_name[0] == '_')
3301 {
3302 symbol_name_is_mangled = symbol_name[1] == '_';
3303 symbol_name++; // Skip the leading underscore
3304 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003305
Jason Molendaa5609c82012-06-21 01:51:02 +00003306 if (symbol_name)
3307 {
Greg Claytondacc4a92013-05-14 22:19:37 +00003308 ConstString const_symbol_name(symbol_name);
Greg Claytondacc4a92013-05-14 22:19:37 +00003309 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Clayton3046e662013-07-10 01:23:25 +00003310 if (is_gsym && is_debug)
3311 N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
Jason Molendaa5609c82012-06-21 01:51:02 +00003312 }
3313 }
3314 if (symbol_section)
3315 {
3316 const addr_t section_file_addr = symbol_section->GetFileAddress();
3317 if (symbol_byte_size == 0 && function_starts_count > 0)
3318 {
3319 addr_t symbol_lookup_file_addr = nlist.n_value;
3320 // Do an exact address match for non-ARM addresses, else get the closest since
3321 // the symbol might be a thumb symbol which has an address with bit zero set
3322 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
3323 if (is_arm && func_start_entry)
3324 {
3325 // Verify that the function start address is the symbol address (ARM)
3326 // or the symbol address + 1 (thumb)
3327 if (func_start_entry->addr != symbol_lookup_file_addr &&
3328 func_start_entry->addr != (symbol_lookup_file_addr + 1))
3329 {
3330 // Not the right entry, NULL it out...
3331 func_start_entry = NULL;
3332 }
3333 }
3334 if (func_start_entry)
3335 {
3336 func_start_entry->data = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003337
Jason Molendaa5609c82012-06-21 01:51:02 +00003338 addr_t symbol_file_addr = func_start_entry->addr;
3339 uint32_t symbol_flags = 0;
3340 if (is_arm)
3341 {
3342 if (symbol_file_addr & 1)
3343 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
3344 symbol_file_addr &= 0xfffffffffffffffeull;
3345 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003346
Jason Molendaa5609c82012-06-21 01:51:02 +00003347 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3348 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3349 if (next_func_start_entry)
3350 {
3351 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3352 // Be sure the clear the Thumb address bit when we calculate the size
3353 // from the current and next address
3354 if (is_arm)
3355 next_symbol_file_addr &= 0xfffffffffffffffeull;
3356 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
3357 }
3358 else
3359 {
3360 symbol_byte_size = section_end_file_addr - symbol_file_addr;
3361 }
3362 }
3363 }
3364 symbol_value -= section_file_addr;
3365 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003366
Greg Claytondacc4a92013-05-14 22:19:37 +00003367 if (is_debug == false)
3368 {
3369 if (type == eSymbolTypeCode)
3370 {
3371 // See if we can find a N_FUN entry for any code symbols.
3372 // If we do find a match, and the name matches, then we
3373 // can merge the two into just the function symbol to avoid
3374 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003375 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3376 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3377 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003378 {
Greg Claytond81088c2014-01-16 01:38:29 +00003379 bool found_it = false;
3380 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003381 {
Greg Claytond81088c2014-01-16 01:38:29 +00003382 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3383 {
3384 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3385 // We just need the flags from the linker symbol, so put these flags
3386 // into the N_FUN flags to avoid duplicate symbols in the symbol table
3387 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3388 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3389 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
3390 sym[pos->second].SetType (eSymbolTypeResolver);
3391 sym[sym_idx].Clear();
3392 found_it = true;
3393 break;
3394 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003395 }
Greg Claytond81088c2014-01-16 01:38:29 +00003396 if (found_it)
3397 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003398 }
Jim Inghamea3ac272014-01-10 22:55:37 +00003399 else
3400 {
Greg Claytond81088c2014-01-16 01:38:29 +00003401 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00003402 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00003403 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003404 }
3405 else if (type == eSymbolTypeData)
3406 {
3407 // See if we can find a N_STSYM entry for any data symbols.
3408 // If we do find a match, and the name matches, then we
3409 // can merge the two into just the Static symbol to avoid
3410 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003411 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3412 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
3413 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003414 {
Greg Claytond81088c2014-01-16 01:38:29 +00003415 bool found_it = false;
3416 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003417 {
Greg Claytond81088c2014-01-16 01:38:29 +00003418 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3419 {
3420 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3421 // We just need the flags from the linker symbol, so put these flags
3422 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3423 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3424 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3425 sym[sym_idx].Clear();
3426 found_it = true;
3427 break;
3428 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003429 }
Greg Claytond81088c2014-01-16 01:38:29 +00003430 if (found_it)
3431 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003432 }
3433 else
3434 {
3435 // Combine N_GSYM stab entries with the non stab symbol
Greg Clayton3046e662013-07-10 01:23:25 +00003436 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
Greg Claytondacc4a92013-05-14 22:19:37 +00003437 if (pos != N_GSYM_name_to_sym_idx.end())
3438 {
3439 const uint32_t GSYM_sym_idx = pos->second;
3440 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
3441 // Copy the address, because often the N_GSYM address has an invalid address of zero
3442 // when the global is a common symbol
3443 sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
3444 sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
3445 // We just need the flags from the linker symbol, so put these flags
3446 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3447 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3448 sym[sym_idx].Clear();
3449 continue;
3450 }
3451 }
3452 }
3453 }
3454
Jason Molendaa5609c82012-06-21 01:51:02 +00003455 sym[sym_idx].SetID (nlist_idx);
3456 sym[sym_idx].SetType (type);
3457 sym[sym_idx].GetAddress().SetSection (symbol_section);
3458 sym[sym_idx].GetAddress().SetOffset (symbol_value);
3459 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003460
Jason Molendaa5609c82012-06-21 01:51:02 +00003461 if (symbol_byte_size > 0)
3462 sym[sym_idx].SetByteSize(symbol_byte_size);
3463
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003464 if (demangled_is_synthesized)
3465 sym[sym_idx].SetDemangledNameIsSynthesized(true);
Jason Molendaa5609c82012-06-21 01:51:02 +00003466 ++sym_idx;
3467 }
3468 else
3469 {
3470 sym[sym_idx].Clear();
3471 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003472
Jason Molendaa5609c82012-06-21 01:51:02 +00003473 }
3474 /////////////////////////////
3475 }
3476 break; // No more entries to consider
3477 }
3478 }
3479 }
3480 }
3481 }
3482 }
3483 }
3484
3485 // Must reset this in case it was mutated above!
3486 nlist_data_offset = 0;
3487#endif
Jim Inghamea3ac272014-01-10 22:55:37 +00003488
Greg Claytonfd814c52013-08-13 01:42:25 +00003489 if (nlist_data.GetByteSize() > 0)
Jason Molendaa5609c82012-06-21 01:51:02 +00003490 {
Jason Molendaa5609c82012-06-21 01:51:02 +00003491
Greg Claytonfd814c52013-08-13 01:42:25 +00003492 // If the sym array was not created while parsing the DSC unmapped
3493 // symbols, create it now.
3494 if (sym == NULL)
Greg Clayton4c82d422012-05-18 23:20:01 +00003495 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003496 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3497 num_syms = symtab->GetNumSymbols();
3498 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003499
Greg Claytonfd814c52013-08-13 01:42:25 +00003500 if (unmapped_local_symbols_found)
3501 {
3502 assert(m_dysymtab.ilocalsym == 0);
3503 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3504 nlist_idx = m_dysymtab.nlocalsym;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003505 }
Greg Claytondebb8812012-05-25 17:04:00 +00003506 else
3507 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003508 nlist_idx = 0;
Greg Claytondebb8812012-05-25 17:04:00 +00003509 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003510
Greg Claytonfd814c52013-08-13 01:42:25 +00003511 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003512 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003513 struct nlist_64 nlist;
3514 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
3515 break;
3516
3517 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
3518 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
3519 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
3520 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
3521 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
3522
3523 SymbolType type = eSymbolTypeInvalid;
3524 const char *symbol_name = NULL;
3525
3526 if (have_strtab_data)
Greg Clayton77ccca72011-12-30 00:32:24 +00003527 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003528 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003529
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003530 if (symbol_name == NULL)
3531 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003532 // No symbol should be NULL, even the symbols with no
3533 // string values should have an offset zero which points
3534 // to an empty C-string
3535 Host::SystemLog (Host::eSystemLogError,
3536 "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
3537 nlist_idx,
3538 nlist.n_strx,
3539 module_sp->GetFileSpec().GetPath().c_str());
3540 continue;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003541 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003542 if (symbol_name[0] == '\0')
3543 symbol_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003544 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003545 else
3546 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003547 const addr_t str_addr = strtab_addr + nlist.n_strx;
3548 Error str_error;
3549 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
3550 symbol_name = memory_symbol_name.c_str();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003551 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003552 const char *symbol_name_non_abi_mangled = NULL;
3553
3554 SectionSP symbol_section;
3555 lldb::addr_t symbol_byte_size = 0;
3556 bool add_nlist = true;
3557 bool is_gsym = false;
Charles Davis510938e2013-08-27 05:04:57 +00003558 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00003559 bool demangled_is_synthesized = false;
3560
3561 assert (sym_idx < num_syms);
3562
3563 sym[sym_idx].SetDebug (is_debug);
3564
3565 if (is_debug)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003566 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003567 switch (nlist.n_type)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003568 {
Charles Davis510938e2013-08-27 05:04:57 +00003569 case N_GSYM:
3570 // global symbol: name,,NO_SECT,type,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003571 // Sometimes the N_GSYM value contains the address.
Jason Molenda4e7511e2013-03-06 23:19:17 +00003572
Greg Claytonfd814c52013-08-13 01:42:25 +00003573 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
3574 // have the same address, but we want to ensure that we always find only the real symbol,
3575 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
3576 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
3577 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
3578 // same address.
Greg Clayton29e08cb2012-03-14 01:53:24 +00003579
Greg Claytonfd814c52013-08-13 01:42:25 +00003580 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
3581 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
3582 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
3583 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
3584 add_nlist = false;
3585 else
3586 {
3587 is_gsym = true;
3588 sym[sym_idx].SetExternal(true);
3589 if (nlist.n_value != 0)
3590 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3591 type = eSymbolTypeData;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003592 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003593 break;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003594
Charles Davis510938e2013-08-27 05:04:57 +00003595 case N_FNAME:
3596 // procedure name (f77 kludge): name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003597 type = eSymbolTypeCompiler;
3598 break;
3599
Charles Davis510938e2013-08-27 05:04:57 +00003600 case N_FUN:
3601 // procedure: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003602 if (symbol_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003603 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003604 type = eSymbolTypeCode;
3605 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3606
Greg Claytond81088c2014-01-16 01:38:29 +00003607 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003608 // We use the current number of symbols in the symbol table in lieu of
3609 // using nlist_idx in case we ever start trimming entries out
3610 N_FUN_indexes.push_back(sym_idx);
Greg Claytondacc4a92013-05-14 22:19:37 +00003611 }
3612 else
3613 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003614 type = eSymbolTypeCompiler;
3615
3616 if ( !N_FUN_indexes.empty() )
Greg Claytondacc4a92013-05-14 22:19:37 +00003617 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003618 // Copy the size of the function into the original STAB entry so we don't have
3619 // to hunt for it later
3620 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
3621 N_FUN_indexes.pop_back();
3622 // We don't really need the end function STAB as it contains the size which
3623 // we already placed with the original symbol, so don't add it if we want a
3624 // minimal symbol table
3625 add_nlist = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00003626 }
3627 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003628 break;
3629
Charles Davis510938e2013-08-27 05:04:57 +00003630 case N_STSYM:
3631 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00003632 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003633 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3634 type = eSymbolTypeData;
3635 break;
3636
Charles Davis510938e2013-08-27 05:04:57 +00003637 case N_LCSYM:
3638 // .lcomm symbol: name,,n_sect,type,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003639 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3640 type = eSymbolTypeCommonBlock;
3641 break;
3642
Charles Davis510938e2013-08-27 05:04:57 +00003643 case N_BNSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003644 // We use the current number of symbols in the symbol table in lieu of
3645 // using nlist_idx in case we ever start trimming entries out
3646 // Skip these if we want minimal symbol tables
3647 add_nlist = false;
3648 break;
3649
Charles Davis510938e2013-08-27 05:04:57 +00003650 case N_ENSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003651 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
3652 // so that we can always skip the entire symbol if we need to navigate
3653 // more quickly at the source level when parsing STABS
3654 // Skip these if we want minimal symbol tables
3655 add_nlist = false;
3656 break;
3657
3658
Charles Davis510938e2013-08-27 05:04:57 +00003659 case N_OPT:
3660 // emitted with gcc2_compiled and in gcc source
Greg Claytonfd814c52013-08-13 01:42:25 +00003661 type = eSymbolTypeCompiler;
3662 break;
3663
Charles Davis510938e2013-08-27 05:04:57 +00003664 case N_RSYM:
3665 // register sym: name,,NO_SECT,type,register
Greg Claytonfd814c52013-08-13 01:42:25 +00003666 type = eSymbolTypeVariable;
3667 break;
3668
Charles Davis510938e2013-08-27 05:04:57 +00003669 case N_SLINE:
3670 // src line: 0,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003671 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3672 type = eSymbolTypeLineEntry;
3673 break;
3674
Charles Davis510938e2013-08-27 05:04:57 +00003675 case N_SSYM:
3676 // structure elt: name,,NO_SECT,type,struct_offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003677 type = eSymbolTypeVariableType;
3678 break;
3679
Charles Davis510938e2013-08-27 05:04:57 +00003680 case N_SO:
3681 // source file name
Greg Claytonfd814c52013-08-13 01:42:25 +00003682 type = eSymbolTypeSourceFile;
3683 if (symbol_name == NULL)
3684 {
3685 add_nlist = false;
3686 if (N_SO_index != UINT32_MAX)
3687 {
3688 // Set the size of the N_SO to the terminating index of this N_SO
3689 // so that we can always skip the entire N_SO if we need to navigate
3690 // more quickly at the source level when parsing STABS
3691 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
3692 symbol_ptr->SetByteSize(sym_idx);
3693 symbol_ptr->SetSizeIsSibling(true);
3694 }
3695 N_NSYM_indexes.clear();
3696 N_INCL_indexes.clear();
3697 N_BRAC_indexes.clear();
3698 N_COMM_indexes.clear();
3699 N_FUN_indexes.clear();
3700 N_SO_index = UINT32_MAX;
3701 }
3702 else
3703 {
3704 // We use the current number of symbols in the symbol table in lieu of
3705 // using nlist_idx in case we ever start trimming entries out
3706 const bool N_SO_has_full_path = symbol_name[0] == '/';
3707 if (N_SO_has_full_path)
3708 {
3709 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3710 {
3711 // We have two consecutive N_SO entries where the first contains a directory
3712 // and the second contains a full path.
3713 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
3714 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3715 add_nlist = false;
3716 }
3717 else
3718 {
3719 // This is the first entry in a N_SO that contains a directory or
3720 // a full path to the source file
3721 N_SO_index = sym_idx;
3722 }
3723 }
3724 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3725 {
3726 // This is usually the second N_SO entry that contains just the filename,
3727 // so here we combine it with the first one if we are minimizing the symbol table
3728 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
3729 if (so_path && so_path[0])
3730 {
3731 std::string full_so_path (so_path);
3732 const size_t double_slash_pos = full_so_path.find("//");
3733 if (double_slash_pos != std::string::npos)
3734 {
3735 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003736 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Claytonfd814c52013-08-13 01:42:25 +00003737 // and the second is the directory for the source file so you end up with
3738 // a path that looks like "/tmp/src//tmp/src/"
3739 FileSpec so_dir(so_path, false);
3740 if (!so_dir.Exists())
3741 {
3742 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3743 if (so_dir.Exists())
3744 {
3745 // Trim off the incorrect path
3746 full_so_path.erase(0, double_slash_pos + 1);
3747 }
3748 }
3749 }
3750 if (*full_so_path.rbegin() != '/')
3751 full_so_path += '/';
3752 full_so_path += symbol_name;
3753 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
3754 add_nlist = false;
3755 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3756 }
3757 }
3758 else
3759 {
3760 // This could be a relative path to a N_SO
3761 N_SO_index = sym_idx;
3762 }
3763 }
3764
3765 break;
3766
Charles Davis510938e2013-08-27 05:04:57 +00003767 case N_OSO:
3768 // object file name: name,,0,0,st_mtime
Greg Claytonfd814c52013-08-13 01:42:25 +00003769 type = eSymbolTypeObjectFile;
3770 break;
3771
Charles Davis510938e2013-08-27 05:04:57 +00003772 case N_LSYM:
3773 // local sym: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003774 type = eSymbolTypeLocal;
3775 break;
3776
3777 //----------------------------------------------------------------------
3778 // INCL scopes
3779 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003780 case N_BINCL:
3781 // include file beginning: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00003782 // We use the current number of symbols in the symbol table in lieu of
3783 // using nlist_idx in case we ever start trimming entries out
3784 N_INCL_indexes.push_back(sym_idx);
3785 type = eSymbolTypeScopeBegin;
3786 break;
3787
Charles Davis510938e2013-08-27 05:04:57 +00003788 case N_EINCL:
3789 // include file end: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003790 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3791 // so that we can always skip the entire symbol if we need to navigate
3792 // more quickly at the source level when parsing STABS
3793 if ( !N_INCL_indexes.empty() )
3794 {
3795 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3796 symbol_ptr->SetByteSize(sym_idx + 1);
3797 symbol_ptr->SetSizeIsSibling(true);
3798 N_INCL_indexes.pop_back();
3799 }
3800 type = eSymbolTypeScopeEnd;
3801 break;
3802
Charles Davis510938e2013-08-27 05:04:57 +00003803 case N_SOL:
3804 // #included file name: name,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003805 type = eSymbolTypeHeaderFile;
3806
3807 // We currently don't use the header files on darwin
3808 add_nlist = false;
3809 break;
3810
Charles Davis510938e2013-08-27 05:04:57 +00003811 case N_PARAMS:
3812 // compiler parameters: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003813 type = eSymbolTypeCompiler;
3814 break;
3815
Charles Davis510938e2013-08-27 05:04:57 +00003816 case N_VERSION:
3817 // compiler version: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003818 type = eSymbolTypeCompiler;
3819 break;
3820
Charles Davis510938e2013-08-27 05:04:57 +00003821 case N_OLEVEL:
3822 // compiler -O level: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003823 type = eSymbolTypeCompiler;
3824 break;
3825
Charles Davis510938e2013-08-27 05:04:57 +00003826 case N_PSYM:
3827 // parameter: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003828 type = eSymbolTypeVariable;
3829 break;
3830
Charles Davis510938e2013-08-27 05:04:57 +00003831 case N_ENTRY:
3832 // alternate entry: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003833 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3834 type = eSymbolTypeLineEntry;
3835 break;
3836
3837 //----------------------------------------------------------------------
3838 // Left and Right Braces
3839 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003840 case N_LBRAC:
3841 // left bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003842 // We use the current number of symbols in the symbol table in lieu of
3843 // using nlist_idx in case we ever start trimming entries out
3844 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3845 N_BRAC_indexes.push_back(sym_idx);
3846 type = eSymbolTypeScopeBegin;
3847 break;
3848
Charles Davis510938e2013-08-27 05:04:57 +00003849 case N_RBRAC:
3850 // right bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003851 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
3852 // so that we can always skip the entire symbol if we need to navigate
3853 // more quickly at the source level when parsing STABS
3854 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3855 if ( !N_BRAC_indexes.empty() )
3856 {
3857 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
3858 symbol_ptr->SetByteSize(sym_idx + 1);
3859 symbol_ptr->SetSizeIsSibling(true);
3860 N_BRAC_indexes.pop_back();
3861 }
3862 type = eSymbolTypeScopeEnd;
3863 break;
3864
Charles Davis510938e2013-08-27 05:04:57 +00003865 case N_EXCL:
3866 // deleted include file: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00003867 type = eSymbolTypeHeaderFile;
3868 break;
3869
3870 //----------------------------------------------------------------------
3871 // COMM scopes
3872 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003873 case N_BCOMM:
3874 // begin common: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003875 // We use the current number of symbols in the symbol table in lieu of
3876 // using nlist_idx in case we ever start trimming entries out
3877 type = eSymbolTypeScopeBegin;
3878 N_COMM_indexes.push_back(sym_idx);
3879 break;
3880
Charles Davis510938e2013-08-27 05:04:57 +00003881 case N_ECOML:
3882 // end common (local name): 0,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003883 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3884 // Fall through
3885
Charles Davis510938e2013-08-27 05:04:57 +00003886 case N_ECOMM:
3887 // end common: name,,n_sect,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003888 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
3889 // so that we can always skip the entire symbol if we need to navigate
3890 // more quickly at the source level when parsing STABS
3891 if ( !N_COMM_indexes.empty() )
3892 {
3893 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
3894 symbol_ptr->SetByteSize(sym_idx + 1);
3895 symbol_ptr->SetSizeIsSibling(true);
3896 N_COMM_indexes.pop_back();
3897 }
3898 type = eSymbolTypeScopeEnd;
3899 break;
3900
Charles Davis510938e2013-08-27 05:04:57 +00003901 case N_LENG:
3902 // second stab entry with length information
Greg Claytonfd814c52013-08-13 01:42:25 +00003903 type = eSymbolTypeAdditional;
3904 break;
3905
3906 default: break;
3907 }
3908 }
3909 else
3910 {
Charles Davis510938e2013-08-27 05:04:57 +00003911 //uint8_t n_pext = N_PEXT & nlist.n_type;
3912 uint8_t n_type = N_TYPE & nlist.n_type;
3913 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00003914
3915 switch (n_type)
3916 {
Charles Davis510938e2013-08-27 05:04:57 +00003917 case N_INDR:// Fall through
3918 case N_PBUD:// Fall through
3919 case N_UNDF:
Greg Claytonfd814c52013-08-13 01:42:25 +00003920 type = eSymbolTypeUndefined;
3921 break;
3922
Charles Davis510938e2013-08-27 05:04:57 +00003923 case N_ABS:
Greg Claytonfd814c52013-08-13 01:42:25 +00003924 type = eSymbolTypeAbsolute;
3925 break;
3926
Charles Davis510938e2013-08-27 05:04:57 +00003927 case N_SECT:
Greg Claytonfd814c52013-08-13 01:42:25 +00003928 {
3929 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3930
3931 if (!symbol_section)
3932 {
3933 // TODO: warn about this?
3934 add_nlist = false;
3935 break;
3936 }
3937
3938 if (TEXT_eh_frame_sectID == nlist.n_sect)
3939 {
3940 type = eSymbolTypeException;
3941 }
3942 else
3943 {
Charles Davis510938e2013-08-27 05:04:57 +00003944 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Greg Claytonfd814c52013-08-13 01:42:25 +00003945
3946 switch (section_type)
3947 {
Charles Davis510938e2013-08-27 05:04:57 +00003948 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
3949 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
3950 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
3951 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
3952 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
3953 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
3954 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
3955 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
3956 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00003957 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
3958 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
3959 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
3960 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00003961 default:
3962 switch (symbol_section->GetType())
3963 {
3964 case lldb::eSectionTypeCode:
3965 type = eSymbolTypeCode;
3966 break;
3967 case eSectionTypeData:
3968 case eSectionTypeDataCString: // Inlined C string data
3969 case eSectionTypeDataCStringPointers: // Pointers to C string data
3970 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
3971 case eSectionTypeData4:
3972 case eSectionTypeData8:
3973 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00003974 type = eSymbolTypeData;
3975 break;
3976 default:
3977 break;
3978 }
3979 break;
Greg Claytonfd814c52013-08-13 01:42:25 +00003980 }
3981
3982 if (type == eSymbolTypeInvalid)
3983 {
3984 const char *symbol_sect_name = symbol_section->GetName().AsCString();
3985 if (symbol_section->IsDescendant (text_section_sp.get()))
3986 {
Charles Davis510938e2013-08-27 05:04:57 +00003987 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3988 S_ATTR_SELF_MODIFYING_CODE |
3989 S_ATTR_SOME_INSTRUCTIONS))
Greg Claytonfd814c52013-08-13 01:42:25 +00003990 type = eSymbolTypeData;
3991 else
3992 type = eSymbolTypeCode;
3993 }
3994 else
3995 if (symbol_section->IsDescendant(data_section_sp.get()))
3996 {
3997 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
3998 {
3999 type = eSymbolTypeRuntime;
4000
4001 if (symbol_name &&
4002 symbol_name[0] == '_' &&
4003 symbol_name[1] == 'O' &&
4004 symbol_name[2] == 'B')
4005 {
4006 llvm::StringRef symbol_name_ref(symbol_name);
4007 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
4008 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
4009 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
4010 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
4011 {
4012 symbol_name_non_abi_mangled = symbol_name + 1;
4013 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
4014 type = eSymbolTypeObjCClass;
4015 demangled_is_synthesized = true;
4016 }
4017 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
4018 {
4019 symbol_name_non_abi_mangled = symbol_name + 1;
4020 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
4021 type = eSymbolTypeObjCMetaClass;
4022 demangled_is_synthesized = true;
4023 }
4024 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
4025 {
4026 symbol_name_non_abi_mangled = symbol_name + 1;
4027 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
4028 type = eSymbolTypeObjCIVar;
4029 demangled_is_synthesized = true;
4030 }
4031 }
4032 }
4033 else
4034 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
4035 {
4036 type = eSymbolTypeException;
4037 }
4038 else
4039 {
4040 type = eSymbolTypeData;
4041 }
4042 }
4043 else
4044 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
4045 {
4046 type = eSymbolTypeTrampoline;
4047 }
4048 else
4049 if (symbol_section->IsDescendant(objc_section_sp.get()))
4050 {
4051 type = eSymbolTypeRuntime;
4052 if (symbol_name && symbol_name[0] == '.')
4053 {
4054 llvm::StringRef symbol_name_ref(symbol_name);
4055 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
4056 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
4057 {
4058 symbol_name_non_abi_mangled = symbol_name;
4059 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4060 type = eSymbolTypeObjCClass;
4061 demangled_is_synthesized = true;
4062 }
4063 }
4064 }
4065 }
4066 }
4067 }
4068 break;
Greg Claytondacc4a92013-05-14 22:19:37 +00004069 }
4070 }
4071
Greg Claytonfd814c52013-08-13 01:42:25 +00004072 if (add_nlist)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004073 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004074 uint64_t symbol_value = nlist.n_value;
4075
4076 if (symbol_name_non_abi_mangled)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004077 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004078 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
4079 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
4080 }
4081 else
4082 {
4083 bool symbol_name_is_mangled = false;
4084
4085 if (symbol_name && symbol_name[0] == '_')
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004086 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004087 symbol_name_is_mangled = symbol_name[1] == '_';
4088 symbol_name++; // Skip the leading underscore
4089 }
4090
4091 if (symbol_name)
4092 {
4093 ConstString const_symbol_name(symbol_name);
4094 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
4095 if (is_gsym && is_debug)
4096 {
4097 N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
4098 }
4099 }
4100 }
4101 if (symbol_section)
4102 {
4103 const addr_t section_file_addr = symbol_section->GetFileAddress();
4104 if (symbol_byte_size == 0 && function_starts_count > 0)
4105 {
4106 addr_t symbol_lookup_file_addr = nlist.n_value;
4107 // Do an exact address match for non-ARM addresses, else get the closest since
4108 // the symbol might be a thumb symbol which has an address with bit zero set
4109 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
4110 if (is_arm && func_start_entry)
4111 {
4112 // Verify that the function start address is the symbol address (ARM)
4113 // or the symbol address + 1 (thumb)
4114 if (func_start_entry->addr != symbol_lookup_file_addr &&
4115 func_start_entry->addr != (symbol_lookup_file_addr + 1))
4116 {
4117 // Not the right entry, NULL it out...
4118 func_start_entry = NULL;
4119 }
4120 }
4121 if (func_start_entry)
4122 {
4123 func_start_entry->data = true;
4124
4125 addr_t symbol_file_addr = func_start_entry->addr;
4126 if (is_arm)
4127 symbol_file_addr &= 0xfffffffffffffffeull;
4128
4129 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4130 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4131 if (next_func_start_entry)
4132 {
4133 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4134 // Be sure the clear the Thumb address bit when we calculate the size
4135 // from the current and next address
4136 if (is_arm)
4137 next_symbol_file_addr &= 0xfffffffffffffffeull;
4138 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
4139 }
4140 else
4141 {
4142 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4143 }
4144 }
4145 }
4146 symbol_value -= section_file_addr;
4147 }
4148
4149 if (is_debug == false)
4150 {
4151 if (type == eSymbolTypeCode)
4152 {
4153 // See if we can find a N_FUN entry for any code symbols.
4154 // If we do find a match, and the name matches, then we
4155 // can merge the two into just the function symbol to avoid
4156 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004157 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4158 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4159 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004160 {
Greg Claytond81088c2014-01-16 01:38:29 +00004161 bool found_it = false;
4162 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004163 {
Greg Claytond81088c2014-01-16 01:38:29 +00004164 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
4165 {
4166 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4167 // We just need the flags from the linker symbol, so put these flags
4168 // into the N_FUN flags to avoid duplicate symbols in the symbol table
4169 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4170 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4171 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
4172 sym[pos->second].SetType (eSymbolTypeResolver);
4173 sym[sym_idx].Clear();
4174 found_it = true;
4175 break;
4176 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004177 }
Greg Claytond81088c2014-01-16 01:38:29 +00004178 if (found_it)
4179 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004180 }
Jim Inghamea3ac272014-01-10 22:55:37 +00004181 else
4182 {
4183 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00004184 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00004185 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004186 }
4187 else if (type == eSymbolTypeData)
4188 {
4189 // See if we can find a N_STSYM entry for any data symbols.
4190 // If we do find a match, and the name matches, then we
4191 // can merge the two into just the Static symbol to avoid
4192 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004193 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4194 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4195 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004196 {
Greg Claytond81088c2014-01-16 01:38:29 +00004197 bool found_it = false;
4198 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004199 {
Greg Claytond81088c2014-01-16 01:38:29 +00004200 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
4201 {
4202 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4203 // We just need the flags from the linker symbol, so put these flags
4204 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
4205 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4206 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4207 sym[sym_idx].Clear();
4208 found_it = true;
4209 break;
4210 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004211 }
Greg Claytond81088c2014-01-16 01:38:29 +00004212 if (found_it)
4213 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004214 }
4215 else
4216 {
4217 // Combine N_GSYM stab entries with the non stab symbol
4218 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
4219 if (pos != N_GSYM_name_to_sym_idx.end())
4220 {
4221 const uint32_t GSYM_sym_idx = pos->second;
4222 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4223 // Copy the address, because often the N_GSYM address has an invalid address of zero
4224 // when the global is a common symbol
4225 sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
4226 sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
4227 // We just need the flags from the linker symbol, so put these flags
4228 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
4229 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4230 sym[sym_idx].Clear();
4231 continue;
4232 }
4233 }
4234 }
4235 }
4236
4237 sym[sym_idx].SetID (nlist_idx);
4238 sym[sym_idx].SetType (type);
4239 sym[sym_idx].GetAddress().SetSection (symbol_section);
4240 sym[sym_idx].GetAddress().SetOffset (symbol_value);
4241 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4242
4243 if (symbol_byte_size > 0)
4244 sym[sym_idx].SetByteSize(symbol_byte_size);
4245
4246 if (demangled_is_synthesized)
4247 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4248
4249 ++sym_idx;
4250 }
4251 else
4252 {
4253 sym[sym_idx].Clear();
4254 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004255 }
4256 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004257
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004258 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4259
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004260 if (function_starts_count > 0)
4261 {
4262 char synthetic_function_symbol[PATH_MAX];
4263 uint32_t num_synthetic_function_symbols = 0;
4264 for (i=0; i<function_starts_count; ++i)
4265 {
4266 if (function_starts.GetEntryRef (i).data == false)
4267 ++num_synthetic_function_symbols;
4268 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004269
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004270 if (num_synthetic_function_symbols > 0)
4271 {
4272 if (num_syms < sym_idx + num_synthetic_function_symbols)
4273 {
4274 num_syms = sym_idx + num_synthetic_function_symbols;
4275 sym = symtab->Resize (num_syms);
4276 }
4277 uint32_t synthetic_function_symbol_idx = 0;
4278 for (i=0; i<function_starts_count; ++i)
4279 {
4280 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
4281 if (func_start_entry->data == false)
4282 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004283 addr_t symbol_file_addr = func_start_entry->addr;
4284 uint32_t symbol_flags = 0;
4285 if (is_arm)
4286 {
4287 if (symbol_file_addr & 1)
4288 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
4289 symbol_file_addr &= 0xfffffffffffffffeull;
4290 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004291 Address symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004292 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004293 {
4294 SectionSP symbol_section (symbol_addr.GetSection());
4295 uint32_t symbol_byte_size = 0;
4296 if (symbol_section)
4297 {
4298 const addr_t section_file_addr = symbol_section->GetFileAddress();
4299 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4300 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4301 if (next_func_start_entry)
4302 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004303 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4304 if (is_arm)
4305 next_symbol_file_addr &= 0xfffffffffffffffeull;
4306 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004307 }
4308 else
4309 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004310 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004311 }
4312 snprintf (synthetic_function_symbol,
4313 sizeof(synthetic_function_symbol),
4314 "___lldb_unnamed_function%u$$%s",
4315 ++synthetic_function_symbol_idx,
4316 module_sp->GetFileSpec().GetFilename().GetCString());
4317 sym[sym_idx].SetID (synthetic_sym_id++);
Greg Clayton037520e2012-07-18 23:18:10 +00004318 sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004319 sym[sym_idx].SetType (eSymbolTypeCode);
4320 sym[sym_idx].SetIsSynthetic (true);
4321 sym[sym_idx].GetAddress() = symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004322 if (symbol_flags)
4323 sym[sym_idx].SetFlags (symbol_flags);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004324 if (symbol_byte_size)
4325 sym[sym_idx].SetByteSize (symbol_byte_size);
4326 ++sym_idx;
4327 }
4328 }
4329 }
4330 }
4331 }
4332 }
4333
4334 // Trim our symbols down to just what we ended up with after
4335 // removing any symbols.
4336 if (sym_idx < num_syms)
4337 {
4338 num_syms = sym_idx;
4339 sym = symtab->Resize (num_syms);
4340 }
4341
4342 // Now synthesize indirect symbols
4343 if (m_dysymtab.nindirectsyms != 0)
4344 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004345 if (indirect_symbol_index_data.GetByteSize())
4346 {
4347 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
4348
4349 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
4350 {
Charles Davis510938e2013-08-27 05:04:57 +00004351 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004352 {
4353 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4354 if (symbol_stub_byte_size == 0)
4355 continue;
4356
4357 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4358
4359 if (num_symbol_stubs == 0)
4360 continue;
4361
4362 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
4363 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
4364 {
4365 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
4366 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
Greg Claytonc7bece562013-01-25 18:06:21 +00004367 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004368 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
4369 {
4370 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
Charles Davis510938e2013-08-27 05:04:57 +00004371 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004372 continue;
4373
4374 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
4375 Symbol *stub_symbol = NULL;
4376 if (index_pos != end_index_pos)
4377 {
4378 // We have a remapping from the original nlist index to
4379 // a current symbol index, so just look this up by index
4380 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
4381 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004382 else
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004383 {
4384 // We need to lookup a symbol using the original nlist
Jason Molenda4e7511e2013-03-06 23:19:17 +00004385 // symbol index since this index is coming from the
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004386 // S_SYMBOL_STUBS
4387 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
4388 }
4389
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004390 if (stub_symbol)
4391 {
4392 Address so_addr(symbol_stub_addr, section_list);
4393
4394 if (stub_symbol->GetType() == eSymbolTypeUndefined)
4395 {
4396 // Change the external symbol into a trampoline that makes sense
4397 // These symbols were N_UNDF N_EXT, and are useless to us, so we
4398 // can re-use them so we don't have to make up a synthetic symbol
4399 // for no good reason.
Greg Clayton9191db42013-10-21 18:40:51 +00004400 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4401 stub_symbol->SetType (eSymbolTypeTrampoline);
4402 else
4403 stub_symbol->SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004404 stub_symbol->SetExternal (false);
4405 stub_symbol->GetAddress() = so_addr;
4406 stub_symbol->SetByteSize (symbol_stub_byte_size);
4407 }
4408 else
4409 {
4410 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda0a287e02012-04-24 02:09:58 +00004411 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004412 if (sym_idx >= num_syms)
Jason Molenda0a287e02012-04-24 02:09:58 +00004413 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004414 sym = symtab->Resize (++num_syms);
Jason Molenda0a287e02012-04-24 02:09:58 +00004415 stub_symbol = NULL; // this pointer no longer valid
4416 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004417 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda0a287e02012-04-24 02:09:58 +00004418 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton9191db42013-10-21 18:40:51 +00004419 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4420 sym[sym_idx].SetType (eSymbolTypeTrampoline);
4421 else
4422 sym[sym_idx].SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004423 sym[sym_idx].SetIsSynthetic (true);
4424 sym[sym_idx].GetAddress() = so_addr;
4425 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
4426 ++sym_idx;
4427 }
4428 }
Greg Clayton3f839a32012-09-05 01:38:55 +00004429 else
4430 {
4431 if (log)
4432 log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
4433 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004434 }
4435 }
4436 }
4437 }
4438 }
4439 }
Greg Clayton9191db42013-10-21 18:40:51 +00004440
4441
4442 if (!trie_entries.empty())
4443 {
4444 for (const auto &e : trie_entries)
4445 {
4446 if (e.entry.import_name)
4447 {
4448 // Make a synthetic symbol to describe re-exported symbol.
4449 if (sym_idx >= num_syms)
4450 sym = symtab->Resize (++num_syms);
4451 sym[sym_idx].SetID (synthetic_sym_id++);
4452 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4453 sym[sym_idx].SetType (eSymbolTypeReExported);
4454 sym[sym_idx].SetIsSynthetic (true);
4455 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4456 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
4457 {
4458 sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
4459 }
4460 ++sym_idx;
4461 }
4462 }
4463 }
4464
4465
Greg Clayton3046e662013-07-10 01:23:25 +00004466
4467// StreamFile s(stdout, false);
4468// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
4469// symtab->Dump(&s, NULL, eSortOrderNone);
4470 // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
4471 symtab->CalculateSymbolSizes();
4472
4473// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
4474// symtab->Dump(&s, NULL, eSortOrderNone);
4475
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004476 return symtab->GetNumSymbols();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004477 }
4478 return 0;
4479}
4480
4481
4482void
4483ObjectFileMachO::Dump (Stream *s)
4484{
Greg Claytona1743492012-03-13 23:14:29 +00004485 ModuleSP module_sp(GetModule());
4486 if (module_sp)
4487 {
4488 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004489 s->Printf("%p: ", static_cast<void*>(this));
Greg Claytona1743492012-03-13 23:14:29 +00004490 s->Indent();
Charles Davis510938e2013-08-27 05:04:57 +00004491 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
Greg Claytona1743492012-03-13 23:14:29 +00004492 s->PutCString("ObjectFileMachO64");
4493 else
4494 s->PutCString("ObjectFileMachO32");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004495
Greg Clayton7ab7f892014-05-29 21:33:45 +00004496 ArchSpec header_arch;
4497 GetArchitecture(header_arch);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004498
Greg Claytona1743492012-03-13 23:14:29 +00004499 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004500
Greg Clayton3046e662013-07-10 01:23:25 +00004501 SectionList *sections = GetSectionList();
4502 if (sections)
4503 sections->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004504
Greg Claytona1743492012-03-13 23:14:29 +00004505 if (m_symtab_ap.get())
4506 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
4507 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004508}
4509
Greg Claytonf4d6de62013-04-24 22:29:28 +00004510bool
4511ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header,
4512 const lldb_private::DataExtractor &data,
4513 lldb::offset_t lc_offset,
4514 lldb_private::UUID& uuid)
4515{
4516 uint32_t i;
4517 struct uuid_command load_cmd;
4518
4519 lldb::offset_t offset = lc_offset;
4520 for (i=0; i<header.ncmds; ++i)
4521 {
4522 const lldb::offset_t cmd_offset = offset;
4523 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4524 break;
4525
Charles Davis510938e2013-08-27 05:04:57 +00004526 if (load_cmd.cmd == LC_UUID)
Greg Claytonf4d6de62013-04-24 22:29:28 +00004527 {
4528 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4529
4530 if (uuid_bytes)
4531 {
4532 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4533 // We pretend these object files have no UUID to prevent crashing.
4534
4535 const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
4536 0x3b, 0xa8,
4537 0x4b, 0x16,
4538 0xb6, 0xa4,
4539 0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
4540
4541 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4542 return false;
4543
4544 uuid.SetBytes (uuid_bytes);
4545 return true;
4546 }
4547 return false;
4548 }
4549 offset = cmd_offset + load_cmd.cmdsize;
4550 }
4551 return false;
4552}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004553
Greg Clayton7ab7f892014-05-29 21:33:45 +00004554
4555bool
4556ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header,
4557 const lldb_private::DataExtractor &data,
4558 lldb::offset_t lc_offset,
4559 ArchSpec &arch)
4560{
4561 arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype);
4562
4563 if (arch.IsValid())
4564 {
4565 llvm::Triple &triple = arch.GetTriple();
4566 if (header.filetype == MH_PRELOAD)
4567 {
4568 // Set OS to "unknown" - this is a standalone binary with no dyld et al
4569 triple.setOS(llvm::Triple::UnknownOS);
4570 return true;
4571 }
4572 else
4573 {
4574 struct load_command load_cmd;
4575
4576 lldb::offset_t offset = lc_offset;
4577 for (uint32_t i=0; i<header.ncmds; ++i)
4578 {
4579 const lldb::offset_t cmd_offset = offset;
4580 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4581 break;
4582
4583 switch (load_cmd.cmd)
4584 {
4585 case LC_VERSION_MIN_IPHONEOS:
4586 triple.setOS (llvm::Triple::IOS);
4587 return true;
4588
4589 case LC_VERSION_MIN_MACOSX:
4590 triple.setOS (llvm::Triple::MacOSX);
4591 return true;
4592
4593 default:
4594 break;
4595 }
4596
4597 offset = cmd_offset + load_cmd.cmdsize;
4598 }
4599
Greg Claytona3a6c122014-07-29 18:04:57 +00004600 // Only set the OS to iOS for ARM, we don't want to set it for x86 and x86_64.
4601 // We do this because we now have MacOSX or iOS as the OS value for x86 and
4602 // x86_64 for normal desktop (MacOSX) and simulator (iOS) binaries. And if
4603 // we compare a "x86_64-apple-ios" to a "x86_64-apple-" triple, it will say
4604 // it is compatible (because the OS is unspecified in the second one and will
4605 // match anything in the first
Greg Clayton7ab7f892014-05-29 21:33:45 +00004606 if (header.cputype == CPU_TYPE_ARM || header.cputype == CPU_TYPE_ARM64)
4607 triple.setOS (llvm::Triple::IOS);
Greg Clayton7ab7f892014-05-29 21:33:45 +00004608 }
4609 }
4610 return arch.IsValid();
4611}
4612
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004613bool
Greg Clayton60830262011-02-04 18:53:10 +00004614ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004615{
Greg Claytona1743492012-03-13 23:14:29 +00004616 ModuleSP module_sp(GetModule());
4617 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004618 {
Greg Claytona1743492012-03-13 23:14:29 +00004619 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Claytonc7bece562013-01-25 18:06:21 +00004620 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +00004621 return GetUUID (m_header, m_data, offset, *uuid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004622 }
4623 return false;
4624}
4625
4626
4627uint32_t
4628ObjectFileMachO::GetDependentModules (FileSpecList& files)
4629{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004630 uint32_t count = 0;
Greg Claytona1743492012-03-13 23:14:29 +00004631 ModuleSP module_sp(GetModule());
4632 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004633 {
Greg Claytona1743492012-03-13 23:14:29 +00004634 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4635 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004636 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004637 const bool resolve_path = false; // Don't resolve the dependent file paths since they may not reside on this system
Greg Claytona1743492012-03-13 23:14:29 +00004638 uint32_t i;
4639 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004640 {
Greg Claytona1743492012-03-13 23:14:29 +00004641 const uint32_t cmd_offset = offset;
4642 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4643 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004644
Greg Claytona1743492012-03-13 23:14:29 +00004645 switch (load_cmd.cmd)
4646 {
Charles Davis510938e2013-08-27 05:04:57 +00004647 case LC_LOAD_DYLIB:
4648 case LC_LOAD_WEAK_DYLIB:
4649 case LC_REEXPORT_DYLIB:
4650 case LC_LOAD_DYLINKER:
4651 case LC_LOADFVMLIB:
4652 case LC_LOAD_UPWARD_DYLIB:
Greg Claytona1743492012-03-13 23:14:29 +00004653 {
4654 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
4655 const char *path = m_data.PeekCStr(name_offset);
4656 // Skip any path that starts with '@' since these are usually:
4657 // @executable_path/.../file
4658 // @rpath/.../file
4659 if (path && path[0] != '@')
4660 {
4661 FileSpec file_spec(path, resolve_path);
4662 if (files.AppendIfUnique(file_spec))
4663 count++;
4664 }
4665 }
4666 break;
4667
4668 default:
4669 break;
4670 }
4671 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004672 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004673 }
4674 return count;
4675}
4676
Jim Ingham672e6f52011-03-07 23:44:08 +00004677lldb_private::Address
Jason Molenda4e7511e2013-03-06 23:19:17 +00004678ObjectFileMachO::GetEntryPointAddress ()
Jim Ingham672e6f52011-03-07 23:44:08 +00004679{
4680 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
4681 // is initialized to an invalid address, so we can just return that.
4682 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
Jason Molenda4e7511e2013-03-06 23:19:17 +00004683
Jim Ingham672e6f52011-03-07 23:44:08 +00004684 if (!IsExecutable() || m_entry_point_address.IsValid())
4685 return m_entry_point_address;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004686
4687 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
Jim Ingham672e6f52011-03-07 23:44:08 +00004688 // /usr/include/mach-o.h, but it is basically:
4689 //
4690 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
4691 // uint32_t count - this is the count of longs in the thread state data
4692 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
4693 // <repeat this trio>
Jason Molenda4e7511e2013-03-06 23:19:17 +00004694 //
Jim Ingham672e6f52011-03-07 23:44:08 +00004695 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
4696 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
4697 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
4698 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
4699 //
4700 // For now we hard-code the offsets and flavors we need:
4701 //
4702 //
4703
Greg Claytona1743492012-03-13 23:14:29 +00004704 ModuleSP module_sp(GetModule());
4705 if (module_sp)
Jim Ingham672e6f52011-03-07 23:44:08 +00004706 {
Greg Claytona1743492012-03-13 23:14:29 +00004707 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4708 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004709 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00004710 uint32_t i;
4711 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
4712 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004713
Greg Claytona1743492012-03-13 23:14:29 +00004714 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham672e6f52011-03-07 23:44:08 +00004715 {
Greg Claytonc7bece562013-01-25 18:06:21 +00004716 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00004717 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4718 break;
4719
4720 switch (load_cmd.cmd)
Jim Ingham672e6f52011-03-07 23:44:08 +00004721 {
Charles Davis510938e2013-08-27 05:04:57 +00004722 case LC_UNIXTHREAD:
4723 case LC_THREAD:
Jim Ingham672e6f52011-03-07 23:44:08 +00004724 {
Greg Claytona1743492012-03-13 23:14:29 +00004725 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham672e6f52011-03-07 23:44:08 +00004726 {
Greg Claytona1743492012-03-13 23:14:29 +00004727 uint32_t flavor = m_data.GetU32(&offset);
4728 uint32_t count = m_data.GetU32(&offset);
4729 if (count == 0)
4730 {
4731 // We've gotten off somehow, log and exit;
4732 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00004733 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004734
Greg Claytona1743492012-03-13 23:14:29 +00004735 switch (m_header.cputype)
4736 {
Charles Davis510938e2013-08-27 05:04:57 +00004737 case llvm::MachO::CPU_TYPE_ARM:
Greg Claytona1743492012-03-13 23:14:29 +00004738 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
4739 {
4740 offset += 60; // This is the offset of pc in the GPR thread state data structure.
4741 start_address = m_data.GetU32(&offset);
4742 done = true;
4743 }
Jim Ingham672e6f52011-03-07 23:44:08 +00004744 break;
Jason Molendaa3329782014-03-29 18:54:20 +00004745 case llvm::MachO::CPU_TYPE_ARM64:
4746 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
4747 {
4748 offset += 256; // This is the offset of pc in the GPR thread state data structure.
4749 start_address = m_data.GetU64(&offset);
4750 done = true;
4751 }
4752 break;
Charles Davis510938e2013-08-27 05:04:57 +00004753 case llvm::MachO::CPU_TYPE_I386:
Greg Claytona1743492012-03-13 23:14:29 +00004754 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
4755 {
4756 offset += 40; // This is the offset of eip in the GPR thread state data structure.
4757 start_address = m_data.GetU32(&offset);
4758 done = true;
4759 }
4760 break;
Charles Davis510938e2013-08-27 05:04:57 +00004761 case llvm::MachO::CPU_TYPE_X86_64:
Greg Claytona1743492012-03-13 23:14:29 +00004762 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
4763 {
4764 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
4765 start_address = m_data.GetU64(&offset);
4766 done = true;
4767 }
4768 break;
4769 default:
4770 return m_entry_point_address;
4771 }
4772 // Haven't found the GPR flavor yet, skip over the data for this flavor:
4773 if (done)
4774 break;
4775 offset += count * 4;
4776 }
Jim Ingham672e6f52011-03-07 23:44:08 +00004777 }
Greg Claytona1743492012-03-13 23:14:29 +00004778 break;
Charles Davis510938e2013-08-27 05:04:57 +00004779 case LC_MAIN:
Sean Callanan226b70c2012-03-08 02:39:03 +00004780 {
Greg Claytona1743492012-03-13 23:14:29 +00004781 ConstString text_segment_name ("__TEXT");
4782 uint64_t entryoffset = m_data.GetU64(&offset);
4783 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
4784 if (text_segment_sp)
4785 {
4786 done = true;
4787 start_address = text_segment_sp->GetFileAddress() + entryoffset;
4788 }
Sean Callanan226b70c2012-03-08 02:39:03 +00004789 }
Greg Claytona1743492012-03-13 23:14:29 +00004790
4791 default:
4792 break;
Sean Callanan226b70c2012-03-08 02:39:03 +00004793 }
Greg Claytona1743492012-03-13 23:14:29 +00004794 if (done)
4795 break;
Jim Ingham672e6f52011-03-07 23:44:08 +00004796
Greg Claytona1743492012-03-13 23:14:29 +00004797 // Go to the next load command:
4798 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham672e6f52011-03-07 23:44:08 +00004799 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004800
Greg Claytona1743492012-03-13 23:14:29 +00004801 if (start_address != LLDB_INVALID_ADDRESS)
Greg Claytone72dfb32012-02-24 01:59:29 +00004802 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00004803 // We got the start address from the load commands, so now resolve that address in the sections
Greg Claytona1743492012-03-13 23:14:29 +00004804 // of this ObjectFile:
4805 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Claytone72dfb32012-02-24 01:59:29 +00004806 {
Greg Claytona1743492012-03-13 23:14:29 +00004807 m_entry_point_address.Clear();
4808 }
4809 }
4810 else
4811 {
4812 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
4813 // "start" symbol in the main executable.
Jason Molenda4e7511e2013-03-06 23:19:17 +00004814
Greg Claytona1743492012-03-13 23:14:29 +00004815 ModuleSP module_sp (GetModule());
Jason Molenda4e7511e2013-03-06 23:19:17 +00004816
Greg Claytona1743492012-03-13 23:14:29 +00004817 if (module_sp)
4818 {
4819 SymbolContextList contexts;
4820 SymbolContext context;
4821 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
4822 {
4823 if (contexts.GetContextAtIndex(0, context))
4824 m_entry_point_address = context.symbol->GetAddress();
4825 }
Greg Claytone72dfb32012-02-24 01:59:29 +00004826 }
4827 }
Jim Ingham672e6f52011-03-07 23:44:08 +00004828 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004829
Jim Ingham672e6f52011-03-07 23:44:08 +00004830 return m_entry_point_address;
4831
4832}
4833
Greg Claytonc9660542012-02-05 02:38:54 +00004834lldb_private::Address
4835ObjectFileMachO::GetHeaderAddress ()
4836{
4837 lldb_private::Address header_addr;
4838 SectionList *section_list = GetSectionList();
4839 if (section_list)
4840 {
4841 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
4842 if (text_segment_sp)
4843 {
Greg Claytone72dfb32012-02-24 01:59:29 +00004844 header_addr.SetSection (text_segment_sp);
Greg Claytonc9660542012-02-05 02:38:54 +00004845 header_addr.SetOffset (0);
4846 }
4847 }
4848 return header_addr;
4849}
4850
Greg Claytonc3776bf2012-02-09 06:16:32 +00004851uint32_t
4852ObjectFileMachO::GetNumThreadContexts ()
4853{
Greg Claytona1743492012-03-13 23:14:29 +00004854 ModuleSP module_sp(GetModule());
4855 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00004856 {
Greg Claytona1743492012-03-13 23:14:29 +00004857 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4858 if (!m_thread_context_offsets_valid)
Greg Claytonc3776bf2012-02-09 06:16:32 +00004859 {
Greg Claytona1743492012-03-13 23:14:29 +00004860 m_thread_context_offsets_valid = true;
Greg Claytonc7bece562013-01-25 18:06:21 +00004861 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00004862 FileRangeArray::Entry file_range;
4863 thread_command thread_cmd;
4864 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Claytonc3776bf2012-02-09 06:16:32 +00004865 {
Greg Claytona1743492012-03-13 23:14:29 +00004866 const uint32_t cmd_offset = offset;
4867 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
4868 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004869
Charles Davis510938e2013-08-27 05:04:57 +00004870 if (thread_cmd.cmd == LC_THREAD)
Greg Claytona1743492012-03-13 23:14:29 +00004871 {
4872 file_range.SetRangeBase (offset);
4873 file_range.SetByteSize (thread_cmd.cmdsize - 8);
4874 m_thread_context_offsets.Append (file_range);
4875 }
4876 offset = cmd_offset + thread_cmd.cmdsize;
Greg Claytonc3776bf2012-02-09 06:16:32 +00004877 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00004878 }
4879 }
4880 return m_thread_context_offsets.GetSize();
4881}
4882
4883lldb::RegisterContextSP
4884ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
4885{
Greg Claytonc3776bf2012-02-09 06:16:32 +00004886 lldb::RegisterContextSP reg_ctx_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +00004887
Greg Claytona1743492012-03-13 23:14:29 +00004888 ModuleSP module_sp(GetModule());
4889 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00004890 {
Greg Claytona1743492012-03-13 23:14:29 +00004891 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4892 if (!m_thread_context_offsets_valid)
4893 GetNumThreadContexts ();
4894
4895 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
Jim Ingham28eb5712012-10-12 17:34:26 +00004896 if (thread_context_file_range)
Greg Claytona1743492012-03-13 23:14:29 +00004897 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00004898
4899 DataExtractor data (m_data,
4900 thread_context_file_range->GetRangeBase(),
Jim Ingham28eb5712012-10-12 17:34:26 +00004901 thread_context_file_range->GetByteSize());
4902
4903 switch (m_header.cputype)
4904 {
Jason Molendaa3329782014-03-29 18:54:20 +00004905 case llvm::MachO::CPU_TYPE_ARM64:
4906 reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
4907 break;
4908
Charles Davis510938e2013-08-27 05:04:57 +00004909 case llvm::MachO::CPU_TYPE_ARM:
Jim Ingham28eb5712012-10-12 17:34:26 +00004910 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
4911 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004912
Charles Davis510938e2013-08-27 05:04:57 +00004913 case llvm::MachO::CPU_TYPE_I386:
Jim Ingham28eb5712012-10-12 17:34:26 +00004914 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
4915 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004916
Charles Davis510938e2013-08-27 05:04:57 +00004917 case llvm::MachO::CPU_TYPE_X86_64:
Jim Ingham28eb5712012-10-12 17:34:26 +00004918 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
4919 break;
4920 }
Greg Claytona1743492012-03-13 23:14:29 +00004921 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00004922 }
4923 return reg_ctx_sp;
4924}
4925
Greg Claytonc9660542012-02-05 02:38:54 +00004926
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004927ObjectFile::Type
4928ObjectFileMachO::CalculateType()
4929{
4930 switch (m_header.filetype)
4931 {
Charles Davis510938e2013-08-27 05:04:57 +00004932 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004933 if (GetAddressByteSize () == 4)
4934 {
4935 // 32 bit kexts are just object files, but they do have a valid
4936 // UUID load command.
4937 UUID uuid;
4938 if (GetUUID(&uuid))
4939 {
4940 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00004941 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004942 // "OSKextGetCurrentIdentifier" as this is required of kexts
4943 if (m_strata == eStrataInvalid)
4944 m_strata = eStrataKernel;
4945 return eTypeSharedLibrary;
4946 }
4947 }
4948 return eTypeObjectFile;
4949
Charles Davis510938e2013-08-27 05:04:57 +00004950 case MH_EXECUTE: return eTypeExecutable; // 0x2u
4951 case MH_FVMLIB: return eTypeSharedLibrary; // 0x3u
4952 case MH_CORE: return eTypeCoreFile; // 0x4u
4953 case MH_PRELOAD: return eTypeSharedLibrary; // 0x5u
4954 case MH_DYLIB: return eTypeSharedLibrary; // 0x6u
4955 case MH_DYLINKER: return eTypeDynamicLinker; // 0x7u
4956 case MH_BUNDLE: return eTypeSharedLibrary; // 0x8u
4957 case MH_DYLIB_STUB: return eTypeStubLibrary; // 0x9u
4958 case MH_DSYM: return eTypeDebugInfo; // 0xAu
4959 case MH_KEXT_BUNDLE: return eTypeSharedLibrary; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004960 default:
4961 break;
4962 }
4963 return eTypeUnknown;
4964}
4965
4966ObjectFile::Strata
4967ObjectFileMachO::CalculateStrata()
4968{
4969 switch (m_header.filetype)
4970 {
Charles Davis510938e2013-08-27 05:04:57 +00004971 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004972 {
4973 // 32 bit kexts are just object files, but they do have a valid
4974 // UUID load command.
4975 UUID uuid;
4976 if (GetUUID(&uuid))
4977 {
4978 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00004979 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004980 // "OSKextGetCurrentIdentifier" as this is required of kexts
4981 if (m_type == eTypeInvalid)
4982 m_type = eTypeSharedLibrary;
4983
4984 return eStrataKernel;
4985 }
4986 }
4987 return eStrataUnknown;
4988
Charles Davis510938e2013-08-27 05:04:57 +00004989 case MH_EXECUTE: // 0x2u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004990 // Check for the MH_DYLDLINK bit in the flags
Charles Davis510938e2013-08-27 05:04:57 +00004991 if (m_header.flags & MH_DYLDLINK)
Sean Callanan49bce8e2012-02-10 20:22:35 +00004992 {
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004993 return eStrataUser;
Sean Callanan49bce8e2012-02-10 20:22:35 +00004994 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004995 else
Sean Callanan49bce8e2012-02-10 20:22:35 +00004996 {
4997 SectionList *section_list = GetSectionList();
4998 if (section_list)
4999 {
5000 static ConstString g_kld_section_name ("__KLD");
5001 if (section_list->FindSectionByName(g_kld_section_name))
5002 return eStrataKernel;
5003 }
5004 }
5005 return eStrataRawImage;
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005006
Charles Davis510938e2013-08-27 05:04:57 +00005007 case MH_FVMLIB: return eStrataUser; // 0x3u
5008 case MH_CORE: return eStrataUnknown; // 0x4u
5009 case MH_PRELOAD: return eStrataRawImage; // 0x5u
5010 case MH_DYLIB: return eStrataUser; // 0x6u
5011 case MH_DYLINKER: return eStrataUser; // 0x7u
5012 case MH_BUNDLE: return eStrataUser; // 0x8u
5013 case MH_DYLIB_STUB: return eStrataUser; // 0x9u
5014 case MH_DSYM: return eStrataUnknown; // 0xAu
5015 case MH_KEXT_BUNDLE: return eStrataKernel; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005016 default:
5017 break;
5018 }
5019 return eStrataUnknown;
5020}
5021
5022
Greg Claytonc2ff9312012-02-22 19:41:02 +00005023uint32_t
5024ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
5025{
Greg Claytona1743492012-03-13 23:14:29 +00005026 ModuleSP module_sp(GetModule());
5027 if (module_sp)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005028 {
Greg Claytona1743492012-03-13 23:14:29 +00005029 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5030 struct dylib_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00005031 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005032 uint32_t version_cmd = 0;
5033 uint64_t version = 0;
5034 uint32_t i;
5035 for (i=0; i<m_header.ncmds; ++i)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005036 {
Greg Claytonc7bece562013-01-25 18:06:21 +00005037 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00005038 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
5039 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005040
Charles Davis510938e2013-08-27 05:04:57 +00005041 if (load_cmd.cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005042 {
Greg Claytona1743492012-03-13 23:14:29 +00005043 if (version_cmd == 0)
5044 {
5045 version_cmd = load_cmd.cmd;
5046 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
5047 break;
5048 version = load_cmd.dylib.current_version;
5049 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005050 break; // Break for now unless there is another more complete version
Greg Claytona1743492012-03-13 23:14:29 +00005051 // number load command in the future.
Greg Claytonc2ff9312012-02-22 19:41:02 +00005052 }
Greg Claytona1743492012-03-13 23:14:29 +00005053 offset = cmd_offset + load_cmd.cmdsize;
Greg Claytonc2ff9312012-02-22 19:41:02 +00005054 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005055
Charles Davis510938e2013-08-27 05:04:57 +00005056 if (version_cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005057 {
Greg Claytona1743492012-03-13 23:14:29 +00005058 if (versions != NULL && num_versions > 0)
5059 {
5060 if (num_versions > 0)
5061 versions[0] = (version & 0xFFFF0000ull) >> 16;
5062 if (num_versions > 1)
5063 versions[1] = (version & 0x0000FF00ull) >> 8;
5064 if (num_versions > 2)
5065 versions[2] = (version & 0x000000FFull);
5066 // Fill in an remaining version numbers with invalid values
5067 for (i=3; i<num_versions; ++i)
5068 versions[i] = UINT32_MAX;
5069 }
5070 // The LC_ID_DYLIB load command has a version with 3 version numbers
5071 // in it, so always return 3
5072 return 3;
Greg Claytonc2ff9312012-02-22 19:41:02 +00005073 }
Greg Claytonc2ff9312012-02-22 19:41:02 +00005074 }
5075 return false;
5076}
5077
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005078bool
Greg Clayton514487e2011-02-15 21:59:32 +00005079ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005080{
Greg Claytona1743492012-03-13 23:14:29 +00005081 ModuleSP module_sp(GetModule());
5082 if (module_sp)
Greg Clayton593577a2011-09-21 03:57:31 +00005083 {
Greg Claytona1743492012-03-13 23:14:29 +00005084 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Clayton7ab7f892014-05-29 21:33:45 +00005085 return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch);
Greg Clayton593577a2011-09-21 03:57:31 +00005086 }
Greg Claytona1743492012-03-13 23:14:29 +00005087 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005088}
5089
5090
Jason Molenda0e0954c2013-04-16 06:24:42 +00005091UUID
5092ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
5093{
5094 UUID uuid;
5095 if (process)
5096 {
5097 addr_t all_image_infos = process->GetImageInfoAddress();
5098
5099 // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
5100 // or it may be the address of the dyld_all_image_infos structure (want). The first four
5101 // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
5102 // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
5103
5104 Error err;
5105 uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00005106 if (version_or_magic != static_cast<uint32_t>(-1)
Charles Davis510938e2013-08-27 05:04:57 +00005107 && version_or_magic != MH_MAGIC
5108 && version_or_magic != MH_CIGAM
5109 && version_or_magic != MH_MAGIC_64
5110 && version_or_magic != MH_CIGAM_64
Jason Molenda0e0954c2013-04-16 06:24:42 +00005111 && version_or_magic >= 13)
5112 {
5113 addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
5114 int wordsize = process->GetAddressByteSize();
5115 if (wordsize == 8)
5116 {
5117 sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
5118 }
5119 if (wordsize == 4)
5120 {
5121 sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
5122 }
5123 if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
5124 {
5125 uuid_t shared_cache_uuid;
5126 if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
5127 {
5128 uuid.SetBytes (shared_cache_uuid);
5129 }
5130 }
5131 }
5132 }
5133 return uuid;
5134}
5135
5136UUID
5137ObjectFileMachO::GetLLDBSharedCacheUUID ()
5138{
5139 UUID uuid;
Todd Fiala013434e2014-07-09 01:29:05 +00005140#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +00005141 uint8_t *(*dyld_get_all_image_infos)(void);
5142 dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
5143 if (dyld_get_all_image_infos)
5144 {
5145 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5146 if (dyld_all_image_infos_address)
5147 {
Jason Molendac9cb7d22013-04-16 21:42:58 +00005148 uint32_t *version = (uint32_t*) dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5149 if (*version >= 13)
Jason Molenda0e0954c2013-04-16 06:24:42 +00005150 {
Jason Molendaa3329782014-03-29 18:54:20 +00005151 uuid_t *sharedCacheUUID_address = 0;
5152 int wordsize = sizeof (uint8_t *);
5153 if (wordsize == 8)
5154 {
5155 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
5156 }
5157 else
5158 {
5159 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84); // sharedCacheUUID <mach-o/dyld_images.h>
5160 }
Jason Molenda0e0954c2013-04-16 06:24:42 +00005161 uuid.SetBytes (sharedCacheUUID_address);
5162 }
5163 }
5164 }
5165#endif
5166 return uuid;
5167}
5168
Greg Clayton9b234982013-10-24 22:54:08 +00005169uint32_t
5170ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
5171{
5172 if (m_min_os_versions.empty())
5173 {
5174 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5175 bool success = false;
5176 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5177 {
5178 const lldb::offset_t load_cmd_offset = offset;
5179
5180 version_min_command lc;
5181 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5182 break;
5183 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5184 {
5185 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5186 {
5187 const uint32_t xxxx = lc.version >> 16;
5188 const uint32_t yy = (lc.version >> 8) & 0xffu;
5189 const uint32_t zz = lc.version & 0xffu;
5190 if (xxxx)
5191 {
5192 m_min_os_versions.push_back(xxxx);
5193 if (yy)
5194 {
5195 m_min_os_versions.push_back(yy);
5196 if (zz)
5197 m_min_os_versions.push_back(zz);
5198 }
5199 }
5200 success = true;
5201 }
5202 }
5203 offset = load_cmd_offset + lc.cmdsize;
5204 }
5205
5206 if (success == false)
5207 {
5208 // Push an invalid value so we don't keep trying to
5209 m_min_os_versions.push_back(UINT32_MAX);
5210 }
5211 }
5212
5213 if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
5214 {
5215 if (versions != NULL && num_versions > 0)
5216 {
5217 for (size_t i=0; i<num_versions; ++i)
5218 {
5219 if (i < m_min_os_versions.size())
5220 versions[i] = m_min_os_versions[i];
5221 else
5222 versions[i] = 0;
5223 }
5224 }
5225 return m_min_os_versions.size();
5226 }
5227 // Call the superclasses version that will empty out the data
5228 return ObjectFile::GetMinimumOSVersion (versions, num_versions);
5229}
5230
5231uint32_t
5232ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions)
5233{
5234 if (m_sdk_versions.empty())
5235 {
5236 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5237 bool success = false;
5238 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5239 {
5240 const lldb::offset_t load_cmd_offset = offset;
5241
5242 version_min_command lc;
5243 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5244 break;
5245 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5246 {
5247 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5248 {
Todd Fialaebecb382014-09-04 19:31:52 +00005249 const uint32_t xxxx = lc.sdk >> 16;
5250 const uint32_t yy = (lc.sdk >> 8) & 0xffu;
5251 const uint32_t zz = lc.sdk & 0xffu;
Greg Clayton9b234982013-10-24 22:54:08 +00005252 if (xxxx)
5253 {
5254 m_sdk_versions.push_back(xxxx);
5255 if (yy)
5256 {
5257 m_sdk_versions.push_back(yy);
5258 if (zz)
5259 m_sdk_versions.push_back(zz);
5260 }
5261 }
5262 success = true;
5263 }
5264 }
5265 offset = load_cmd_offset + lc.cmdsize;
5266 }
5267
5268 if (success == false)
5269 {
5270 // Push an invalid value so we don't keep trying to
5271 m_sdk_versions.push_back(UINT32_MAX);
5272 }
5273 }
5274
5275 if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
5276 {
5277 if (versions != NULL && num_versions > 0)
5278 {
5279 for (size_t i=0; i<num_versions; ++i)
5280 {
5281 if (i < m_sdk_versions.size())
5282 versions[i] = m_sdk_versions[i];
5283 else
5284 versions[i] = 0;
5285 }
5286 }
5287 return m_sdk_versions.size();
5288 }
5289 // Call the superclasses version that will empty out the data
5290 return ObjectFile::GetSDKVersion (versions, num_versions);
5291}
5292
Jason Molenda0e0954c2013-04-16 06:24:42 +00005293
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005294//------------------------------------------------------------------
5295// PluginInterface protocol
5296//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00005297lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005298ObjectFileMachO::GetPluginName()
5299{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005300 return GetPluginNameStatic();
5301}
5302
5303uint32_t
5304ObjectFileMachO::GetPluginVersion()
5305{
5306 return 1;
5307}
5308
Greg Clayton7524e092014-02-06 20:10:16 +00005309
5310bool
Greg Clayton751caf62014-02-07 22:54:47 +00005311ObjectFileMachO::SetLoadAddress (Target &target,
5312 lldb::addr_t value,
5313 bool value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005314{
Greg Clayton7524e092014-02-06 20:10:16 +00005315 ModuleSP module_sp = GetModule();
5316 if (module_sp)
5317 {
5318 size_t num_loaded_sections = 0;
5319 SectionList *section_list = GetSectionList ();
5320 if (section_list)
5321 {
5322 lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
5323 const size_t num_sections = section_list->GetSize();
5324
Greg Clayton751caf62014-02-07 22:54:47 +00005325 const bool is_memory_image = (bool)m_process_wp.lock();
5326 const Strata strata = GetStrata();
5327 static ConstString g_linkedit_segname ("__LINKEDIT");
5328 if (value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005329 {
Greg Clayton751caf62014-02-07 22:54:47 +00005330 // "value" is an offset to apply to each top level segment
Greg Clayton7524e092014-02-06 20:10:16 +00005331 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5332 {
5333 // Iterate through the object file sections to find all
5334 // of the sections that size on disk (to avoid __PAGEZERO)
5335 // and load them
5336 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton751caf62014-02-07 22:54:47 +00005337 if (section_sp &&
5338 section_sp->GetFileSize() > 0 &&
5339 section_sp->IsThreadSpecific() == false &&
5340 module_sp.get() == section_sp->GetModule().get())
Greg Clayton7524e092014-02-06 20:10:16 +00005341 {
Greg Clayton751caf62014-02-07 22:54:47 +00005342 // Ignore __LINKEDIT and __DWARF segments
5343 if (section_sp->GetName() == g_linkedit_segname)
5344 {
5345 // Only map __LINKEDIT if we have an in memory image and this isn't
5346 // a kernel binary like a kext or mach_kernel.
5347 if (is_memory_image == false || strata == eStrataKernel)
5348 continue;
5349 }
5350 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
Greg Clayton7524e092014-02-06 20:10:16 +00005351 ++num_loaded_sections;
5352 }
5353 }
5354 }
Greg Clayton751caf62014-02-07 22:54:47 +00005355 else
5356 {
5357 // "value" is the new base address of the mach_header, adjust each
5358 // section accordingly
5359
5360 // First find the address of the mach header which is the first non-zero
5361 // file sized section whose file offset is zero as this will be subtracted
5362 // from each other valid section's vmaddr and then get "base_addr" added to
5363 // it when loading the module in the target
5364 for (size_t sect_idx = 0;
5365 sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
5366 ++sect_idx)
5367 {
5368 // Iterate through the object file sections to find all
5369 // of the sections that size on disk (to avoid __PAGEZERO)
5370 // and load them
5371 Section *section = section_list->GetSectionAtIndex (sect_idx).get();
5372 if (section &&
5373 section->GetFileSize() > 0 &&
5374 section->GetFileOffset() == 0 &&
5375 section->IsThreadSpecific() == false &&
5376 module_sp.get() == section->GetModule().get())
5377 {
5378 // Ignore __LINKEDIT and __DWARF segments
5379 if (section->GetName() == g_linkedit_segname)
5380 {
5381 // Only map __LINKEDIT if we have an in memory image and this isn't
5382 // a kernel binary like a kext or mach_kernel.
5383 if (is_memory_image == false || strata == eStrataKernel)
5384 continue;
5385 }
5386 mach_base_file_addr = section->GetFileAddress();
5387 }
5388 }
5389
5390 if (mach_base_file_addr != LLDB_INVALID_ADDRESS)
5391 {
5392 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5393 {
5394 // Iterate through the object file sections to find all
5395 // of the sections that size on disk (to avoid __PAGEZERO)
5396 // and load them
5397 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
5398 if (section_sp &&
5399 section_sp->GetFileSize() > 0 &&
5400 section_sp->IsThreadSpecific() == false &&
5401 module_sp.get() == section_sp->GetModule().get())
5402 {
5403 // Ignore __LINKEDIT and __DWARF segments
5404 if (section_sp->GetName() == g_linkedit_segname)
5405 {
5406 // Only map __LINKEDIT if we have an in memory image and this isn't
5407 // a kernel binary like a kext or mach_kernel.
5408 if (is_memory_image == false || strata == eStrataKernel)
5409 continue;
5410 }
5411 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() - mach_base_file_addr + value))
5412 ++num_loaded_sections;
5413 }
5414 }
5415 }
5416 }
Greg Clayton7524e092014-02-06 20:10:16 +00005417 }
Greg Clayton7524e092014-02-06 20:10:16 +00005418 return num_loaded_sections > 0;
5419 }
Jason Molenda5cf1e232014-10-16 07:41:32 +00005420 return false;
Greg Clayton7524e092014-02-06 20:10:16 +00005421}
5422
Greg Claytona2715cf2014-06-13 00:54:12 +00005423bool
5424ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp,
5425 const FileSpec &outfile,
5426 Error &error)
5427{
5428 if (process_sp)
5429 {
5430 Target &target = process_sp->GetTarget();
5431 const ArchSpec target_arch = target.GetArchitecture();
5432 const llvm::Triple &target_triple = target_arch.GetTriple();
5433 if (target_triple.getVendor() == llvm::Triple::Apple &&
5434 (target_triple.getOS() == llvm::Triple::MacOSX ||
5435 target_triple.getOS() == llvm::Triple::IOS))
5436 {
5437 bool make_core = false;
5438 switch (target_arch.GetMachine())
5439 {
Jason Molenda22952582014-11-12 01:11:36 +00005440 // arm and arm64 core file writing is having some problem with writing
5441 // down the dyld shared images info struct and/or the main executable binary.
5442// case llvm::Triple::arm:
5443// case llvm::Triple::aarch64:
5444
Greg Claytona2715cf2014-06-13 00:54:12 +00005445 case llvm::Triple::x86:
5446 case llvm::Triple::x86_64:
5447 make_core = true;
5448 break;
5449 default:
5450 error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str());
5451 break;
5452 }
5453
5454 if (make_core)
5455 {
5456 std::vector<segment_command_64> segment_load_commands;
Saleem Abdulrasool3924d752014-06-13 03:30:39 +00005457// uint32_t range_info_idx = 0;
Greg Claytona2715cf2014-06-13 00:54:12 +00005458 MemoryRegionInfo range_info;
5459 Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
Jason Molendad20359d2014-11-11 10:59:15 +00005460 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
5461 const ByteOrder byte_order = target_arch.GetByteOrder();
Greg Claytona2715cf2014-06-13 00:54:12 +00005462 if (range_error.Success())
5463 {
5464 while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS)
5465 {
5466 const addr_t addr = range_info.GetRange().GetRangeBase();
5467 const addr_t size = range_info.GetRange().GetByteSize();
5468
5469 if (size == 0)
5470 break;
5471
5472 // Calculate correct protections
5473 uint32_t prot = 0;
5474 if (range_info.GetReadable() == MemoryRegionInfo::eYes)
5475 prot |= VM_PROT_READ;
5476 if (range_info.GetWritable() == MemoryRegionInfo::eYes)
5477 prot |= VM_PROT_WRITE;
5478 if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
5479 prot |= VM_PROT_EXECUTE;
5480
5481// printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n",
5482// range_info_idx,
5483// addr,
5484// size,
5485// (prot & VM_PROT_READ ) ? 'r' : '-',
5486// (prot & VM_PROT_WRITE ) ? 'w' : '-',
5487// (prot & VM_PROT_EXECUTE) ? 'x' : '-');
5488
5489 if (prot != 0)
5490 {
Jason Molendad20359d2014-11-11 10:59:15 +00005491 uint32_t cmd_type = LC_SEGMENT_64;
5492 uint32_t segment_size = sizeof (segment_command_64);
5493 if (addr_byte_size == 4)
5494 {
5495 cmd_type = LC_SEGMENT;
5496 segment_size = sizeof (segment_command);
5497 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005498 segment_command_64 segment = {
Jason Molendad20359d2014-11-11 10:59:15 +00005499 cmd_type, // uint32_t cmd;
5500 segment_size, // uint32_t cmdsize;
Greg Claytona2715cf2014-06-13 00:54:12 +00005501 {0}, // char segname[16];
Jason Molendad20359d2014-11-11 10:59:15 +00005502 addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
5503 size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
5504 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
5505 size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
Greg Claytona2715cf2014-06-13 00:54:12 +00005506 prot, // uint32_t maxprot;
5507 prot, // uint32_t initprot;
5508 0, // uint32_t nsects;
5509 0 }; // uint32_t flags;
5510 segment_load_commands.push_back(segment);
5511 }
5512 else
5513 {
5514 // No protections and a size of 1 used to be returned from old
5515 // debugservers when we asked about a region that was past the
5516 // last memory region and it indicates the end...
5517 if (size == 1)
5518 break;
5519 }
5520
5521 range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info);
5522 if (range_error.Fail())
5523 break;
5524 }
5525
Greg Claytona2715cf2014-06-13 00:54:12 +00005526 StreamString buffer (Stream::eBinary,
5527 addr_byte_size,
5528 byte_order);
5529
5530 mach_header_64 mach_header;
Jason Molendad20359d2014-11-11 10:59:15 +00005531 if (addr_byte_size == 8)
5532 {
5533 mach_header.magic = MH_MAGIC_64;
5534 }
5535 else
5536 {
5537 mach_header.magic = MH_MAGIC;
5538 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005539 mach_header.cputype = target_arch.GetMachOCPUType();
5540 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
5541 mach_header.filetype = MH_CORE;
5542 mach_header.ncmds = segment_load_commands.size();
5543 mach_header.flags = 0;
5544 mach_header.reserved = 0;
5545 ThreadList &thread_list = process_sp->GetThreadList();
5546 const uint32_t num_threads = thread_list.GetSize();
5547
5548 // Make an array of LC_THREAD data items. Each one contains
5549 // the contents of the LC_THREAD load command. The data doesn't
5550 // contain the load command + load command size, we will
5551 // add the load command and load command size as we emit the data.
5552 std::vector<StreamString> LC_THREAD_datas(num_threads);
5553 for (auto &LC_THREAD_data : LC_THREAD_datas)
5554 {
5555 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
5556 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
5557 LC_THREAD_data.SetByteOrder(byte_order);
5558 }
5559 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
5560 {
5561 ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx));
5562 if (thread_sp)
5563 {
5564 switch (mach_header.cputype)
5565 {
Jason Molenda22952582014-11-12 01:11:36 +00005566 case llvm::MachO::CPU_TYPE_ARM64:
5567 RegisterContextDarwin_arm64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005568 break;
Jason Molenda22952582014-11-12 01:11:36 +00005569
5570 case llvm::MachO::CPU_TYPE_ARM:
5571 RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5572 break;
5573
Greg Claytona2715cf2014-06-13 00:54:12 +00005574 case llvm::MachO::CPU_TYPE_I386:
Jason Molendad20359d2014-11-11 10:59:15 +00005575 RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005576 break;
5577
5578 case llvm::MachO::CPU_TYPE_X86_64:
5579 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5580 break;
5581 }
5582
5583 }
5584 }
5585
5586 // The size of the load command is the size of the segments...
Jason Molendad20359d2014-11-11 10:59:15 +00005587 if (addr_byte_size == 8)
5588 {
5589 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64);
5590 }
5591 else
5592 {
5593 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command);
5594 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005595
5596 // and the size of all LC_THREAD load command
5597 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5598 {
Greg Claytone37df2e2014-09-16 20:50:29 +00005599 ++mach_header.ncmds;
Greg Claytona2715cf2014-06-13 00:54:12 +00005600 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
5601 }
5602
5603 printf ("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
5604 mach_header.magic,
5605 mach_header.cputype,
5606 mach_header.cpusubtype,
5607 mach_header.filetype,
5608 mach_header.ncmds,
5609 mach_header.sizeofcmds,
5610 mach_header.flags,
5611 mach_header.reserved);
5612
5613 // Write the mach header
5614 buffer.PutHex32(mach_header.magic);
5615 buffer.PutHex32(mach_header.cputype);
5616 buffer.PutHex32(mach_header.cpusubtype);
5617 buffer.PutHex32(mach_header.filetype);
5618 buffer.PutHex32(mach_header.ncmds);
5619 buffer.PutHex32(mach_header.sizeofcmds);
5620 buffer.PutHex32(mach_header.flags);
Jason Molendad20359d2014-11-11 10:59:15 +00005621 if (addr_byte_size == 8)
5622 {
5623 buffer.PutHex32(mach_header.reserved);
5624 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005625
5626 // Skip the mach header and all load commands and align to the next
5627 // 0x1000 byte boundary
5628 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
5629 if (file_offset & 0x00000fff)
5630 {
5631 file_offset += 0x00001000ull;
5632 file_offset &= (~0x00001000ull + 1);
5633 }
5634
5635 for (auto &segment : segment_load_commands)
5636 {
5637 segment.fileoff = file_offset;
5638 file_offset += segment.filesize;
5639 }
5640
5641 // Write out all of the LC_THREAD load commands
5642 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5643 {
5644 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
5645 buffer.PutHex32(LC_THREAD);
5646 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
5647 buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size);
5648 }
5649
5650 // Write out all of the segment load commands
5651 for (const auto &segment : segment_load_commands)
5652 {
5653 printf ("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64 ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n",
5654 segment.cmd,
5655 segment.cmdsize,
5656 segment.vmaddr,
5657 segment.vmaddr + segment.vmsize,
5658 segment.fileoff,
5659 segment.filesize,
5660 segment.maxprot,
5661 segment.initprot,
5662 segment.nsects,
5663 segment.flags);
5664
5665 buffer.PutHex32(segment.cmd);
5666 buffer.PutHex32(segment.cmdsize);
5667 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
Jason Molendad20359d2014-11-11 10:59:15 +00005668 if (addr_byte_size == 8)
5669 {
5670 buffer.PutHex64(segment.vmaddr);
5671 buffer.PutHex64(segment.vmsize);
5672 buffer.PutHex64(segment.fileoff);
5673 buffer.PutHex64(segment.filesize);
5674 }
5675 else
5676 {
5677 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
5678 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
5679 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
5680 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
5681 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005682 buffer.PutHex32(segment.maxprot);
5683 buffer.PutHex32(segment.initprot);
5684 buffer.PutHex32(segment.nsects);
5685 buffer.PutHex32(segment.flags);
5686 }
5687
5688 File core_file;
5689 std::string core_file_path(outfile.GetPath());
5690 error = core_file.Open(core_file_path.c_str(),
5691 File::eOpenOptionWrite |
5692 File::eOpenOptionTruncate |
5693 File::eOpenOptionCanCreate);
5694 if (error.Success())
5695 {
5696 // Read 1 page at a time
5697 uint8_t bytes[0x1000];
5698 // Write the mach header and load commands out to the core file
5699 size_t bytes_written = buffer.GetString().size();
5700 error = core_file.Write(buffer.GetString().data(), bytes_written);
5701 if (error.Success())
5702 {
5703 // Now write the file data for all memory segments in the process
5704 for (const auto &segment : segment_load_commands)
5705 {
David Majnemerb98a5e02014-07-24 00:24:12 +00005706 if (core_file.SeekFromStart(segment.fileoff) == -1)
Greg Claytona2715cf2014-06-13 00:54:12 +00005707 {
5708 error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str());
5709 break;
5710 }
5711
Jason Molendad20359d2014-11-11 10:59:15 +00005712 printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr);
Greg Claytona2715cf2014-06-13 00:54:12 +00005713 addr_t bytes_left = segment.vmsize;
5714 addr_t addr = segment.vmaddr;
5715 Error memory_read_error;
5716 while (bytes_left > 0 && error.Success())
5717 {
5718 const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
5719 const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error);
5720 if (bytes_read == bytes_to_read)
5721 {
5722 size_t bytes_written = bytes_read;
5723 error = core_file.Write(bytes, bytes_written);
5724 bytes_left -= bytes_read;
5725 addr += bytes_read;
5726 }
5727 else
5728 {
5729 // Some pages within regions are not readable, those
5730 // should be zero filled
5731 memset (bytes, 0, bytes_to_read);
5732 size_t bytes_written = bytes_to_read;
5733 error = core_file.Write(bytes, bytes_written);
5734 bytes_left -= bytes_to_read;
5735 addr += bytes_to_read;
5736 }
5737 }
5738 }
5739 }
5740 }
5741 }
5742 else
5743 {
5744 error.SetErrorString("process doesn't support getting memory region info");
5745 }
5746 }
5747 return true; // This is the right plug to handle saving core files for this process
5748 }
5749 }
5750 return false;
5751}
5752