blob: 6cf5c299627c36bbc1f0e34cb648a9adae61974d [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
131
132 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 }
159
160 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
169 data.PutHex32 (sizeof(GPR)/sizeof(uint64_t)); // Number of uint64_t values that follow
170 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);
243 data.PutHex32 (sizeof(EXC)/sizeof(uint64_t));
244 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 }
360protected:
361 virtual int
362 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
363 {
364 return 0;
365 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000366
Greg Claytonc3776bf2012-02-09 06:16:32 +0000367 virtual int
368 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
369 {
370 return 0;
371 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000372
Greg Claytonc3776bf2012-02-09 06:16:32 +0000373 virtual int
374 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
375 {
376 return 0;
377 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000378
Greg Claytonc3776bf2012-02-09 06:16:32 +0000379 virtual int
380 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
381 {
382 return 0;
383 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000384
Greg Claytonc3776bf2012-02-09 06:16:32 +0000385 virtual int
386 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
387 {
388 return 0;
389 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000390
Greg Claytonc3776bf2012-02-09 06:16:32 +0000391 virtual int
392 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
393 {
394 return 0;
395 }
396};
397
Jason Molenda4e7511e2013-03-06 23:19:17 +0000398class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000399{
400public:
401 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
Greg Claytonc2807462012-10-30 23:57:32 +0000402 RegisterContextDarwin_arm (thread, 0)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000403 {
404 SetRegisterDataFrom_LC_THREAD (data);
405 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000406
Greg Claytonc859e2d2012-02-13 23:10:39 +0000407 virtual void
408 InvalidateAllRegisters ()
409 {
410 // Do nothing... registers are always valid...
411 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000412
Greg Claytonc859e2d2012-02-13 23:10:39 +0000413 void
414 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
415 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000416 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000417 SetError (GPRRegSet, Read, -1);
418 SetError (FPURegSet, Read, -1);
419 SetError (EXCRegSet, Read, -1);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000420 bool done = false;
421
422 while (!done)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000423 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000424 int flavor = data.GetU32 (&offset);
425 uint32_t count = data.GetU32 (&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000426 lldb::offset_t next_thread_state = offset + (count * 4);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000427 switch (flavor)
428 {
429 case GPRRegSet:
430 for (uint32_t i=0; i<count; ++i)
Jason Molendaddf91772013-05-14 04:50:47 +0000431 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000432 gpr.r[i] = data.GetU32(&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000433 }
434
435 // Note that gpr.cpsr is also copied by the above loop; this loop technically extends
436 // one element past the end of the gpr.r[] array.
437
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000438 SetError (GPRRegSet, Read, 0);
Jason Molendaddf91772013-05-14 04:50:47 +0000439 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000440 break;
441
442 case FPURegSet:
443 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000444 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0];
445 const int fpu_reg_buf_size = sizeof (fpu.floats);
446 if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000447 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000448 offset += fpu_reg_buf_size;
449 fpu.fpscr = data.GetU32(&offset);
450 SetError (FPURegSet, Read, 0);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000451 }
Jason Molenda663d2e12013-05-14 03:52:22 +0000452 else
453 {
454 done = true;
455 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000456 }
Jason Molendaddf91772013-05-14 04:50:47 +0000457 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000458 break;
459
460 case EXCRegSet:
Jason Molendaddf91772013-05-14 04:50:47 +0000461 if (count == 3)
462 {
463 exc.exception = data.GetU32(&offset);
464 exc.fsr = data.GetU32(&offset);
465 exc.far = data.GetU32(&offset);
466 SetError (EXCRegSet, Read, 0);
467 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000468 done = true;
Jason Molendaddf91772013-05-14 04:50:47 +0000469 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000470 break;
471
472 // Unknown register set flavor, stop trying to parse.
473 default:
474 done = true;
475 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000476 }
477 }
478protected:
479 virtual int
480 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
481 {
Jason Molendaddf91772013-05-14 04:50:47 +0000482 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000483 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000484
Greg Claytonc859e2d2012-02-13 23:10:39 +0000485 virtual int
486 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
487 {
Jason Molendaddf91772013-05-14 04:50:47 +0000488 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000489 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000490
Greg Claytonc859e2d2012-02-13 23:10:39 +0000491 virtual int
492 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
493 {
Jason Molendaddf91772013-05-14 04:50:47 +0000494 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000495 }
Greg Claytonc2807462012-10-30 23:57:32 +0000496
497 virtual int
498 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
499 {
500 return -1;
501 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000502
Greg Claytonc859e2d2012-02-13 23:10:39 +0000503 virtual int
504 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
505 {
506 return 0;
507 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000508
Greg Claytonc859e2d2012-02-13 23:10:39 +0000509 virtual int
510 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
511 {
512 return 0;
513 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000514
Greg Claytonc859e2d2012-02-13 23:10:39 +0000515 virtual int
516 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
517 {
518 return 0;
519 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000520
Greg Claytonc2807462012-10-30 23:57:32 +0000521 virtual int
522 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
523 {
524 return -1;
525 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000526};
527
Jason Molendaa3329782014-03-29 18:54:20 +0000528class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
529{
530public:
531 RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
532 RegisterContextDarwin_arm64 (thread, 0)
533 {
534 SetRegisterDataFrom_LC_THREAD (data);
535 }
536
537 virtual void
538 InvalidateAllRegisters ()
539 {
540 // Do nothing... registers are always valid...
541 }
542
543 void
544 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
545 {
546 lldb::offset_t offset = 0;
547 SetError (GPRRegSet, Read, -1);
548 SetError (FPURegSet, Read, -1);
549 SetError (EXCRegSet, Read, -1);
550 bool done = false;
551 while (!done)
552 {
553 int flavor = data.GetU32 (&offset);
554 uint32_t count = data.GetU32 (&offset);
555 lldb::offset_t next_thread_state = offset + (count * 4);
556 switch (flavor)
557 {
558 case GPRRegSet:
559 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
560 if (count >= (33 * 2) + 1)
561 {
562 for (uint32_t i=0; i<33; ++i)
563 gpr.x[i] = data.GetU64(&offset);
564 gpr.cpsr = data.GetU32(&offset);
565 SetError (GPRRegSet, Read, 0);
566 }
567 offset = next_thread_state;
568 break;
569 case FPURegSet:
570 {
571 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
572 const int fpu_reg_buf_size = sizeof (fpu);
573 if (fpu_reg_buf_size == count
574 && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
575 {
576 SetError (FPURegSet, Read, 0);
577 }
578 else
579 {
580 done = true;
581 }
582 }
583 offset = next_thread_state;
584 break;
585 case EXCRegSet:
586 if (count == 4)
587 {
588 exc.far = data.GetU64(&offset);
589 exc.esr = data.GetU32(&offset);
590 exc.exception = data.GetU32(&offset);
591 SetError (EXCRegSet, Read, 0);
592 }
593 offset = next_thread_state;
594 break;
595 default:
596 done = true;
597 break;
598 }
599 }
600 }
601protected:
602 virtual int
603 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
604 {
605 return -1;
606 }
607
608 virtual int
609 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
610 {
611 return -1;
612 }
613
614 virtual int
615 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
616 {
617 return -1;
618 }
619
620 virtual int
621 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
622 {
623 return -1;
624 }
625
626 virtual int
627 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
628 {
629 return 0;
630 }
631
632 virtual int
633 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
634 {
635 return 0;
636 }
637
638 virtual int
639 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
640 {
641 return 0;
642 }
643
644 virtual int
645 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
646 {
647 return -1;
648 }
649};
650
Greg Clayton9aae0a12013-05-15 19:52:08 +0000651static uint32_t
652MachHeaderSizeFromMagic(uint32_t magic)
653{
654 switch (magic)
655 {
Charles Davis510938e2013-08-27 05:04:57 +0000656 case MH_MAGIC:
657 case MH_CIGAM:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000658 return sizeof(struct mach_header);
659
Charles Davis510938e2013-08-27 05:04:57 +0000660 case MH_MAGIC_64:
661 case MH_CIGAM_64:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000662 return sizeof(struct mach_header_64);
663 break;
664
665 default:
666 break;
667 }
668 return 0;
669}
670
Greg Claytonded470d2011-03-19 01:12:21 +0000671#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672
673void
674ObjectFileMachO::Initialize()
675{
676 PluginManager::RegisterPlugin (GetPluginNameStatic(),
677 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000678 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000679 CreateMemoryInstance,
Greg Claytona2715cf2014-06-13 00:54:12 +0000680 GetModuleSpecifications,
681 SaveCore);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000682}
683
684void
685ObjectFileMachO::Terminate()
686{
687 PluginManager::UnregisterPlugin (CreateInstance);
688}
689
690
Greg Clayton57abc5d2013-05-10 21:47:16 +0000691lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000692ObjectFileMachO::GetPluginNameStatic()
693{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000694 static ConstString g_name("mach-o");
695 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696}
697
698const char *
699ObjectFileMachO::GetPluginDescriptionStatic()
700{
701 return "Mach-o object file reader (32 and 64 bit)";
702}
703
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704ObjectFile *
Greg Clayton5ce9c562013-02-06 17:22:03 +0000705ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
706 DataBufferSP& data_sp,
707 lldb::offset_t data_offset,
708 const FileSpec* file,
709 lldb::offset_t file_offset,
710 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000712 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000713 {
Greg Clayton5ce9c562013-02-06 17:22:03 +0000714 data_sp = file->MemoryMapFileContents(file_offset, length);
715 data_offset = 0;
716 }
717
718 if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
719 {
720 // Update the data to contain the entire file if it doesn't already
721 if (data_sp->GetByteSize() < length)
722 {
723 data_sp = file->MemoryMapFileContents(file_offset, length);
724 data_offset = 0;
725 }
Greg Clayton7b0992d2013-04-18 22:45:39 +0000726 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 +0000727 if (objfile_ap.get() && objfile_ap->ParseHeader())
728 return objfile_ap.release();
729 }
730 return NULL;
731}
732
Greg Claytonc9660542012-02-05 02:38:54 +0000733ObjectFile *
Jason Molenda4e7511e2013-03-06 23:19:17 +0000734ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
735 DataBufferSP& data_sp,
736 const ProcessSP &process_sp,
Greg Claytonc9660542012-02-05 02:38:54 +0000737 lldb::addr_t header_addr)
738{
739 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
740 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000741 std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonc9660542012-02-05 02:38:54 +0000742 if (objfile_ap.get() && objfile_ap->ParseHeader())
743 return objfile_ap.release();
744 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000745 return NULL;
Greg Claytonc9660542012-02-05 02:38:54 +0000746}
747
Greg Claytonf4d6de62013-04-24 22:29:28 +0000748size_t
749ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
750 lldb::DataBufferSP& data_sp,
751 lldb::offset_t data_offset,
752 lldb::offset_t file_offset,
753 lldb::offset_t length,
754 lldb_private::ModuleSpecList &specs)
755{
756 const size_t initial_count = specs.GetSize();
757
758 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
759 {
760 DataExtractor data;
761 data.SetData(data_sp);
762 llvm::MachO::mach_header header;
763 if (ParseHeader (data, &data_offset, header))
764 {
Jason Molenda48cd3332014-04-22 04:52:30 +0000765 size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
766 if (header_and_load_cmds >= data_sp->GetByteSize())
Greg Claytonf4d6de62013-04-24 22:29:28 +0000767 {
Jason Molenda48cd3332014-04-22 04:52:30 +0000768 data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);
Greg Clayton2540a8a2013-07-12 22:07:46 +0000769 data.SetData(data_sp);
770 data_offset = MachHeaderSizeFromMagic(header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000771 }
772 if (data_sp)
773 {
774 ModuleSpec spec;
775 spec.GetFileSpec() = file;
Greg Clayton7ab7f892014-05-29 21:33:45 +0000776 spec.SetObjectOffset(file_offset);
777
778 if (GetArchitecture (header, data, data_offset, spec.GetArchitecture()))
Jason Molendab000e4d2013-08-27 02:22:06 +0000779 {
Greg Clayton7ab7f892014-05-29 21:33:45 +0000780 if (spec.GetArchitecture().IsValid())
781 {
782 GetUUID (header, data, data_offset, spec.GetUUID());
783 specs.Append(spec);
784 }
Greg Claytonf4d6de62013-04-24 22:29:28 +0000785 }
786 }
787 }
788 }
789 return specs.GetSize() - initial_count;
790}
791
792
Greg Claytonc9660542012-02-05 02:38:54 +0000793
794const ConstString &
795ObjectFileMachO::GetSegmentNameTEXT()
796{
797 static ConstString g_segment_name_TEXT ("__TEXT");
798 return g_segment_name_TEXT;
799}
800
801const ConstString &
802ObjectFileMachO::GetSegmentNameDATA()
803{
804 static ConstString g_segment_name_DATA ("__DATA");
805 return g_segment_name_DATA;
806}
807
808const ConstString &
809ObjectFileMachO::GetSegmentNameOBJC()
810{
811 static ConstString g_segment_name_OBJC ("__OBJC");
812 return g_segment_name_OBJC;
813}
814
815const ConstString &
816ObjectFileMachO::GetSegmentNameLINKEDIT()
817{
818 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
819 return g_section_name_LINKEDIT;
820}
821
822const ConstString &
823ObjectFileMachO::GetSectionNameEHFrame()
824{
825 static ConstString g_section_name_eh_frame ("__eh_frame");
826 return g_section_name_eh_frame;
827}
828
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829bool
Jason Molenda4e7511e2013-03-06 23:19:17 +0000830ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
831 lldb::addr_t data_offset,
Greg Clayton44435ed2012-01-12 05:25:17 +0000832 lldb::addr_t data_length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000833{
Greg Clayton44435ed2012-01-12 05:25:17 +0000834 DataExtractor data;
835 data.SetData (data_sp, data_offset, data_length);
Greg Claytonc7bece562013-01-25 18:06:21 +0000836 lldb::offset_t offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837 uint32_t magic = data.GetU32(&offset);
838 return MachHeaderSizeFromMagic(magic) != 0;
839}
840
841
Greg Clayton5ce9c562013-02-06 17:22:03 +0000842ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
843 DataBufferSP& data_sp,
844 lldb::offset_t data_offset,
845 const FileSpec* file,
846 lldb::offset_t file_offset,
847 lldb::offset_t length) :
848 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytonc3776bf2012-02-09 06:16:32 +0000849 m_mach_segments(),
850 m_mach_sections(),
851 m_entry_point_address(),
852 m_thread_context_offsets(),
853 m_thread_context_offsets_valid(false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000854{
Greg Clayton72b77eb2011-02-04 21:13:05 +0000855 ::memset (&m_header, 0, sizeof(m_header));
856 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857}
858
Greg Claytone72dfb32012-02-24 01:59:29 +0000859ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonc9660542012-02-05 02:38:54 +0000860 lldb::DataBufferSP& header_data_sp,
861 const lldb::ProcessSP &process_sp,
862 lldb::addr_t header_addr) :
Greg Claytone72dfb32012-02-24 01:59:29 +0000863 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonc3776bf2012-02-09 06:16:32 +0000864 m_mach_segments(),
865 m_mach_sections(),
866 m_entry_point_address(),
867 m_thread_context_offsets(),
868 m_thread_context_offsets_valid(false)
Greg Claytonc9660542012-02-05 02:38:54 +0000869{
870 ::memset (&m_header, 0, sizeof(m_header));
871 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
872}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000873
874ObjectFileMachO::~ObjectFileMachO()
875{
876}
877
Greg Claytonf4d6de62013-04-24 22:29:28 +0000878bool
879ObjectFileMachO::ParseHeader (DataExtractor &data,
880 lldb::offset_t *data_offset_ptr,
881 llvm::MachO::mach_header &header)
882{
883 data.SetByteOrder (lldb::endian::InlHostByteOrder());
884 // Leave magic in the original byte order
885 header.magic = data.GetU32(data_offset_ptr);
886 bool can_parse = false;
887 bool is_64_bit = false;
888 switch (header.magic)
889 {
Charles Davis510938e2013-08-27 05:04:57 +0000890 case MH_MAGIC:
Greg Claytonf4d6de62013-04-24 22:29:28 +0000891 data.SetByteOrder (lldb::endian::InlHostByteOrder());
892 data.SetAddressByteSize(4);
893 can_parse = true;
894 break;
895
Charles Davis510938e2013-08-27 05:04:57 +0000896 case MH_MAGIC_64:
Greg Claytonf4d6de62013-04-24 22:29:28 +0000897 data.SetByteOrder (lldb::endian::InlHostByteOrder());
898 data.SetAddressByteSize(8);
899 can_parse = true;
900 is_64_bit = true;
901 break;
902
Charles Davis510938e2013-08-27 05:04:57 +0000903 case MH_CIGAM:
Greg Claytonf4d6de62013-04-24 22:29:28 +0000904 data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
905 data.SetAddressByteSize(4);
906 can_parse = true;
907 break;
908
Charles Davis510938e2013-08-27 05:04:57 +0000909 case MH_CIGAM_64:
Greg Claytonf4d6de62013-04-24 22:29:28 +0000910 data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
911 data.SetAddressByteSize(8);
912 is_64_bit = true;
913 can_parse = true;
914 break;
915
916 default:
917 break;
918 }
919
920 if (can_parse)
921 {
922 data.GetU32(data_offset_ptr, &header.cputype, 6);
923 if (is_64_bit)
924 *data_offset_ptr += 4;
925 return true;
926 }
927 else
928 {
929 memset(&header, 0, sizeof(header));
930 }
931 return false;
932}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000933
934bool
935ObjectFileMachO::ParseHeader ()
936{
Greg Claytona1743492012-03-13 23:14:29 +0000937 ModuleSP module_sp(GetModule());
938 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939 {
Greg Claytona1743492012-03-13 23:14:29 +0000940 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
941 bool can_parse = false;
Greg Claytonc7bece562013-01-25 18:06:21 +0000942 lldb::offset_t offset = 0;
Greg Clayton7fb56d02011-02-01 01:31:41 +0000943 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +0000944 // Leave magic in the original byte order
945 m_header.magic = m_data.GetU32(&offset);
946 switch (m_header.magic)
Greg Claytonc9660542012-02-05 02:38:54 +0000947 {
Charles Davis510938e2013-08-27 05:04:57 +0000948 case MH_MAGIC:
Greg Claytona1743492012-03-13 23:14:29 +0000949 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
950 m_data.SetAddressByteSize(4);
951 can_parse = true;
952 break;
953
Charles Davis510938e2013-08-27 05:04:57 +0000954 case MH_MAGIC_64:
Greg Claytona1743492012-03-13 23:14:29 +0000955 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
956 m_data.SetAddressByteSize(8);
957 can_parse = true;
958 break;
959
Charles Davis510938e2013-08-27 05:04:57 +0000960 case MH_CIGAM:
Greg Claytona1743492012-03-13 23:14:29 +0000961 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
962 m_data.SetAddressByteSize(4);
963 can_parse = true;
964 break;
965
Charles Davis510938e2013-08-27 05:04:57 +0000966 case MH_CIGAM_64:
Greg Claytona1743492012-03-13 23:14:29 +0000967 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
968 m_data.SetAddressByteSize(8);
969 can_parse = true;
970 break;
971
972 default:
973 break;
Greg Claytonc9660542012-02-05 02:38:54 +0000974 }
Greg Claytona1743492012-03-13 23:14:29 +0000975
976 if (can_parse)
977 {
978 m_data.GetU32(&offset, &m_header.cputype, 6);
979
Greg Clayton7ab7f892014-05-29 21:33:45 +0000980
981 ArchSpec mach_arch;
982
983 if (GetArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +0000984 {
Greg Clayton7ab7f892014-05-29 21:33:45 +0000985 // Check if the module has a required architecture
986 const ArchSpec &module_arch = module_sp->GetArchitecture();
987 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
988 return false;
989
990 if (SetModulesArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +0000991 {
Greg Clayton7ab7f892014-05-29 21:33:45 +0000992 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
993 if (m_data.GetByteSize() < header_and_lc_size)
Greg Claytona1743492012-03-13 23:14:29 +0000994 {
Greg Clayton7ab7f892014-05-29 21:33:45 +0000995 DataBufferSP data_sp;
996 ProcessSP process_sp (m_process_wp.lock());
997 if (process_sp)
998 {
999 data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
1000 }
1001 else
1002 {
1003 // Read in all only the load command data from the file on disk
1004 data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
1005 if (data_sp->GetByteSize() != header_and_lc_size)
1006 return false;
1007 }
1008 if (data_sp)
1009 m_data.SetData (data_sp);
Greg Claytona1743492012-03-13 23:14:29 +00001010 }
Greg Claytona1743492012-03-13 23:14:29 +00001011 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00001012 return true;
Greg Claytona1743492012-03-13 23:14:29 +00001013 }
Greg Claytona1743492012-03-13 23:14:29 +00001014 }
1015 else
1016 {
1017 memset(&m_header, 0, sizeof(struct mach_header));
1018 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019 }
1020 return false;
1021}
1022
1023
1024ByteOrder
1025ObjectFileMachO::GetByteOrder () const
1026{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001027 return m_data.GetByteOrder ();
1028}
1029
Jim Ingham5aee1622010-08-09 23:31:02 +00001030bool
1031ObjectFileMachO::IsExecutable() const
1032{
Charles Davis510938e2013-08-27 05:04:57 +00001033 return m_header.filetype == MH_EXECUTE;
Jim Ingham5aee1622010-08-09 23:31:02 +00001034}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001035
Greg Claytonc7bece562013-01-25 18:06:21 +00001036uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001037ObjectFileMachO::GetAddressByteSize () const
1038{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001039 return m_data.GetAddressByteSize ();
1040}
1041
Greg Claytone0d378b2011-03-24 21:19:54 +00001042AddressClass
Greg Claytonded470d2011-03-19 01:12:21 +00001043ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
1044{
1045 Symtab *symtab = GetSymtab();
1046 if (symtab)
1047 {
1048 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
1049 if (symbol)
1050 {
Greg Claytone7612132012-03-07 21:03:09 +00001051 if (symbol->ValueIsAddress())
Greg Claytonded470d2011-03-19 01:12:21 +00001052 {
Greg Claytone7612132012-03-07 21:03:09 +00001053 SectionSP section_sp (symbol->GetAddress().GetSection());
Greg Claytone72dfb32012-02-24 01:59:29 +00001054 if (section_sp)
Greg Claytonded470d2011-03-19 01:12:21 +00001055 {
Charles Davis510938e2013-08-27 05:04:57 +00001056 const lldb::SectionType section_type = section_sp->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001057 switch (section_type)
1058 {
1059 case eSectionTypeInvalid: return eAddressClassUnknown;
1060 case eSectionTypeCode:
Charles Davis510938e2013-08-27 05:04:57 +00001061 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001062 {
1063 // For ARM we have a bit in the n_desc field of the symbol
1064 // that tells us ARM/Thumb which is bit 0x0008.
1065 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1066 return eAddressClassCodeAlternateISA;
1067 }
1068 return eAddressClassCode;
1069
1070 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton5009f9d2011-10-27 17:55:14 +00001071 case eSectionTypeData:
1072 case eSectionTypeDataCString:
1073 case eSectionTypeDataCStringPointers:
1074 case eSectionTypeDataSymbolAddress:
1075 case eSectionTypeData4:
1076 case eSectionTypeData8:
1077 case eSectionTypeData16:
1078 case eSectionTypeDataPointers:
1079 case eSectionTypeZeroFill:
1080 case eSectionTypeDataObjCMessageRefs:
1081 case eSectionTypeDataObjCCFStrings:
1082 return eAddressClassData;
1083 case eSectionTypeDebug:
1084 case eSectionTypeDWARFDebugAbbrev:
1085 case eSectionTypeDWARFDebugAranges:
1086 case eSectionTypeDWARFDebugFrame:
1087 case eSectionTypeDWARFDebugInfo:
1088 case eSectionTypeDWARFDebugLine:
1089 case eSectionTypeDWARFDebugLoc:
1090 case eSectionTypeDWARFDebugMacInfo:
1091 case eSectionTypeDWARFDebugPubNames:
1092 case eSectionTypeDWARFDebugPubTypes:
1093 case eSectionTypeDWARFDebugRanges:
1094 case eSectionTypeDWARFDebugStr:
1095 case eSectionTypeDWARFAppleNames:
1096 case eSectionTypeDWARFAppleTypes:
1097 case eSectionTypeDWARFAppleNamespaces:
1098 case eSectionTypeDWARFAppleObjC:
1099 return eAddressClassDebug;
Greg Claytonded470d2011-03-19 01:12:21 +00001100 case eSectionTypeEHFrame: return eAddressClassRuntime;
Michael Sartaina7499c92013-07-01 19:45:50 +00001101 case eSectionTypeELFSymbolTable:
1102 case eSectionTypeELFDynamicSymbols:
1103 case eSectionTypeELFRelocationEntries:
1104 case eSectionTypeELFDynamicLinkInfo:
Greg Claytonded470d2011-03-19 01:12:21 +00001105 case eSectionTypeOther: return eAddressClassUnknown;
1106 }
1107 }
1108 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001109
Greg Claytone0d378b2011-03-24 21:19:54 +00001110 const SymbolType symbol_type = symbol->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001111 switch (symbol_type)
1112 {
1113 case eSymbolTypeAny: return eAddressClassUnknown;
1114 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Jason Molenda4e7511e2013-03-06 23:19:17 +00001115
Greg Claytonded470d2011-03-19 01:12:21 +00001116 case eSymbolTypeCode:
1117 case eSymbolTypeTrampoline:
Greg Clayton059f7242013-02-27 21:16:04 +00001118 case eSymbolTypeResolver:
Charles Davis510938e2013-08-27 05:04:57 +00001119 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001120 {
1121 // For ARM we have a bit in the n_desc field of the symbol
1122 // that tells us ARM/Thumb which is bit 0x0008.
1123 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1124 return eAddressClassCodeAlternateISA;
1125 }
1126 return eAddressClassCode;
1127
1128 case eSymbolTypeData: return eAddressClassData;
1129 case eSymbolTypeRuntime: return eAddressClassRuntime;
1130 case eSymbolTypeException: return eAddressClassRuntime;
1131 case eSymbolTypeSourceFile: return eAddressClassDebug;
1132 case eSymbolTypeHeaderFile: return eAddressClassDebug;
1133 case eSymbolTypeObjectFile: return eAddressClassDebug;
1134 case eSymbolTypeCommonBlock: return eAddressClassDebug;
1135 case eSymbolTypeBlock: return eAddressClassDebug;
1136 case eSymbolTypeLocal: return eAddressClassData;
1137 case eSymbolTypeParam: return eAddressClassData;
1138 case eSymbolTypeVariable: return eAddressClassData;
1139 case eSymbolTypeVariableType: return eAddressClassDebug;
1140 case eSymbolTypeLineEntry: return eAddressClassDebug;
1141 case eSymbolTypeLineHeader: return eAddressClassDebug;
1142 case eSymbolTypeScopeBegin: return eAddressClassDebug;
1143 case eSymbolTypeScopeEnd: return eAddressClassDebug;
1144 case eSymbolTypeAdditional: return eAddressClassUnknown;
1145 case eSymbolTypeCompiler: return eAddressClassDebug;
1146 case eSymbolTypeInstrumentation:return eAddressClassDebug;
1147 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton456809c2011-12-03 02:30:59 +00001148 case eSymbolTypeObjCClass: return eAddressClassRuntime;
1149 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
1150 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Clayton9191db42013-10-21 18:40:51 +00001151 case eSymbolTypeReExported: return eAddressClassRuntime;
Greg Claytonded470d2011-03-19 01:12:21 +00001152 }
1153 }
1154 }
1155 return eAddressClassUnknown;
1156}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157
1158Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001159ObjectFileMachO::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001160{
Greg Claytona1743492012-03-13 23:14:29 +00001161 ModuleSP module_sp(GetModule());
1162 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163 {
Greg Claytona1743492012-03-13 23:14:29 +00001164 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1165 if (m_symtab_ap.get() == NULL)
1166 {
1167 m_symtab_ap.reset(new Symtab(this));
1168 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
Greg Clayton3046e662013-07-10 01:23:25 +00001169 ParseSymtab ();
Greg Claytona1743492012-03-13 23:14:29 +00001170 m_symtab_ap->Finalize ();
1171 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 }
1173 return m_symtab_ap.get();
1174}
1175
Greg Clayton3046e662013-07-10 01:23:25 +00001176bool
1177ObjectFileMachO::IsStripped ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001178{
Greg Clayton3046e662013-07-10 01:23:25 +00001179 if (m_dysymtab.cmd == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180 {
Greg Clayton3046e662013-07-10 01:23:25 +00001181 ModuleSP module_sp(GetModule());
1182 if (module_sp)
Greg Claytona1743492012-03-13 23:14:29 +00001183 {
Greg Clayton3046e662013-07-10 01:23:25 +00001184 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1185 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton4d78c402012-05-25 18:09:55 +00001186 {
Greg Clayton3046e662013-07-10 01:23:25 +00001187 const lldb::offset_t load_cmd_offset = offset;
1188
1189 load_command lc;
1190 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
1191 break;
Charles Davis510938e2013-08-27 05:04:57 +00001192 if (lc.cmd == LC_DYSYMTAB)
Greg Clayton4d78c402012-05-25 18:09:55 +00001193 {
Greg Clayton3046e662013-07-10 01:23:25 +00001194 m_dysymtab.cmd = lc.cmd;
1195 m_dysymtab.cmdsize = lc.cmdsize;
1196 if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
1197 {
1198 // Clear m_dysymtab if we were unable to read all items from the load command
1199 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1200 }
Greg Clayton4d78c402012-05-25 18:09:55 +00001201 }
Greg Clayton3046e662013-07-10 01:23:25 +00001202 offset = load_cmd_offset + lc.cmdsize;
Greg Clayton4d78c402012-05-25 18:09:55 +00001203 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001204 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001205 }
Greg Clayton3046e662013-07-10 01:23:25 +00001206 if (m_dysymtab.cmd)
Greg Clayton93e28612013-10-11 22:03:48 +00001207 return m_dysymtab.nlocalsym <= 1;
Greg Clayton3046e662013-07-10 01:23:25 +00001208 return false;
1209}
Greg Clayton1eac0c72012-04-24 03:06:13 +00001210
Greg Clayton3046e662013-07-10 01:23:25 +00001211void
1212ObjectFileMachO::CreateSections (SectionList &unified_section_list)
1213{
1214 if (!m_sections_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001215 {
Greg Clayton3046e662013-07-10 01:23:25 +00001216 m_sections_ap.reset(new SectionList());
1217
Charles Davis510938e2013-08-27 05:04:57 +00001218 const bool is_dsym = (m_header.filetype == MH_DSYM);
Greg Clayton3046e662013-07-10 01:23:25 +00001219 lldb::user_id_t segID = 0;
1220 lldb::user_id_t sectID = 0;
1221 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1222 uint32_t i;
1223 const bool is_core = GetType() == eTypeCoreFile;
1224 //bool dump_sections = false;
1225 ModuleSP module_sp (GetModule());
1226 // First look up any LC_ENCRYPTION_INFO load commands
1227 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
1228 EncryptedFileRanges encrypted_file_ranges;
1229 encryption_info_command encryption_cmd;
1230 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231 {
Greg Clayton3046e662013-07-10 01:23:25 +00001232 const lldb::offset_t load_cmd_offset = offset;
1233 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
1234 break;
1235
Charles Davis510938e2013-08-27 05:04:57 +00001236 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237 {
Greg Clayton3046e662013-07-10 01:23:25 +00001238 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001239 {
Greg Clayton3046e662013-07-10 01:23:25 +00001240 if (encryption_cmd.cryptid != 0)
Greg Claytond37d6922013-04-16 16:51:19 +00001241 {
Greg Clayton3046e662013-07-10 01:23:25 +00001242 EncryptedFileRanges::Entry entry;
1243 entry.SetRangeBase(encryption_cmd.cryptoff);
1244 entry.SetByteSize(encryption_cmd.cryptsize);
1245 encrypted_file_ranges.Append(entry);
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001246 }
1247 }
Greg Clayton3046e662013-07-10 01:23:25 +00001248 }
1249 offset = load_cmd_offset + encryption_cmd.cmdsize;
1250 }
1251
1252 offset = MachHeaderSizeFromMagic(m_header.magic);
1253
1254 struct segment_command_64 load_cmd;
1255 for (i=0; i<m_header.ncmds; ++i)
1256 {
1257 const lldb::offset_t load_cmd_offset = offset;
1258 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1259 break;
1260
Charles Davis510938e2013-08-27 05:04:57 +00001261 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
Greg Clayton3046e662013-07-10 01:23:25 +00001262 {
1263 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264 {
Greg Clayton3046e662013-07-10 01:23:25 +00001265 bool add_section = true;
1266 bool add_to_unified = true;
1267 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 +00001268
Greg Clayton3046e662013-07-10 01:23:25 +00001269 SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
1270 if (is_dsym && unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271 {
Greg Clayton3046e662013-07-10 01:23:25 +00001272 if (const_segname == GetSegmentNameLINKEDIT())
1273 {
1274 // We need to keep the __LINKEDIT segment private to this object file only
1275 add_to_unified = false;
1276 }
1277 else
1278 {
1279 // This is the dSYM file and this section has already been created by
1280 // the object file, no need to create it.
1281 add_section = false;
1282 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001283 }
Greg Clayton3046e662013-07-10 01:23:25 +00001284 load_cmd.vmaddr = m_data.GetAddress(&offset);
1285 load_cmd.vmsize = m_data.GetAddress(&offset);
1286 load_cmd.fileoff = m_data.GetAddress(&offset);
1287 load_cmd.filesize = m_data.GetAddress(&offset);
1288 if (m_length != 0 && load_cmd.filesize != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001289 {
Greg Clayton3046e662013-07-10 01:23:25 +00001290 if (load_cmd.fileoff > m_length)
1291 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001292 // 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 +00001293 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001294 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001295 // is null out the SectionList vector and if a process has been set up, dump a message
1296 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001297 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001298 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 +00001299 i,
1300 lc_segment_name,
1301 load_cmd.fileoff,
1302 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001303
1304 load_cmd.fileoff = 0;
1305 load_cmd.filesize = 0;
1306 }
1307
1308 if (load_cmd.fileoff + load_cmd.filesize > m_length)
1309 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001310 // 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 +00001311 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001312 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001313 // is null out the SectionList vector and if a process has been set up, dump a message
1314 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001315 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001316 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 +00001317 i,
1318 lc_segment_name,
1319 load_cmd.fileoff + load_cmd.filesize,
1320 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001321
1322 // Tuncase the length
1323 load_cmd.filesize = m_length - load_cmd.fileoff;
1324 }
1325 }
1326 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
1327 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001328
Charles Davis510938e2013-08-27 05:04:57 +00001329 const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001330
Greg Clayton3046e662013-07-10 01:23:25 +00001331 // Keep a list of mach segments around in case we need to
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001332 // get at data that isn't stored in the abstracted Sections.
Greg Clayton3046e662013-07-10 01:23:25 +00001333 m_mach_segments.push_back (load_cmd);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001334
Greg Clayton3046e662013-07-10 01:23:25 +00001335 // Use a segment ID of the segment index shifted left by 8 so they
1336 // never conflict with any of the sections.
1337 SectionSP segment_sp;
1338 if (add_section && (const_segname || is_core))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001339 {
Greg Clayton3046e662013-07-10 01:23:25 +00001340 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
1341 this, // Object file to which this sections belongs
1342 ++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
1343 const_segname, // Name of this section
1344 eSectionTypeContainer, // This section is a container of other sections.
1345 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
1346 load_cmd.vmsize, // VM size in bytes of this section
1347 load_cmd.fileoff, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001348 load_cmd.filesize, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001349 0, // Segments have no alignment information
Greg Clayton3046e662013-07-10 01:23:25 +00001350 load_cmd.flags)); // Flags for this section
Greg Clayton8d38ac42010-06-28 23:51:11 +00001351
Greg Clayton3046e662013-07-10 01:23:25 +00001352 segment_sp->SetIsEncrypted (segment_is_encrypted);
1353 m_sections_ap->AddSection(segment_sp);
1354 if (add_to_unified)
1355 unified_section_list.AddSection(segment_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356 }
Greg Clayton3046e662013-07-10 01:23:25 +00001357 else if (unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001358 {
Jason Molenda20eb31b2013-08-16 03:20:42 +00001359 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr)
1360 {
1361 // Check to see if the module was read from memory?
1362 if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid())
1363 {
1364 // We have a module that is in memory and needs to have its
1365 // file address adjusted. We need to do this because when we
1366 // load a file from memory, its addresses will be slid already,
1367 // yet the addresses in the new symbol file will still be unslid.
1368 // Since everything is stored as section offset, this shouldn't
1369 // cause any problems.
Jason Molenda5894a732013-08-17 03:39:52 +00001370
1371 // Make sure we've parsed the symbol table from the
1372 // ObjectFile before we go around changing its Sections.
1373 module_sp->GetObjectFile()->GetSymtab();
1374 // eh_frame would present the same problems but we parse that on
1375 // a per-function basis as-needed so it's more difficult to
1376 // remove its use of the Sections. Realistically, the environments
1377 // where this code path will be taken will not have eh_frame sections.
1378
Jason Molenda20eb31b2013-08-16 03:20:42 +00001379 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
1380 }
1381 }
Greg Clayton3046e662013-07-10 01:23:25 +00001382 m_sections_ap->AddSection(unified_section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001383 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001384
Greg Clayton3046e662013-07-10 01:23:25 +00001385 struct section_64 sect64;
1386 ::memset (&sect64, 0, sizeof(sect64));
1387 // Push a section into our mach sections for the section at
Charles Davis510938e2013-08-27 05:04:57 +00001388 // index zero (NO_SECT) if we don't have any mach sections yet...
Greg Clayton3046e662013-07-10 01:23:25 +00001389 if (m_mach_sections.empty())
1390 m_mach_sections.push_back(sect64);
1391 uint32_t segment_sect_idx;
1392 const lldb::user_id_t first_segment_sectID = sectID + 1;
1393
1394
Charles Davis510938e2013-08-27 05:04:57 +00001395 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
Greg Clayton3046e662013-07-10 01:23:25 +00001396 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001397 {
Greg Clayton3046e662013-07-10 01:23:25 +00001398 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
Greg Clayton89411422010-10-08 00:21:05 +00001399 break;
Greg Clayton3046e662013-07-10 01:23:25 +00001400 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
1401 break;
1402 sect64.addr = m_data.GetAddress(&offset);
1403 sect64.size = m_data.GetAddress(&offset);
1404
1405 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
1406 break;
1407
1408 // Keep a list of mach sections around in case we need to
1409 // get at data that isn't stored in the abstracted Sections.
1410 m_mach_sections.push_back (sect64);
1411
1412 if (add_section)
1413 {
1414 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
1415 if (!const_segname)
1416 {
1417 // We have a segment with no name so we need to conjure up
1418 // segments that correspond to the section's segname if there
1419 // isn't already such a section. If there is such a section,
1420 // we resize the section so that it spans all sections.
1421 // We also mark these sections as fake so address matches don't
1422 // hit if they land in the gaps between the child sections.
1423 const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
1424 segment_sp = unified_section_list.FindSectionByName (const_segname);
1425 if (segment_sp.get())
1426 {
1427 Section *segment = segment_sp.get();
1428 // Grow the section size as needed.
1429 const lldb::addr_t sect64_min_addr = sect64.addr;
1430 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1431 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
1432 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
1433 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
1434 if (sect64_min_addr >= curr_seg_min_addr)
1435 {
1436 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
1437 // Only grow the section size if needed
1438 if (new_seg_byte_size > curr_seg_byte_size)
1439 segment->SetByteSize (new_seg_byte_size);
1440 }
1441 else
1442 {
1443 // We need to change the base address of the segment and
1444 // adjust the child section offsets for all existing children.
1445 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
1446 segment->Slide(slide_amount, false);
1447 segment->GetChildren().Slide(-slide_amount, false);
1448 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
1449 }
1450
1451 // Grow the section size as needed.
1452 if (sect64.offset)
1453 {
1454 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
1455 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
1456
1457 const lldb::addr_t section_min_file_offset = sect64.offset;
1458 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
1459 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
1460 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
1461 segment->SetFileOffset (new_file_offset);
1462 segment->SetFileSize (new_file_size);
1463 }
1464 }
1465 else
1466 {
1467 // Create a fake section for the section's named segment
1468 segment_sp.reset(new Section (segment_sp, // Parent section
1469 module_sp, // Module to which this section belongs
1470 this, // Object file to which this section belongs
1471 ++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
1472 const_segname, // Name of this section
1473 eSectionTypeContainer, // This section is a container of other sections.
1474 sect64.addr, // File VM address == addresses as they are found in the object file
1475 sect64.size, // VM size in bytes of this section
1476 sect64.offset, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001477 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001478 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001479 load_cmd.flags)); // Flags for this section
1480 segment_sp->SetIsFake(true);
1481
1482 m_sections_ap->AddSection(segment_sp);
1483 if (add_to_unified)
1484 unified_section_list.AddSection(segment_sp);
1485 segment_sp->SetIsEncrypted (segment_is_encrypted);
1486 }
1487 }
1488 assert (segment_sp.get());
1489
Charles Davis510938e2013-08-27 05:04:57 +00001490 lldb::SectionType sect_type = eSectionTypeOther;
Greg Clayton3046e662013-07-10 01:23:25 +00001491
Greg Clayton38f9cc42014-06-16 22:53:16 +00001492 if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1493 sect_type = eSectionTypeCode;
1494 else
Greg Clayton3046e662013-07-10 01:23:25 +00001495 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001496 uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
1497 static ConstString g_sect_name_objc_data ("__objc_data");
1498 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
1499 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
1500 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
1501 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
1502 static ConstString g_sect_name_objc_const ("__objc_const");
1503 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
1504 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton3046e662013-07-10 01:23:25 +00001505
Greg Clayton38f9cc42014-06-16 22:53:16 +00001506 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
1507 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
1508 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
1509 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
1510 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
1511 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
1512 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
1513 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
1514 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
1515 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
1516 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
1517 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
1518 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
1519 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
1520 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
1521 static ConstString g_sect_name_eh_frame ("__eh_frame");
1522 static ConstString g_sect_name_text ("__text");
1523 static ConstString g_sect_name_data ("__data");
1524
1525
1526 if (section_name == g_sect_name_dwarf_debug_abbrev)
1527 sect_type = eSectionTypeDWARFDebugAbbrev;
1528 else if (section_name == g_sect_name_dwarf_debug_aranges)
1529 sect_type = eSectionTypeDWARFDebugAranges;
1530 else if (section_name == g_sect_name_dwarf_debug_frame)
1531 sect_type = eSectionTypeDWARFDebugFrame;
1532 else if (section_name == g_sect_name_dwarf_debug_info)
1533 sect_type = eSectionTypeDWARFDebugInfo;
1534 else if (section_name == g_sect_name_dwarf_debug_line)
1535 sect_type = eSectionTypeDWARFDebugLine;
1536 else if (section_name == g_sect_name_dwarf_debug_loc)
1537 sect_type = eSectionTypeDWARFDebugLoc;
1538 else if (section_name == g_sect_name_dwarf_debug_macinfo)
1539 sect_type = eSectionTypeDWARFDebugMacInfo;
1540 else if (section_name == g_sect_name_dwarf_debug_pubnames)
1541 sect_type = eSectionTypeDWARFDebugPubNames;
1542 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
1543 sect_type = eSectionTypeDWARFDebugPubTypes;
1544 else if (section_name == g_sect_name_dwarf_debug_ranges)
1545 sect_type = eSectionTypeDWARFDebugRanges;
1546 else if (section_name == g_sect_name_dwarf_debug_str)
1547 sect_type = eSectionTypeDWARFDebugStr;
1548 else if (section_name == g_sect_name_dwarf_apple_names)
1549 sect_type = eSectionTypeDWARFAppleNames;
1550 else if (section_name == g_sect_name_dwarf_apple_types)
1551 sect_type = eSectionTypeDWARFAppleTypes;
1552 else if (section_name == g_sect_name_dwarf_apple_namespaces)
1553 sect_type = eSectionTypeDWARFAppleNamespaces;
1554 else if (section_name == g_sect_name_dwarf_apple_objc)
1555 sect_type = eSectionTypeDWARFAppleObjC;
1556 else if (section_name == g_sect_name_objc_selrefs)
1557 sect_type = eSectionTypeDataCStringPointers;
1558 else if (section_name == g_sect_name_objc_msgrefs)
1559 sect_type = eSectionTypeDataObjCMessageRefs;
1560 else if (section_name == g_sect_name_eh_frame)
1561 sect_type = eSectionTypeEHFrame;
1562 else if (section_name == g_sect_name_cfstring)
1563 sect_type = eSectionTypeDataObjCCFStrings;
1564 else if (section_name == g_sect_name_objc_data ||
1565 section_name == g_sect_name_objc_classrefs ||
1566 section_name == g_sect_name_objc_superrefs ||
1567 section_name == g_sect_name_objc_const ||
1568 section_name == g_sect_name_objc_classlist)
Greg Clayton3046e662013-07-10 01:23:25 +00001569 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001570 sect_type = eSectionTypeDataPointers;
1571 }
1572
1573 if (sect_type == eSectionTypeOther)
1574 {
1575 switch (mach_sect_type)
1576 {
1577 // TODO: categorize sections by other flags for regular sections
1578 case S_REGULAR:
1579 if (section_name == g_sect_name_text)
1580 sect_type = eSectionTypeCode;
1581 else if (section_name == g_sect_name_data)
1582 sect_type = eSectionTypeData;
1583 else
1584 sect_type = eSectionTypeOther;
1585 break;
1586 case S_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1587 case S_CSTRING_LITERALS: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1588 case S_4BYTE_LITERALS: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1589 case S_8BYTE_LITERALS: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1590 case S_LITERAL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1591 case S_NON_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1592 case S_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1593 case S_SYMBOL_STUBS: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1594 case S_MOD_INIT_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1595 case S_MOD_TERM_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1596 case S_COALESCED: sect_type = eSectionTypeOther; break;
1597 case S_GB_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1598 case S_INTERPOSING: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1599 case S_16BYTE_LITERALS: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1600 case S_DTRACE_DOF: sect_type = eSectionTypeDebug; break;
1601 case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break;
1602 default: break;
1603 }
Greg Clayton3046e662013-07-10 01:23:25 +00001604 }
1605 }
1606
1607 SectionSP section_sp(new Section (segment_sp,
1608 module_sp,
1609 this,
1610 ++sectID,
1611 section_name,
1612 sect_type,
1613 sect64.addr - segment_sp->GetFileAddress(),
1614 sect64.size,
1615 sect64.offset,
1616 sect64.offset == 0 ? 0 : sect64.size,
Greg Clayton48672af2014-06-24 22:22:43 +00001617 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001618 sect64.flags));
1619 // Set the section to be encrypted to match the segment
1620
1621 bool section_is_encrypted = false;
1622 if (!segment_is_encrypted && load_cmd.filesize != 0)
1623 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
1624
1625 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
1626 segment_sp->GetChildren().AddSection(section_sp);
1627
1628 if (segment_sp->IsFake())
1629 {
1630 segment_sp.reset();
1631 const_segname.Clear();
1632 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001633 }
1634 }
Greg Clayton3046e662013-07-10 01:23:25 +00001635 if (segment_sp && is_dsym)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001636 {
Greg Clayton3046e662013-07-10 01:23:25 +00001637 if (first_segment_sectID <= sectID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001638 {
Greg Clayton3046e662013-07-10 01:23:25 +00001639 lldb::user_id_t sect_uid;
1640 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001641 {
Greg Clayton3046e662013-07-10 01:23:25 +00001642 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1643 SectionSP next_section_sp;
1644 if (sect_uid + 1 <= sectID)
1645 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1646
1647 if (curr_section_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648 {
Greg Clayton3046e662013-07-10 01:23:25 +00001649 if (curr_section_sp->GetByteSize() == 0)
1650 {
1651 if (next_section_sp.get() != NULL)
1652 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1653 else
1654 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1655 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001656 }
1657 }
1658 }
1659 }
1660 }
1661 }
1662 }
Charles Davis510938e2013-08-27 05:04:57 +00001663 else if (load_cmd.cmd == LC_DYSYMTAB)
Greg Clayton3046e662013-07-10 01:23:25 +00001664 {
1665 m_dysymtab.cmd = load_cmd.cmd;
1666 m_dysymtab.cmdsize = load_cmd.cmdsize;
1667 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1668 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001669
Greg Clayton3046e662013-07-10 01:23:25 +00001670 offset = load_cmd_offset + load_cmd.cmdsize;
1671 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001672 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001673}
1674
1675class MachSymtabSectionInfo
1676{
1677public:
1678
1679 MachSymtabSectionInfo (SectionList *section_list) :
1680 m_section_list (section_list),
1681 m_section_infos()
1682 {
1683 // Get the number of sections down to a depth of 1 to include
1684 // all segments and their sections, but no other sections that
1685 // may be added for debug map or
1686 m_section_infos.resize(section_list->GetNumSections(1));
1687 }
1688
1689
Greg Claytone72dfb32012-02-24 01:59:29 +00001690 SectionSP
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001691 GetSection (uint8_t n_sect, addr_t file_addr)
1692 {
1693 if (n_sect == 0)
Greg Claytone72dfb32012-02-24 01:59:29 +00001694 return SectionSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001695 if (n_sect < m_section_infos.size())
1696 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001697 if (!m_section_infos[n_sect].section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001698 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001699 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1700 m_section_infos[n_sect].section_sp = section_sp;
Sean Callanan9a028512012-08-09 00:50:26 +00001701 if (section_sp)
Greg Claytondda0d122011-07-10 17:32:33 +00001702 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001703 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1704 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Claytondda0d122011-07-10 17:32:33 +00001705 }
1706 else
1707 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00001708 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Claytondda0d122011-07-10 17:32:33 +00001709 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001710 }
1711 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton8f258512011-08-26 20:01:35 +00001712 {
1713 // Symbol is in section.
Greg Claytone72dfb32012-02-24 01:59:29 +00001714 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001715 }
1716 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1717 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1718 {
1719 // Symbol is in section with zero size, but has the same start
1720 // address as the section. This can happen with linker symbols
1721 // (symbols that start with the letter 'l' or 'L'.
Greg Claytone72dfb32012-02-24 01:59:29 +00001722 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001723 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001724 }
Greg Claytone72dfb32012-02-24 01:59:29 +00001725 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001726 }
1727
1728protected:
1729 struct SectionInfo
1730 {
1731 SectionInfo () :
1732 vm_range(),
Greg Claytone72dfb32012-02-24 01:59:29 +00001733 section_sp ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001734 {
1735 }
1736
1737 VMRange vm_range;
Greg Claytone72dfb32012-02-24 01:59:29 +00001738 SectionSP section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001739 };
1740 SectionList *m_section_list;
1741 std::vector<SectionInfo> m_section_infos;
1742};
1743
Greg Clayton9191db42013-10-21 18:40:51 +00001744struct TrieEntry
1745{
1746 TrieEntry () :
1747 name(),
1748 address(LLDB_INVALID_ADDRESS),
1749 flags (0),
1750 other(0),
1751 import_name()
1752 {
1753 }
1754
1755 void
1756 Clear ()
1757 {
1758 name.Clear();
1759 address = LLDB_INVALID_ADDRESS;
1760 flags = 0;
1761 other = 0;
1762 import_name.Clear();
1763 }
1764
1765 void
1766 Dump () const
1767 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001768 printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
1769 static_cast<unsigned long long>(address),
1770 static_cast<unsigned long long>(flags),
1771 static_cast<unsigned long long>(other), name.GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +00001772 if (import_name)
1773 printf (" -> \"%s\"\n", import_name.GetCString());
1774 else
1775 printf ("\n");
1776 }
1777 ConstString name;
1778 uint64_t address;
1779 uint64_t flags;
1780 uint64_t other;
1781 ConstString import_name;
1782};
1783
1784struct TrieEntryWithOffset
1785{
1786 lldb::offset_t nodeOffset;
1787 TrieEntry entry;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001788
Greg Clayton9191db42013-10-21 18:40:51 +00001789 TrieEntryWithOffset (lldb::offset_t offset) :
1790 nodeOffset (offset),
1791 entry()
1792 {
1793 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001794
Greg Clayton9191db42013-10-21 18:40:51 +00001795 void
1796 Dump (uint32_t idx) const
1797 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001798 printf ("[%3u] 0x%16.16llx: ", idx,
1799 static_cast<unsigned long long>(nodeOffset));
Greg Clayton9191db42013-10-21 18:40:51 +00001800 entry.Dump();
1801 }
1802
1803 bool
1804 operator<(const TrieEntryWithOffset& other) const
1805 {
1806 return ( nodeOffset < other.nodeOffset );
1807 }
1808};
1809
1810static void
1811ParseTrieEntries (DataExtractor &data,
1812 lldb::offset_t offset,
1813 std::vector<llvm::StringRef> &nameSlices,
1814 std::set<lldb::addr_t> &resolver_addresses,
1815 std::vector<TrieEntryWithOffset>& output)
1816{
1817 if (!data.ValidOffset(offset))
1818 return;
1819
1820 const uint64_t terminalSize = data.GetULEB128(&offset);
1821 lldb::offset_t children_offset = offset + terminalSize;
1822 if ( terminalSize != 0 ) {
1823 TrieEntryWithOffset e (offset);
1824 e.entry.flags = data.GetULEB128(&offset);
1825 const char *import_name = NULL;
1826 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
1827 e.entry.address = 0;
1828 e.entry.other = data.GetULEB128(&offset); // dylib ordinal
1829 import_name = data.GetCStr(&offset);
1830 }
1831 else {
1832 e.entry.address = data.GetULEB128(&offset);
1833 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
1834 {
Jim Inghamea3ac272014-01-10 22:55:37 +00001835 //resolver_addresses.insert(e.entry.address);
Greg Clayton9191db42013-10-21 18:40:51 +00001836 e.entry.other = data.GetULEB128(&offset);
Jim Inghamea3ac272014-01-10 22:55:37 +00001837 resolver_addresses.insert(e.entry.other);
Greg Clayton9191db42013-10-21 18:40:51 +00001838 }
1839 else
1840 e.entry.other = 0;
1841 }
1842 // Only add symbols that are reexport symbols with a valid import name
1843 if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
1844 {
1845 std::string name;
1846 if (!nameSlices.empty())
1847 {
1848 for (auto name_slice: nameSlices)
1849 name.append(name_slice.data(), name_slice.size());
1850 }
1851 if (name.size() > 1)
1852 {
1853 // Skip the leading '_'
1854 e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
1855 }
1856 if (import_name)
1857 {
1858 // Skip the leading '_'
1859 e.entry.import_name.SetCString(import_name+1);
1860 }
1861 output.push_back(e);
1862 }
1863 }
1864
1865 const uint8_t childrenCount = data.GetU8(&children_offset);
1866 for (uint8_t i=0; i < childrenCount; ++i) {
1867 nameSlices.push_back(data.GetCStr(&children_offset));
1868 lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
1869 if (childNodeOffset)
1870 {
1871 ParseTrieEntries(data,
1872 childNodeOffset,
1873 nameSlices,
1874 resolver_addresses,
1875 output);
1876 }
1877 nameSlices.pop_back();
1878 }
1879}
1880
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001881size_t
Greg Clayton3046e662013-07-10 01:23:25 +00001882ObjectFileMachO::ParseSymtab ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001883{
1884 Timer scoped_timer(__PRETTY_FUNCTION__,
1885 "ObjectFileMachO::ParseSymtab () module = %s",
1886 m_file.GetFilename().AsCString(""));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001887 ModuleSP module_sp (GetModule());
1888 if (!module_sp)
1889 return 0;
1890
1891 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
1892 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
Greg Clayton9191db42013-10-21 18:40:51 +00001893 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 +00001894 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
1895 FunctionStarts function_starts;
Greg Claytonc7bece562013-01-25 18:06:21 +00001896 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001897 uint32_t i;
Greg Clayton9191db42013-10-21 18:40:51 +00001898 FileSpecList dylib_files;
Greg Clayton5160ce52013-03-27 23:08:40 +00001899 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
Greg Clayton77ccca72011-12-30 00:32:24 +00001900
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001901 for (i=0; i<m_header.ncmds; ++i)
1902 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001903 const lldb::offset_t cmd_offset = offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001904 // Read in the load command and load command size
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001905 struct load_command lc;
1906 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001907 break;
1908 // Watch for the symbol table load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001909 switch (lc.cmd)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001910 {
Charles Davis510938e2013-08-27 05:04:57 +00001911 case LC_SYMTAB:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001912 symtab_load_command.cmd = lc.cmd;
1913 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001914 // Read in the rest of the symtab load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001915 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
1916 return 0;
1917 if (symtab_load_command.symoff == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001918 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001919 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001920 module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001921 return 0;
1922 }
1923
1924 if (symtab_load_command.stroff == 0)
1925 {
1926 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001927 module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001928 return 0;
1929 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001930
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001931 if (symtab_load_command.nsyms == 0)
1932 {
1933 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001934 module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001935 return 0;
1936 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001937
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001938 if (symtab_load_command.strsize == 0)
1939 {
1940 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001941 module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001942 return 0;
1943 }
1944 break;
1945
Greg Clayton9191db42013-10-21 18:40:51 +00001946 case LC_DYLD_INFO:
1947 case LC_DYLD_INFO_ONLY:
1948 if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
1949 {
1950 dyld_info.cmd = lc.cmd;
1951 dyld_info.cmdsize = lc.cmdsize;
1952 }
1953 else
1954 {
1955 memset (&dyld_info, 0, sizeof(dyld_info));
1956 }
1957 break;
1958
1959 case LC_LOAD_DYLIB:
1960 case LC_LOAD_WEAK_DYLIB:
1961 case LC_REEXPORT_DYLIB:
1962 case LC_LOADFVMLIB:
1963 case LC_LOAD_UPWARD_DYLIB:
1964 {
1965 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
1966 const char *path = m_data.PeekCStr(name_offset);
1967 if (path)
1968 {
1969 FileSpec file_spec(path, false);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001970 // Strip the path if there is @rpath, @executable, etc so we just use the basename
Greg Clayton9191db42013-10-21 18:40:51 +00001971 if (path[0] == '@')
1972 file_spec.GetDirectory().Clear();
Jim Inghamfbe0b9a2014-05-21 03:58:03 +00001973
1974 if (lc.cmd == LC_REEXPORT_DYLIB)
1975 {
1976 m_reexported_dylibs.AppendIfUnique(file_spec);
1977 }
Greg Clayton9191db42013-10-21 18:40:51 +00001978
1979 dylib_files.Append(file_spec);
1980 }
1981 }
1982 break;
1983
Charles Davis510938e2013-08-27 05:04:57 +00001984 case LC_FUNCTION_STARTS:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001985 function_starts_load_command.cmd = lc.cmd;
1986 function_starts_load_command.cmdsize = lc.cmdsize;
1987 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 +00001988 memset (&function_starts_load_command, 0, sizeof(function_starts_load_command));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00001989 break;
1990
1991 default:
1992 break;
1993 }
1994 offset = cmd_offset + lc.cmdsize;
1995 }
1996
1997 if (symtab_load_command.cmd)
1998 {
1999 Symtab *symtab = m_symtab_ap.get();
2000 SectionList *section_list = GetSectionList();
2001 if (section_list == NULL)
2002 return 0;
2003
Greg Claytonc7bece562013-01-25 18:06:21 +00002004 const uint32_t addr_byte_size = m_data.GetAddressByteSize();
2005 const ByteOrder byte_order = m_data.GetByteOrder();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002006 bool bit_width_32 = addr_byte_size == 4;
2007 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
2008
Greg Claytonc7bece562013-01-25 18:06:21 +00002009 DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
2010 DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
2011 DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
Jason Molendad34e6522013-02-05 22:31:24 +00002012 DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002013 DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);
Jason Molenda4e7511e2013-03-06 23:19:17 +00002014
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002015 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
2016 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Clayton4c82d422012-05-18 23:20:01 +00002017 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
Greg Claytonfd814c52013-08-13 01:42:25 +00002018
2019 ProcessSP process_sp (m_process_wp.lock());
2020 Process *process = process_sp.get();
2021
Greg Clayton86eac942013-08-13 21:32:34 +00002022 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
2023
Greg Clayton48672af2014-06-24 22:22:43 +00002024 if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002025 {
Greg Clayton4c82d422012-05-18 23:20:01 +00002026 Target &target = process->GetTarget();
Greg Claytonfd814c52013-08-13 01:42:25 +00002027
Greg Clayton86eac942013-08-13 21:32:34 +00002028 memory_module_load_level = target.GetMemoryModuleLoadLevel();
Greg Claytonfd814c52013-08-13 01:42:25 +00002029
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002030 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2031 // Reading mach file from memory in a process or core file...
2032
2033 if (linkedit_section_sp)
2034 {
2035 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
2036 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2037 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Clayton4c82d422012-05-18 23:20:01 +00002038 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton26b47e22012-04-18 05:19:20 +00002039
2040 bool data_was_read = false;
2041
Todd Fiala013434e2014-07-09 01:29:05 +00002042#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa3329782014-03-29 18:54:20 +00002043 if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
Greg Clayton77ccca72011-12-30 00:32:24 +00002044 {
Greg Clayton26b47e22012-04-18 05:19:20 +00002045 // This mach-o memory file is in the dyld shared cache. If this
2046 // program is not remote and this is iOS, then this process will
2047 // share the same shared cache as the process we are debugging and
2048 // we can read the entire __LINKEDIT from the address space in this
2049 // process. This is a needed optimization that is used for local iOS
2050 // debugging only since all shared libraries in the shared cache do
2051 // not have corresponding files that exist in the file system of the
2052 // device. They have been combined into a single file. This means we
2053 // always have to load these files from memory. All of the symbol and
2054 // string tables from all of the __LINKEDIT sections from the shared
2055 // libraries in the shared cache have been merged into a single large
2056 // symbol and string table. Reading all of this symbol and string table
2057 // data across can slow down debug launch times, so we optimize this by
2058 // reading the memory for the __LINKEDIT section from this process.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002059
2060 UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
2061 UUID process_shared_cache(GetProcessSharedCacheUUID(process));
2062 bool use_lldb_cache = true;
2063 if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache)
2064 {
2065 use_lldb_cache = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002066 ModuleSP module_sp (GetModule());
2067 if (module_sp)
2068 module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow.");
2069
Jason Molenda0e0954c2013-04-16 06:24:42 +00002070 }
2071
Greg Clayton26b47e22012-04-18 05:19:20 +00002072 PlatformSP platform_sp (target.GetPlatform());
Jason Molenda0e0954c2013-04-16 06:24:42 +00002073 if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
Greg Clayton26b47e22012-04-18 05:19:20 +00002074 {
2075 data_was_read = true;
2076 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Clayton4c82d422012-05-18 23:20:01 +00002077 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton26b47e22012-04-18 05:19:20 +00002078 if (function_starts_load_command.cmd)
2079 {
2080 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2081 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
2082 }
2083 }
2084 }
2085#endif
2086
2087 if (!data_was_read)
2088 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002089 if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
Jason Molendad34e6522013-02-05 22:31:24 +00002090 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002091 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
2092 if (nlist_data_sp)
2093 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2094 // Load strings individually from memory when loading from memory since shared cache
2095 // string tables contain strings for all symbols from all shared cached libraries
2096 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
2097 //if (strtab_data_sp)
2098 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
2099 if (m_dysymtab.nindirectsyms != 0)
2100 {
2101 const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
2102 DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
2103 if (indirect_syms_data_sp)
2104 indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2105 }
Jason Molendad34e6522013-02-05 22:31:24 +00002106 }
Greg Claytonfd814c52013-08-13 01:42:25 +00002107
2108 if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
Greg Clayton26b47e22012-04-18 05:19:20 +00002109 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002110 if (function_starts_load_command.cmd)
2111 {
2112 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2113 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
2114 if (func_start_data_sp)
2115 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
2116 }
Greg Clayton26b47e22012-04-18 05:19:20 +00002117 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002118 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002119 }
2120 }
2121 else
2122 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002123 nlist_data.SetData (m_data,
2124 symtab_load_command.symoff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002125 nlist_data_byte_size);
2126 strtab_data.SetData (m_data,
Jason Molenda4e7511e2013-03-06 23:19:17 +00002127 symtab_load_command.stroff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002128 strtab_data_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002129
2130 if (dyld_info.export_size > 0)
2131 {
2132 dyld_trie_data.SetData (m_data,
2133 dyld_info.export_off,
2134 dyld_info.export_size);
2135 }
2136
Jason Molendad34e6522013-02-05 22:31:24 +00002137 if (m_dysymtab.nindirectsyms != 0)
2138 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002139 indirect_symbol_index_data.SetData (m_data,
2140 m_dysymtab.indirectsymoff,
Jason Molendad34e6522013-02-05 22:31:24 +00002141 m_dysymtab.nindirectsyms * 4);
2142 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002143 if (function_starts_load_command.cmd)
2144 {
2145 function_starts_data.SetData (m_data,
2146 function_starts_load_command.dataoff,
2147 function_starts_load_command.datasize);
2148 }
2149 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002150
Greg Clayton86eac942013-08-13 21:32:34 +00002151 if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete)
2152 {
2153 if (log)
2154 module_sp->LogMessage(log, "failed to read nlist data");
2155 return 0;
2156 }
2157
2158
Greg Claytondebb8812012-05-25 17:04:00 +00002159 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2160 if (!have_strtab_data)
Greg Clayton4c82d422012-05-18 23:20:01 +00002161 {
Greg Claytondebb8812012-05-25 17:04:00 +00002162 if (process)
2163 {
2164 if (strtab_addr == LLDB_INVALID_ADDRESS)
2165 {
2166 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002167 module_sp->LogMessage(log, "failed to locate the strtab in memory");
Greg Claytondebb8812012-05-25 17:04:00 +00002168 return 0;
2169 }
2170 }
2171 else
Greg Clayton4c82d422012-05-18 23:20:01 +00002172 {
2173 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002174 module_sp->LogMessage(log, "failed to read strtab data");
Greg Clayton4c82d422012-05-18 23:20:01 +00002175 return 0;
2176 }
2177 }
Greg Clayton4c82d422012-05-18 23:20:01 +00002178
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002179 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
2180 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
2181 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
2182 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
2183 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
2184 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
2185 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
2186 SectionSP eh_frame_section_sp;
2187 if (text_section_sp.get())
2188 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
2189 else
2190 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
2191
Charles Davis510938e2013-08-27 05:04:57 +00002192 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
Jason Molenda5635f772013-03-21 03:36:01 +00002193
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002194 // lldb works best if it knows the start address of all functions in a module.
Jason Molenda5635f772013-03-21 03:36:01 +00002195 // Linker symbols or debug info are normally the best source of information for start addr / size but
2196 // they may be stripped in a released binary.
Jason Molendad63d3c72013-04-16 00:18:44 +00002197 // Two additional sources of information exist in Mach-O binaries:
Jason Molenda5635f772013-03-21 03:36:01 +00002198 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
2199 // binary, relative to the text section.
2200 // eh_frame - the eh_frame FDEs have the start addr & size of each function
2201 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
2202 // Binaries built to run on older releases may need to use eh_frame information.
2203
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002204 if (text_section_sp && function_starts_data.GetByteSize())
2205 {
2206 FunctionStarts::Entry function_start_entry;
2207 function_start_entry.data = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00002208 lldb::offset_t function_start_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002209 function_start_entry.addr = text_section_sp->GetFileAddress();
2210 uint64_t delta;
2211 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
2212 {
2213 // Now append the current entry
2214 function_start_entry.addr += delta;
2215 function_starts.Append(function_start_entry);
2216 }
Jason Molendad63d3c72013-04-16 00:18:44 +00002217 }
Jason Molenda5635f772013-03-21 03:36:01 +00002218 else
2219 {
Jason Molenda584ce2f2013-03-22 00:38:45 +00002220 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
2221 // but it doesn't actually have the eh_frame content. And if we have a dSYM, we don't need to do any
2222 // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
2223 // the module.
2224 if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
Jason Molenda5635f772013-03-21 03:36:01 +00002225 {
2226 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindGCC, true);
2227 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
2228 eh_frame.GetFunctionAddressAndSizeVector (functions);
2229 addr_t text_base_addr = text_section_sp->GetFileAddress();
2230 size_t count = functions.GetSize();
2231 for (size_t i = 0; i < count; ++i)
2232 {
2233 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
2234 if (func)
2235 {
2236 FunctionStarts::Entry function_start_entry;
2237 function_start_entry.addr = func->base - text_base_addr;
2238 function_starts.Append(function_start_entry);
2239 }
2240 }
2241 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002242 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002243
Greg Claytonc7bece562013-01-25 18:06:21 +00002244 const size_t function_starts_count = function_starts.GetSize();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002245
Saleem Abdulrasoolb5c128b2014-07-23 01:53:52 +00002246 const user_id_t TEXT_eh_frame_sectID =
2247 eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
2248 : static_cast<user_id_t>(NO_SECT);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002249
Greg Claytonc7bece562013-01-25 18:06:21 +00002250 lldb::offset_t nlist_data_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002251
2252 uint32_t N_SO_index = UINT32_MAX;
2253
2254 MachSymtabSectionInfo section_info (section_list);
2255 std::vector<uint32_t> N_FUN_indexes;
2256 std::vector<uint32_t> N_NSYM_indexes;
2257 std::vector<uint32_t> N_INCL_indexes;
2258 std::vector<uint32_t> N_BRAC_indexes;
2259 std::vector<uint32_t> N_COMM_indexes;
Greg Claytond81088c2014-01-16 01:38:29 +00002260 typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002261 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
Greg Claytondacc4a92013-05-14 22:19:37 +00002262 typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002263 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2264 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
Greg Claytondacc4a92013-05-14 22:19:37 +00002265 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002266 // Any symbols that get merged into another will get an entry
2267 // in this map so we know
2268 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2269 uint32_t nlist_idx = 0;
2270 Symbol *symbol_ptr = NULL;
2271
2272 uint32_t sym_idx = 0;
Jason Molendaa5609c82012-06-21 01:51:02 +00002273 Symbol *sym = NULL;
Greg Claytonc7bece562013-01-25 18:06:21 +00002274 size_t num_syms = 0;
Greg Clayton4c82d422012-05-18 23:20:01 +00002275 std::string memory_symbol_name;
Jason Molendaa5609c82012-06-21 01:51:02 +00002276 uint32_t unmapped_local_symbols_found = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002277
Jim Inghamea3ac272014-01-10 22:55:37 +00002278 std::vector<TrieEntryWithOffset> trie_entries;
2279 std::set<lldb::addr_t> resolver_addresses;
2280
2281 if (dyld_trie_data.GetByteSize() > 0)
2282 {
2283 std::vector<llvm::StringRef> nameSlices;
2284 ParseTrieEntries (dyld_trie_data,
2285 0,
2286 nameSlices,
2287 resolver_addresses,
2288 trie_entries);
2289
2290 ConstString text_segment_name ("__TEXT");
2291 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2292 if (text_segment_sp)
2293 {
2294 const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
2295 if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
2296 {
2297 for (auto &e : trie_entries)
2298 e.entry.address += text_segment_file_addr;
2299 }
2300 }
2301 }
2302
Todd Fiala013434e2014-07-09 01:29:05 +00002303#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa5609c82012-06-21 01:51:02 +00002304
2305 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
2306 // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
2307 // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
2308 // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
2309 // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
2310 // nlist parser to ignore all LOCAL symbols.
2311
2312 if (m_header.flags & 0x80000000u)
2313 {
2314 // Before we can start mapping the DSC, we need to make certain the target process is actually
2315 // using the cache we can find.
2316
Jason Molendaa5609c82012-06-21 01:51:02 +00002317 // Next we need to determine the correct path for the dyld shared cache.
2318
Greg Clayton7ab7f892014-05-29 21:33:45 +00002319 ArchSpec header_arch;
2320 GetArchitecture(header_arch);
Jason Molendaa5609c82012-06-21 01:51:02 +00002321 char dsc_path[PATH_MAX];
2322
2323 snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
Jason Molenda4e7511e2013-03-06 23:19:17 +00002324 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
2325 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
Jason Molendaa5609c82012-06-21 01:51:02 +00002326 header_arch.GetArchitectureName());
2327
2328 FileSpec dsc_filespec(dsc_path, false);
2329
2330 // We need definitions of two structures in the on-disk DSC, copy them here manually
Jason Molendad63d3c72013-04-16 00:18:44 +00002331 struct lldb_copy_dyld_cache_header_v0
Greg Clayton946f8902012-09-05 22:30:51 +00002332 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002333 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2334 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2335 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
Jason Molenda4e7511e2013-03-06 23:19:17 +00002336 uint32_t imagesOffset;
2337 uint32_t imagesCount;
2338 uint64_t dyldBaseAddress;
2339 uint64_t codeSignatureOffset;
2340 uint64_t codeSignatureSize;
2341 uint64_t slideInfoOffset;
2342 uint64_t slideInfoSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002343 uint64_t localSymbolsOffset; // file offset of where local symbols are stored
2344 uint64_t localSymbolsSize; // size of local symbols information
2345 };
2346 struct lldb_copy_dyld_cache_header_v1
2347 {
2348 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2349 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2350 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
2351 uint32_t imagesOffset;
2352 uint32_t imagesCount;
2353 uint64_t dyldBaseAddress;
2354 uint64_t codeSignatureOffset;
2355 uint64_t codeSignatureSize;
2356 uint64_t slideInfoOffset;
2357 uint64_t slideInfoSize;
Jason Molenda4e7511e2013-03-06 23:19:17 +00002358 uint64_t localSymbolsOffset;
2359 uint64_t localSymbolsSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002360 uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later
Greg Clayton946f8902012-09-05 22:30:51 +00002361 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002362
Jason Molendad63d3c72013-04-16 00:18:44 +00002363 struct lldb_copy_dyld_cache_mapping_info
2364 {
2365 uint64_t address;
2366 uint64_t size;
2367 uint64_t fileOffset;
2368 uint32_t maxProt;
2369 uint32_t initProt;
2370 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002371
Greg Clayton946f8902012-09-05 22:30:51 +00002372 struct lldb_copy_dyld_cache_local_symbols_info
2373 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002374 uint32_t nlistOffset;
2375 uint32_t nlistCount;
2376 uint32_t stringsOffset;
2377 uint32_t stringsSize;
2378 uint32_t entriesOffset;
2379 uint32_t entriesCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002380 };
2381 struct lldb_copy_dyld_cache_local_symbols_entry
2382 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002383 uint32_t dylibOffset;
2384 uint32_t nlistStartIndex;
2385 uint32_t nlistCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002386 };
Jason Molendaa5609c82012-06-21 01:51:02 +00002387
Jason Molendaf8130862012-06-22 03:28:35 +00002388 /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
2389 The dyld_cache_local_symbols_info structure gives us three things:
2390 1. The start and count of the nlist records in the dyld_shared_cache file
2391 2. The start and size of the strings for these nlist records
2392 3. The start and count of dyld_cache_local_symbols_entry entries
2393
2394 There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
2395 The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
Jason Molenda4e7511e2013-03-06 23:19:17 +00002396 The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
Jason Molendaf8130862012-06-22 03:28:35 +00002397 and the count of how many nlist records there are for this dylib/framework.
2398 */
2399
Jason Molendaa5609c82012-06-21 01:51:02 +00002400 // Process the dsc header to find the unmapped symbols
2401 //
2402 // Save some VM space, do not map the entire cache in one shot.
2403
Jason Molenda255f9bb2013-03-06 23:17:36 +00002404 DataBufferSP dsc_data_sp;
2405 dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
2406
2407 if (dsc_data_sp)
Jason Molendaa5609c82012-06-21 01:51:02 +00002408 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002409 DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002410
Jason Molenda255f9bb2013-03-06 23:17:36 +00002411 char version_str[17];
2412 int version = -1;
2413 lldb::offset_t offset = 0;
2414 memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16);
2415 version_str[16] = '\0';
2416 if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6]))
2417 {
2418 int v;
2419 if (::sscanf (version_str + 6, "%d", &v) == 1)
2420 {
2421 version = v;
2422 }
2423 }
2424
Jason Molenda0e0954c2013-04-16 06:24:42 +00002425 UUID dsc_uuid;
2426 if (version >= 1)
2427 {
2428 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
2429 uint8_t uuid_bytes[sizeof (uuid_t)];
2430 memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
2431 dsc_uuid.SetBytes (uuid_bytes);
2432 }
2433
2434 bool uuid_match = true;
2435 if (dsc_uuid.IsValid() && process)
2436 {
2437 UUID shared_cache_uuid(GetProcessSharedCacheUUID(process));
2438
2439 if (shared_cache_uuid.IsValid() && dsc_uuid != shared_cache_uuid)
2440 {
2441 // The on-disk dyld_shared_cache file is not the same as the one in this
2442 // process' memory, don't use it.
2443 uuid_match = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002444 ModuleSP module_sp (GetModule());
2445 if (module_sp)
2446 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 +00002447 }
2448 }
2449
Jason Molenda4e7511e2013-03-06 23:19:17 +00002450 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);
Jason Molenda255f9bb2013-03-06 23:17:36 +00002451
Jason Molendaa5609c82012-06-21 01:51:02 +00002452 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
2453
2454 // If the mappingOffset points to a location inside the header, we've
2455 // opened an old dyld shared cache, and should not proceed further.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002456 if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
Jason Molendaa5609c82012-06-21 01:51:02 +00002457 {
2458
Jason Molenda255f9bb2013-03-06 23:17:36 +00002459 DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContents(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
2460 DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
2461 offset = 0;
2462
2463 // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
2464 // in the shared library cache need to be adjusted by an offset to match up with the
2465 // dylibOffset identifying field in the dyld_cache_local_symbol_entry's. This offset is
2466 // recorded in mapping_offset_value.
2467 const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
2468
2469 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
Jason Molendaa5609c82012-06-21 01:51:02 +00002470 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
2471 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
2472
Jason Molenda4e7511e2013-03-06 23:19:17 +00002473 if (localSymbolsOffset && localSymbolsSize)
Jason Molendaa5609c82012-06-21 01:51:02 +00002474 {
2475 // Map the local symbols
Jason Molenda4e7511e2013-03-06 23:19:17 +00002476 if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
Jason Molendaa5609c82012-06-21 01:51:02 +00002477 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002478 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002479
2480 offset = 0;
2481
2482 // Read the local_symbols_infos struct in one shot
2483 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
2484 dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
2485
Jason Molendaa5609c82012-06-21 01:51:02 +00002486 SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
2487
Jason Molenda255f9bb2013-03-06 23:17:36 +00002488 uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00002489
2490 offset = local_symbols_info.entriesOffset;
2491 for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
2492 {
2493 struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
2494 local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
2495 local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
2496 local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
2497
Jason Molenda4e7511e2013-03-06 23:19:17 +00002498 if (header_file_offset == local_symbols_entry.dylibOffset)
Jason Molendaa5609c82012-06-21 01:51:02 +00002499 {
2500 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
2501
2502 // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
2503 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2504 num_syms = symtab->GetNumSymbols();
2505
2506 nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
2507 uint32_t string_table_offset = local_symbols_info.stringsOffset;
2508
Jason Molenda4e7511e2013-03-06 23:19:17 +00002509 for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
Jason Molendaa5609c82012-06-21 01:51:02 +00002510 {
2511 /////////////////////////////
2512 {
2513 struct nlist_64 nlist;
2514 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2515 break;
2516
2517 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
2518 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2519 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2520 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
2521 nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
2522
2523 SymbolType type = eSymbolTypeInvalid;
2524 const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
2525
2526 if (symbol_name == NULL)
2527 {
2528 // No symbol should be NULL, even the symbols with no
2529 // string values should have an offset zero which points
2530 // to an empty C-string
2531 Host::SystemLog (Host::eSystemLogError,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002532 "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 +00002533 entry_index,
2534 nlist.n_strx,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002535 module_sp->GetFileSpec().GetPath().c_str());
Jason Molendaa5609c82012-06-21 01:51:02 +00002536 continue;
2537 }
2538 if (symbol_name[0] == '\0')
2539 symbol_name = NULL;
2540
2541 const char *symbol_name_non_abi_mangled = NULL;
2542
2543 SectionSP symbol_section;
2544 uint32_t symbol_byte_size = 0;
2545 bool add_nlist = true;
Charles Davis510938e2013-08-27 05:04:57 +00002546 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002547 bool demangled_is_synthesized = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00002548 bool is_gsym = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002549
2550 assert (sym_idx < num_syms);
2551
2552 sym[sym_idx].SetDebug (is_debug);
2553
2554 if (is_debug)
2555 {
2556 switch (nlist.n_type)
2557 {
Charles Davis510938e2013-08-27 05:04:57 +00002558 case N_GSYM:
2559 // global symbol: name,,NO_SECT,type,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002560 // Sometimes the N_GSYM value contains the address.
2561
2562 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
2563 // have the same address, but we want to ensure that we always find only the real symbol,
2564 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
2565 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
2566 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
2567 // same address.
2568
2569 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
2570 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
2571 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
2572 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
2573 add_nlist = false;
2574 else
2575 {
Greg Claytondacc4a92013-05-14 22:19:37 +00002576 is_gsym = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00002577 sym[sym_idx].SetExternal(true);
2578 if (nlist.n_value != 0)
2579 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2580 type = eSymbolTypeData;
2581 }
2582 break;
2583
Charles Davis510938e2013-08-27 05:04:57 +00002584 case N_FNAME:
2585 // procedure name (f77 kludge): name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002586 type = eSymbolTypeCompiler;
2587 break;
2588
Charles Davis510938e2013-08-27 05:04:57 +00002589 case N_FUN:
2590 // procedure: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002591 if (symbol_name)
2592 {
2593 type = eSymbolTypeCode;
2594 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2595
Greg Claytond81088c2014-01-16 01:38:29 +00002596 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002597 // We use the current number of symbols in the symbol table in lieu of
2598 // using nlist_idx in case we ever start trimming entries out
2599 N_FUN_indexes.push_back(sym_idx);
2600 }
2601 else
2602 {
2603 type = eSymbolTypeCompiler;
2604
2605 if ( !N_FUN_indexes.empty() )
2606 {
2607 // Copy the size of the function into the original STAB entry so we don't have
2608 // to hunt for it later
2609 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
2610 N_FUN_indexes.pop_back();
2611 // We don't really need the end function STAB as it contains the size which
2612 // we already placed with the original symbol, so don't add it if we want a
2613 // minimal symbol table
Greg Clayton3046e662013-07-10 01:23:25 +00002614 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002615 }
2616 }
2617 break;
2618
Charles Davis510938e2013-08-27 05:04:57 +00002619 case N_STSYM:
2620 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00002621 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002622 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2623 type = eSymbolTypeData;
2624 break;
2625
Charles Davis510938e2013-08-27 05:04:57 +00002626 case N_LCSYM:
2627 // .lcomm symbol: name,,n_sect,type,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002628 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2629 type = eSymbolTypeCommonBlock;
2630 break;
2631
Charles Davis510938e2013-08-27 05:04:57 +00002632 case N_BNSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002633 // We use the current number of symbols in the symbol table in lieu of
2634 // using nlist_idx in case we ever start trimming entries out
Greg Clayton3046e662013-07-10 01:23:25 +00002635 // Skip these if we want minimal symbol tables
2636 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002637 break;
2638
Charles Davis510938e2013-08-27 05:04:57 +00002639 case N_ENSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002640 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
2641 // so that we can always skip the entire symbol if we need to navigate
2642 // more quickly at the source level when parsing STABS
Greg Clayton3046e662013-07-10 01:23:25 +00002643 // Skip these if we want minimal symbol tables
2644 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002645 break;
2646
2647
Charles Davis510938e2013-08-27 05:04:57 +00002648 case N_OPT:
2649 // emitted with gcc2_compiled and in gcc source
Jason Molendaa5609c82012-06-21 01:51:02 +00002650 type = eSymbolTypeCompiler;
2651 break;
2652
Charles Davis510938e2013-08-27 05:04:57 +00002653 case N_RSYM:
2654 // register sym: name,,NO_SECT,type,register
Jason Molendaa5609c82012-06-21 01:51:02 +00002655 type = eSymbolTypeVariable;
2656 break;
2657
Charles Davis510938e2013-08-27 05:04:57 +00002658 case N_SLINE:
2659 // src line: 0,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002660 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2661 type = eSymbolTypeLineEntry;
2662 break;
2663
Charles Davis510938e2013-08-27 05:04:57 +00002664 case N_SSYM:
2665 // structure elt: name,,NO_SECT,type,struct_offset
Jason Molendaa5609c82012-06-21 01:51:02 +00002666 type = eSymbolTypeVariableType;
2667 break;
2668
Charles Davis510938e2013-08-27 05:04:57 +00002669 case N_SO:
2670 // source file name
Jason Molendaa5609c82012-06-21 01:51:02 +00002671 type = eSymbolTypeSourceFile;
2672 if (symbol_name == NULL)
2673 {
Greg Clayton3046e662013-07-10 01:23:25 +00002674 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002675 if (N_SO_index != UINT32_MAX)
2676 {
2677 // Set the size of the N_SO to the terminating index of this N_SO
2678 // so that we can always skip the entire N_SO if we need to navigate
2679 // more quickly at the source level when parsing STABS
2680 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
Greg Clayton3046e662013-07-10 01:23:25 +00002681 symbol_ptr->SetByteSize(sym_idx);
Jason Molendaa5609c82012-06-21 01:51:02 +00002682 symbol_ptr->SetSizeIsSibling(true);
2683 }
2684 N_NSYM_indexes.clear();
2685 N_INCL_indexes.clear();
2686 N_BRAC_indexes.clear();
2687 N_COMM_indexes.clear();
2688 N_FUN_indexes.clear();
2689 N_SO_index = UINT32_MAX;
2690 }
2691 else
2692 {
2693 // We use the current number of symbols in the symbol table in lieu of
2694 // using nlist_idx in case we ever start trimming entries out
2695 const bool N_SO_has_full_path = symbol_name[0] == '/';
2696 if (N_SO_has_full_path)
2697 {
Greg Clayton3046e662013-07-10 01:23:25 +00002698 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00002699 {
2700 // We have two consecutive N_SO entries where the first contains a directory
2701 // and the second contains a full path.
Jason Molendad9d5cf52012-07-20 03:35:44 +00002702 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00002703 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2704 add_nlist = false;
2705 }
2706 else
2707 {
2708 // This is the first entry in a N_SO that contains a directory or
2709 // a full path to the source file
2710 N_SO_index = sym_idx;
2711 }
2712 }
Greg Clayton3046e662013-07-10 01:23:25 +00002713 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00002714 {
2715 // This is usually the second N_SO entry that contains just the filename,
2716 // so here we combine it with the first one if we are minimizing the symbol table
2717 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
2718 if (so_path && so_path[0])
2719 {
2720 std::string full_so_path (so_path);
Greg Clayton0662d962012-09-07 20:29:13 +00002721 const size_t double_slash_pos = full_so_path.find("//");
2722 if (double_slash_pos != std::string::npos)
2723 {
2724 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00002725 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Clayton0662d962012-09-07 20:29:13 +00002726 // and the second is the directory for the source file so you end up with
2727 // a path that looks like "/tmp/src//tmp/src/"
2728 FileSpec so_dir(so_path, false);
2729 if (!so_dir.Exists())
2730 {
2731 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
2732 if (so_dir.Exists())
2733 {
2734 // Trim off the incorrect path
2735 full_so_path.erase(0, double_slash_pos + 1);
2736 }
2737 }
2738 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002739 if (*full_so_path.rbegin() != '/')
2740 full_so_path += '/';
2741 full_so_path += symbol_name;
Jason Molendad9d5cf52012-07-20 03:35:44 +00002742 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00002743 add_nlist = false;
2744 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2745 }
2746 }
Greg Clayton946f8902012-09-05 22:30:51 +00002747 else
2748 {
2749 // This could be a relative path to a N_SO
2750 N_SO_index = sym_idx;
2751 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002752 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002753 break;
2754
Charles Davis510938e2013-08-27 05:04:57 +00002755 case N_OSO:
2756 // object file name: name,,0,0,st_mtime
Jason Molendaa5609c82012-06-21 01:51:02 +00002757 type = eSymbolTypeObjectFile;
2758 break;
2759
Charles Davis510938e2013-08-27 05:04:57 +00002760 case N_LSYM:
2761 // local sym: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00002762 type = eSymbolTypeLocal;
2763 break;
2764
2765 //----------------------------------------------------------------------
2766 // INCL scopes
2767 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00002768 case N_BINCL:
2769 // include file beginning: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00002770 // We use the current number of symbols in the symbol table in lieu of
2771 // using nlist_idx in case we ever start trimming entries out
2772 N_INCL_indexes.push_back(sym_idx);
2773 type = eSymbolTypeScopeBegin;
2774 break;
2775
Charles Davis510938e2013-08-27 05:04:57 +00002776 case N_EINCL:
2777 // include file end: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002778 // Set the size of the N_BINCL to the terminating index of this N_EINCL
2779 // so that we can always skip the entire symbol if we need to navigate
2780 // more quickly at the source level when parsing STABS
2781 if ( !N_INCL_indexes.empty() )
2782 {
2783 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
2784 symbol_ptr->SetByteSize(sym_idx + 1);
2785 symbol_ptr->SetSizeIsSibling(true);
2786 N_INCL_indexes.pop_back();
2787 }
2788 type = eSymbolTypeScopeEnd;
2789 break;
2790
Charles Davis510938e2013-08-27 05:04:57 +00002791 case N_SOL:
2792 // #included file name: name,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002793 type = eSymbolTypeHeaderFile;
2794
2795 // We currently don't use the header files on darwin
Greg Clayton3046e662013-07-10 01:23:25 +00002796 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002797 break;
2798
Charles Davis510938e2013-08-27 05:04:57 +00002799 case N_PARAMS:
2800 // compiler parameters: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002801 type = eSymbolTypeCompiler;
2802 break;
2803
Charles Davis510938e2013-08-27 05:04:57 +00002804 case N_VERSION:
2805 // compiler version: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002806 type = eSymbolTypeCompiler;
2807 break;
2808
Charles Davis510938e2013-08-27 05:04:57 +00002809 case N_OLEVEL:
2810 // compiler -O level: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002811 type = eSymbolTypeCompiler;
2812 break;
2813
Charles Davis510938e2013-08-27 05:04:57 +00002814 case N_PSYM:
2815 // parameter: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00002816 type = eSymbolTypeVariable;
2817 break;
2818
Charles Davis510938e2013-08-27 05:04:57 +00002819 case N_ENTRY:
2820 // alternate entry: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002821 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2822 type = eSymbolTypeLineEntry;
2823 break;
2824
2825 //----------------------------------------------------------------------
2826 // Left and Right Braces
2827 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00002828 case N_LBRAC:
2829 // left bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002830 // We use the current number of symbols in the symbol table in lieu of
2831 // using nlist_idx in case we ever start trimming entries out
2832 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2833 N_BRAC_indexes.push_back(sym_idx);
2834 type = eSymbolTypeScopeBegin;
2835 break;
2836
Charles Davis510938e2013-08-27 05:04:57 +00002837 case N_RBRAC:
2838 // right bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002839 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
2840 // so that we can always skip the entire symbol if we need to navigate
2841 // more quickly at the source level when parsing STABS
2842 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2843 if ( !N_BRAC_indexes.empty() )
2844 {
2845 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
2846 symbol_ptr->SetByteSize(sym_idx + 1);
2847 symbol_ptr->SetSizeIsSibling(true);
2848 N_BRAC_indexes.pop_back();
2849 }
2850 type = eSymbolTypeScopeEnd;
2851 break;
2852
Charles Davis510938e2013-08-27 05:04:57 +00002853 case N_EXCL:
2854 // deleted include file: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00002855 type = eSymbolTypeHeaderFile;
2856 break;
2857
2858 //----------------------------------------------------------------------
2859 // COMM scopes
2860 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00002861 case N_BCOMM:
2862 // begin common: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002863 // We use the current number of symbols in the symbol table in lieu of
2864 // using nlist_idx in case we ever start trimming entries out
2865 type = eSymbolTypeScopeBegin;
2866 N_COMM_indexes.push_back(sym_idx);
2867 break;
2868
Charles Davis510938e2013-08-27 05:04:57 +00002869 case N_ECOML:
2870 // end common (local name): 0,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002871 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2872 // Fall through
2873
Charles Davis510938e2013-08-27 05:04:57 +00002874 case N_ECOMM:
2875 // end common: name,,n_sect,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002876 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
2877 // so that we can always skip the entire symbol if we need to navigate
2878 // more quickly at the source level when parsing STABS
2879 if ( !N_COMM_indexes.empty() )
2880 {
2881 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
2882 symbol_ptr->SetByteSize(sym_idx + 1);
2883 symbol_ptr->SetSizeIsSibling(true);
2884 N_COMM_indexes.pop_back();
2885 }
2886 type = eSymbolTypeScopeEnd;
2887 break;
2888
Charles Davis510938e2013-08-27 05:04:57 +00002889 case N_LENG:
2890 // second stab entry with length information
Jason Molendaa5609c82012-06-21 01:51:02 +00002891 type = eSymbolTypeAdditional;
2892 break;
2893
2894 default: break;
2895 }
2896 }
2897 else
2898 {
Charles Davis510938e2013-08-27 05:04:57 +00002899 //uint8_t n_pext = N_PEXT & nlist.n_type;
2900 uint8_t n_type = N_TYPE & nlist.n_type;
2901 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Jason Molendaa5609c82012-06-21 01:51:02 +00002902
2903 switch (n_type)
2904 {
Charles Davis510938e2013-08-27 05:04:57 +00002905 case N_INDR: // Fall through
2906 case N_PBUD: // Fall through
2907 case N_UNDF:
Jason Molendaa5609c82012-06-21 01:51:02 +00002908 type = eSymbolTypeUndefined;
2909 break;
2910
Charles Davis510938e2013-08-27 05:04:57 +00002911 case N_ABS:
Jason Molendaa5609c82012-06-21 01:51:02 +00002912 type = eSymbolTypeAbsolute;
2913 break;
2914
Charles Davis510938e2013-08-27 05:04:57 +00002915 case N_SECT:
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002916 {
2917 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00002918
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002919 if (symbol_section == NULL)
Jason Molendaa5609c82012-06-21 01:51:02 +00002920 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002921 // TODO: warn about this?
2922 add_nlist = false;
2923 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00002924 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002925
2926 if (TEXT_eh_frame_sectID == nlist.n_sect)
Jason Molendaa5609c82012-06-21 01:51:02 +00002927 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002928 type = eSymbolTypeException;
2929 }
2930 else
2931 {
Charles Davis510938e2013-08-27 05:04:57 +00002932 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Jason Molenda4e7511e2013-03-06 23:19:17 +00002933
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002934 switch (section_type)
Jason Molendaa5609c82012-06-21 01:51:02 +00002935 {
Charles Davis510938e2013-08-27 05:04:57 +00002936 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
2937 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
2938 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
2939 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
2940 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
2941 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
2942 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
2943 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
2944 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00002945 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
2946 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
2947 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
2948 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00002949 default:
2950 switch (symbol_section->GetType())
2951 {
2952 case lldb::eSectionTypeCode:
2953 type = eSymbolTypeCode;
2954 break;
2955 case eSectionTypeData:
2956 case eSectionTypeDataCString: // Inlined C string data
2957 case eSectionTypeDataCStringPointers: // Pointers to C string data
2958 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
2959 case eSectionTypeData4:
2960 case eSectionTypeData8:
2961 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00002962 type = eSymbolTypeData;
2963 break;
2964 default:
2965 break;
2966 }
2967 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00002968 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002969
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002970 if (type == eSymbolTypeInvalid)
2971 {
2972 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2973 if (symbol_section->IsDescendant (text_section_sp.get()))
2974 {
Charles Davis510938e2013-08-27 05:04:57 +00002975 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
2976 S_ATTR_SELF_MODIFYING_CODE |
2977 S_ATTR_SOME_INSTRUCTIONS))
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002978 type = eSymbolTypeData;
2979 else
2980 type = eSymbolTypeCode;
2981 }
2982 else if (symbol_section->IsDescendant(data_section_sp.get()))
Jason Molendaa5609c82012-06-21 01:51:02 +00002983 {
2984 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
2985 {
2986 type = eSymbolTypeRuntime;
Jason Molenda4e7511e2013-03-06 23:19:17 +00002987
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002988 if (symbol_name &&
2989 symbol_name[0] == '_' &&
2990 symbol_name[1] == 'O' &&
Jason Molendaa5609c82012-06-21 01:51:02 +00002991 symbol_name[2] == 'B')
2992 {
2993 llvm::StringRef symbol_name_ref(symbol_name);
2994 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2995 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2996 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
2997 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
2998 {
2999 symbol_name_non_abi_mangled = symbol_name + 1;
3000 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3001 type = eSymbolTypeObjCClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003002 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003003 }
3004 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3005 {
3006 symbol_name_non_abi_mangled = symbol_name + 1;
3007 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3008 type = eSymbolTypeObjCMetaClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003009 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003010 }
3011 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3012 {
3013 symbol_name_non_abi_mangled = symbol_name + 1;
3014 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3015 type = eSymbolTypeObjCIVar;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003016 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003017 }
3018 }
3019 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003020 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
Jason Molendaa5609c82012-06-21 01:51:02 +00003021 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003022 type = eSymbolTypeException;
Jason Molendaa5609c82012-06-21 01:51:02 +00003023 }
3024 else
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003025 {
3026 type = eSymbolTypeData;
3027 }
3028 }
3029 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
3030 {
3031 type = eSymbolTypeTrampoline;
3032 }
3033 else if (symbol_section->IsDescendant(objc_section_sp.get()))
3034 {
3035 type = eSymbolTypeRuntime;
3036 if (symbol_name && symbol_name[0] == '.')
3037 {
3038 llvm::StringRef symbol_name_ref(symbol_name);
3039 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
3040 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
Jason Molendaa5609c82012-06-21 01:51:02 +00003041 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003042 symbol_name_non_abi_mangled = symbol_name;
3043 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
3044 type = eSymbolTypeObjCClass;
3045 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003046 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003047 }
3048 }
3049 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003050 }
3051 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003052 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003053 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003054 }
3055
3056 if (add_nlist)
3057 {
3058 uint64_t symbol_value = nlist.n_value;
Jason Molendaa5609c82012-06-21 01:51:02 +00003059 if (symbol_name_non_abi_mangled)
3060 {
Jason Molendad9d5cf52012-07-20 03:35:44 +00003061 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
3062 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Jason Molendaa5609c82012-06-21 01:51:02 +00003063 }
3064 else
3065 {
Greg Clayton3046e662013-07-10 01:23:25 +00003066 bool symbol_name_is_mangled = false;
3067
Jason Molendaa5609c82012-06-21 01:51:02 +00003068 if (symbol_name && symbol_name[0] == '_')
3069 {
3070 symbol_name_is_mangled = symbol_name[1] == '_';
3071 symbol_name++; // Skip the leading underscore
3072 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003073
Jason Molendaa5609c82012-06-21 01:51:02 +00003074 if (symbol_name)
3075 {
Greg Claytondacc4a92013-05-14 22:19:37 +00003076 ConstString const_symbol_name(symbol_name);
Greg Claytondacc4a92013-05-14 22:19:37 +00003077 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Clayton3046e662013-07-10 01:23:25 +00003078 if (is_gsym && is_debug)
3079 N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
Jason Molendaa5609c82012-06-21 01:51:02 +00003080 }
3081 }
3082 if (symbol_section)
3083 {
3084 const addr_t section_file_addr = symbol_section->GetFileAddress();
3085 if (symbol_byte_size == 0 && function_starts_count > 0)
3086 {
3087 addr_t symbol_lookup_file_addr = nlist.n_value;
3088 // Do an exact address match for non-ARM addresses, else get the closest since
3089 // the symbol might be a thumb symbol which has an address with bit zero set
3090 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
3091 if (is_arm && func_start_entry)
3092 {
3093 // Verify that the function start address is the symbol address (ARM)
3094 // or the symbol address + 1 (thumb)
3095 if (func_start_entry->addr != symbol_lookup_file_addr &&
3096 func_start_entry->addr != (symbol_lookup_file_addr + 1))
3097 {
3098 // Not the right entry, NULL it out...
3099 func_start_entry = NULL;
3100 }
3101 }
3102 if (func_start_entry)
3103 {
3104 func_start_entry->data = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003105
Jason Molendaa5609c82012-06-21 01:51:02 +00003106 addr_t symbol_file_addr = func_start_entry->addr;
3107 uint32_t symbol_flags = 0;
3108 if (is_arm)
3109 {
3110 if (symbol_file_addr & 1)
3111 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
3112 symbol_file_addr &= 0xfffffffffffffffeull;
3113 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003114
Jason Molendaa5609c82012-06-21 01:51:02 +00003115 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3116 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3117 if (next_func_start_entry)
3118 {
3119 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3120 // Be sure the clear the Thumb address bit when we calculate the size
3121 // from the current and next address
3122 if (is_arm)
3123 next_symbol_file_addr &= 0xfffffffffffffffeull;
3124 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
3125 }
3126 else
3127 {
3128 symbol_byte_size = section_end_file_addr - symbol_file_addr;
3129 }
3130 }
3131 }
3132 symbol_value -= section_file_addr;
3133 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003134
Greg Claytondacc4a92013-05-14 22:19:37 +00003135 if (is_debug == false)
3136 {
3137 if (type == eSymbolTypeCode)
3138 {
3139 // See if we can find a N_FUN entry for any code symbols.
3140 // If we do find a match, and the name matches, then we
3141 // can merge the two into just the function symbol to avoid
3142 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003143 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3144 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3145 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003146 {
Greg Claytond81088c2014-01-16 01:38:29 +00003147 bool found_it = false;
3148 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003149 {
Greg Claytond81088c2014-01-16 01:38:29 +00003150 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3151 {
3152 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3153 // We just need the flags from the linker symbol, so put these flags
3154 // into the N_FUN flags to avoid duplicate symbols in the symbol table
3155 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3156 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3157 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
3158 sym[pos->second].SetType (eSymbolTypeResolver);
3159 sym[sym_idx].Clear();
3160 found_it = true;
3161 break;
3162 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003163 }
Greg Claytond81088c2014-01-16 01:38:29 +00003164 if (found_it)
3165 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003166 }
Jim Inghamea3ac272014-01-10 22:55:37 +00003167 else
3168 {
Greg Claytond81088c2014-01-16 01:38:29 +00003169 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00003170 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00003171 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003172 }
3173 else if (type == eSymbolTypeData)
3174 {
3175 // See if we can find a N_STSYM entry for any data symbols.
3176 // If we do find a match, and the name matches, then we
3177 // can merge the two into just the Static symbol to avoid
3178 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003179 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3180 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
3181 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003182 {
Greg Claytond81088c2014-01-16 01:38:29 +00003183 bool found_it = false;
3184 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003185 {
Greg Claytond81088c2014-01-16 01:38:29 +00003186 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3187 {
3188 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3189 // We just need the flags from the linker symbol, so put these flags
3190 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3191 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3192 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3193 sym[sym_idx].Clear();
3194 found_it = true;
3195 break;
3196 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003197 }
Greg Claytond81088c2014-01-16 01:38:29 +00003198 if (found_it)
3199 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003200 }
3201 else
3202 {
3203 // Combine N_GSYM stab entries with the non stab symbol
Greg Clayton3046e662013-07-10 01:23:25 +00003204 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 +00003205 if (pos != N_GSYM_name_to_sym_idx.end())
3206 {
3207 const uint32_t GSYM_sym_idx = pos->second;
3208 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
3209 // Copy the address, because often the N_GSYM address has an invalid address of zero
3210 // when the global is a common symbol
3211 sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
3212 sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
3213 // We just need the flags from the linker symbol, so put these flags
3214 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3215 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3216 sym[sym_idx].Clear();
3217 continue;
3218 }
3219 }
3220 }
3221 }
3222
Jason Molendaa5609c82012-06-21 01:51:02 +00003223 sym[sym_idx].SetID (nlist_idx);
3224 sym[sym_idx].SetType (type);
3225 sym[sym_idx].GetAddress().SetSection (symbol_section);
3226 sym[sym_idx].GetAddress().SetOffset (symbol_value);
3227 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003228
Jason Molendaa5609c82012-06-21 01:51:02 +00003229 if (symbol_byte_size > 0)
3230 sym[sym_idx].SetByteSize(symbol_byte_size);
3231
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003232 if (demangled_is_synthesized)
3233 sym[sym_idx].SetDemangledNameIsSynthesized(true);
Jason Molendaa5609c82012-06-21 01:51:02 +00003234 ++sym_idx;
3235 }
3236 else
3237 {
3238 sym[sym_idx].Clear();
3239 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003240
Jason Molendaa5609c82012-06-21 01:51:02 +00003241 }
3242 /////////////////////////////
3243 }
3244 break; // No more entries to consider
3245 }
3246 }
3247 }
3248 }
3249 }
3250 }
3251 }
3252
3253 // Must reset this in case it was mutated above!
3254 nlist_data_offset = 0;
3255#endif
Jim Inghamea3ac272014-01-10 22:55:37 +00003256
Greg Claytonfd814c52013-08-13 01:42:25 +00003257 if (nlist_data.GetByteSize() > 0)
Jason Molendaa5609c82012-06-21 01:51:02 +00003258 {
Jason Molendaa5609c82012-06-21 01:51:02 +00003259
Greg Claytonfd814c52013-08-13 01:42:25 +00003260 // If the sym array was not created while parsing the DSC unmapped
3261 // symbols, create it now.
3262 if (sym == NULL)
Greg Clayton4c82d422012-05-18 23:20:01 +00003263 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003264 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3265 num_syms = symtab->GetNumSymbols();
3266 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003267
Greg Claytonfd814c52013-08-13 01:42:25 +00003268 if (unmapped_local_symbols_found)
3269 {
3270 assert(m_dysymtab.ilocalsym == 0);
3271 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3272 nlist_idx = m_dysymtab.nlocalsym;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003273 }
Greg Claytondebb8812012-05-25 17:04:00 +00003274 else
3275 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003276 nlist_idx = 0;
Greg Claytondebb8812012-05-25 17:04:00 +00003277 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003278
Greg Claytonfd814c52013-08-13 01:42:25 +00003279 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003280 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003281 struct nlist_64 nlist;
3282 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
3283 break;
3284
3285 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
3286 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
3287 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
3288 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
3289 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
3290
3291 SymbolType type = eSymbolTypeInvalid;
3292 const char *symbol_name = NULL;
3293
3294 if (have_strtab_data)
Greg Clayton77ccca72011-12-30 00:32:24 +00003295 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003296 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003297
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003298 if (symbol_name == NULL)
3299 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003300 // No symbol should be NULL, even the symbols with no
3301 // string values should have an offset zero which points
3302 // to an empty C-string
3303 Host::SystemLog (Host::eSystemLogError,
3304 "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
3305 nlist_idx,
3306 nlist.n_strx,
3307 module_sp->GetFileSpec().GetPath().c_str());
3308 continue;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003309 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003310 if (symbol_name[0] == '\0')
3311 symbol_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003312 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003313 else
3314 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003315 const addr_t str_addr = strtab_addr + nlist.n_strx;
3316 Error str_error;
3317 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
3318 symbol_name = memory_symbol_name.c_str();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003319 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003320 const char *symbol_name_non_abi_mangled = NULL;
3321
3322 SectionSP symbol_section;
3323 lldb::addr_t symbol_byte_size = 0;
3324 bool add_nlist = true;
3325 bool is_gsym = false;
Charles Davis510938e2013-08-27 05:04:57 +00003326 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00003327 bool demangled_is_synthesized = false;
3328
3329 assert (sym_idx < num_syms);
3330
3331 sym[sym_idx].SetDebug (is_debug);
3332
3333 if (is_debug)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003334 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003335 switch (nlist.n_type)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003336 {
Charles Davis510938e2013-08-27 05:04:57 +00003337 case N_GSYM:
3338 // global symbol: name,,NO_SECT,type,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003339 // Sometimes the N_GSYM value contains the address.
Jason Molenda4e7511e2013-03-06 23:19:17 +00003340
Greg Claytonfd814c52013-08-13 01:42:25 +00003341 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
3342 // have the same address, but we want to ensure that we always find only the real symbol,
3343 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
3344 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
3345 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
3346 // same address.
Greg Clayton29e08cb2012-03-14 01:53:24 +00003347
Greg Claytonfd814c52013-08-13 01:42:25 +00003348 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
3349 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
3350 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
3351 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
3352 add_nlist = false;
3353 else
3354 {
3355 is_gsym = true;
3356 sym[sym_idx].SetExternal(true);
3357 if (nlist.n_value != 0)
3358 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3359 type = eSymbolTypeData;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003360 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003361 break;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003362
Charles Davis510938e2013-08-27 05:04:57 +00003363 case N_FNAME:
3364 // procedure name (f77 kludge): name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003365 type = eSymbolTypeCompiler;
3366 break;
3367
Charles Davis510938e2013-08-27 05:04:57 +00003368 case N_FUN:
3369 // procedure: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003370 if (symbol_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003371 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003372 type = eSymbolTypeCode;
3373 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3374
Greg Claytond81088c2014-01-16 01:38:29 +00003375 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003376 // We use the current number of symbols in the symbol table in lieu of
3377 // using nlist_idx in case we ever start trimming entries out
3378 N_FUN_indexes.push_back(sym_idx);
Greg Claytondacc4a92013-05-14 22:19:37 +00003379 }
3380 else
3381 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003382 type = eSymbolTypeCompiler;
3383
3384 if ( !N_FUN_indexes.empty() )
Greg Claytondacc4a92013-05-14 22:19:37 +00003385 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003386 // Copy the size of the function into the original STAB entry so we don't have
3387 // to hunt for it later
3388 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
3389 N_FUN_indexes.pop_back();
3390 // We don't really need the end function STAB as it contains the size which
3391 // we already placed with the original symbol, so don't add it if we want a
3392 // minimal symbol table
3393 add_nlist = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00003394 }
3395 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003396 break;
3397
Charles Davis510938e2013-08-27 05:04:57 +00003398 case N_STSYM:
3399 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00003400 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003401 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3402 type = eSymbolTypeData;
3403 break;
3404
Charles Davis510938e2013-08-27 05:04:57 +00003405 case N_LCSYM:
3406 // .lcomm symbol: name,,n_sect,type,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003407 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3408 type = eSymbolTypeCommonBlock;
3409 break;
3410
Charles Davis510938e2013-08-27 05:04:57 +00003411 case N_BNSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003412 // We use the current number of symbols in the symbol table in lieu of
3413 // using nlist_idx in case we ever start trimming entries out
3414 // Skip these if we want minimal symbol tables
3415 add_nlist = false;
3416 break;
3417
Charles Davis510938e2013-08-27 05:04:57 +00003418 case N_ENSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003419 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
3420 // so that we can always skip the entire symbol if we need to navigate
3421 // more quickly at the source level when parsing STABS
3422 // Skip these if we want minimal symbol tables
3423 add_nlist = false;
3424 break;
3425
3426
Charles Davis510938e2013-08-27 05:04:57 +00003427 case N_OPT:
3428 // emitted with gcc2_compiled and in gcc source
Greg Claytonfd814c52013-08-13 01:42:25 +00003429 type = eSymbolTypeCompiler;
3430 break;
3431
Charles Davis510938e2013-08-27 05:04:57 +00003432 case N_RSYM:
3433 // register sym: name,,NO_SECT,type,register
Greg Claytonfd814c52013-08-13 01:42:25 +00003434 type = eSymbolTypeVariable;
3435 break;
3436
Charles Davis510938e2013-08-27 05:04:57 +00003437 case N_SLINE:
3438 // src line: 0,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003439 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3440 type = eSymbolTypeLineEntry;
3441 break;
3442
Charles Davis510938e2013-08-27 05:04:57 +00003443 case N_SSYM:
3444 // structure elt: name,,NO_SECT,type,struct_offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003445 type = eSymbolTypeVariableType;
3446 break;
3447
Charles Davis510938e2013-08-27 05:04:57 +00003448 case N_SO:
3449 // source file name
Greg Claytonfd814c52013-08-13 01:42:25 +00003450 type = eSymbolTypeSourceFile;
3451 if (symbol_name == NULL)
3452 {
3453 add_nlist = false;
3454 if (N_SO_index != UINT32_MAX)
3455 {
3456 // Set the size of the N_SO to the terminating index of this N_SO
3457 // so that we can always skip the entire N_SO if we need to navigate
3458 // more quickly at the source level when parsing STABS
3459 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
3460 symbol_ptr->SetByteSize(sym_idx);
3461 symbol_ptr->SetSizeIsSibling(true);
3462 }
3463 N_NSYM_indexes.clear();
3464 N_INCL_indexes.clear();
3465 N_BRAC_indexes.clear();
3466 N_COMM_indexes.clear();
3467 N_FUN_indexes.clear();
3468 N_SO_index = UINT32_MAX;
3469 }
3470 else
3471 {
3472 // We use the current number of symbols in the symbol table in lieu of
3473 // using nlist_idx in case we ever start trimming entries out
3474 const bool N_SO_has_full_path = symbol_name[0] == '/';
3475 if (N_SO_has_full_path)
3476 {
3477 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3478 {
3479 // We have two consecutive N_SO entries where the first contains a directory
3480 // and the second contains a full path.
3481 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
3482 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3483 add_nlist = false;
3484 }
3485 else
3486 {
3487 // This is the first entry in a N_SO that contains a directory or
3488 // a full path to the source file
3489 N_SO_index = sym_idx;
3490 }
3491 }
3492 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3493 {
3494 // This is usually the second N_SO entry that contains just the filename,
3495 // so here we combine it with the first one if we are minimizing the symbol table
3496 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
3497 if (so_path && so_path[0])
3498 {
3499 std::string full_so_path (so_path);
3500 const size_t double_slash_pos = full_so_path.find("//");
3501 if (double_slash_pos != std::string::npos)
3502 {
3503 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003504 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Claytonfd814c52013-08-13 01:42:25 +00003505 // and the second is the directory for the source file so you end up with
3506 // a path that looks like "/tmp/src//tmp/src/"
3507 FileSpec so_dir(so_path, false);
3508 if (!so_dir.Exists())
3509 {
3510 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3511 if (so_dir.Exists())
3512 {
3513 // Trim off the incorrect path
3514 full_so_path.erase(0, double_slash_pos + 1);
3515 }
3516 }
3517 }
3518 if (*full_so_path.rbegin() != '/')
3519 full_so_path += '/';
3520 full_so_path += symbol_name;
3521 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
3522 add_nlist = false;
3523 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3524 }
3525 }
3526 else
3527 {
3528 // This could be a relative path to a N_SO
3529 N_SO_index = sym_idx;
3530 }
3531 }
3532
3533 break;
3534
Charles Davis510938e2013-08-27 05:04:57 +00003535 case N_OSO:
3536 // object file name: name,,0,0,st_mtime
Greg Claytonfd814c52013-08-13 01:42:25 +00003537 type = eSymbolTypeObjectFile;
3538 break;
3539
Charles Davis510938e2013-08-27 05:04:57 +00003540 case N_LSYM:
3541 // local sym: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003542 type = eSymbolTypeLocal;
3543 break;
3544
3545 //----------------------------------------------------------------------
3546 // INCL scopes
3547 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003548 case N_BINCL:
3549 // include file beginning: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00003550 // We use the current number of symbols in the symbol table in lieu of
3551 // using nlist_idx in case we ever start trimming entries out
3552 N_INCL_indexes.push_back(sym_idx);
3553 type = eSymbolTypeScopeBegin;
3554 break;
3555
Charles Davis510938e2013-08-27 05:04:57 +00003556 case N_EINCL:
3557 // include file end: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003558 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3559 // so that we can always skip the entire symbol if we need to navigate
3560 // more quickly at the source level when parsing STABS
3561 if ( !N_INCL_indexes.empty() )
3562 {
3563 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3564 symbol_ptr->SetByteSize(sym_idx + 1);
3565 symbol_ptr->SetSizeIsSibling(true);
3566 N_INCL_indexes.pop_back();
3567 }
3568 type = eSymbolTypeScopeEnd;
3569 break;
3570
Charles Davis510938e2013-08-27 05:04:57 +00003571 case N_SOL:
3572 // #included file name: name,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003573 type = eSymbolTypeHeaderFile;
3574
3575 // We currently don't use the header files on darwin
3576 add_nlist = false;
3577 break;
3578
Charles Davis510938e2013-08-27 05:04:57 +00003579 case N_PARAMS:
3580 // compiler parameters: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003581 type = eSymbolTypeCompiler;
3582 break;
3583
Charles Davis510938e2013-08-27 05:04:57 +00003584 case N_VERSION:
3585 // compiler version: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003586 type = eSymbolTypeCompiler;
3587 break;
3588
Charles Davis510938e2013-08-27 05:04:57 +00003589 case N_OLEVEL:
3590 // compiler -O level: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003591 type = eSymbolTypeCompiler;
3592 break;
3593
Charles Davis510938e2013-08-27 05:04:57 +00003594 case N_PSYM:
3595 // parameter: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003596 type = eSymbolTypeVariable;
3597 break;
3598
Charles Davis510938e2013-08-27 05:04:57 +00003599 case N_ENTRY:
3600 // alternate entry: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003601 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3602 type = eSymbolTypeLineEntry;
3603 break;
3604
3605 //----------------------------------------------------------------------
3606 // Left and Right Braces
3607 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003608 case N_LBRAC:
3609 // left bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003610 // We use the current number of symbols in the symbol table in lieu of
3611 // using nlist_idx in case we ever start trimming entries out
3612 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3613 N_BRAC_indexes.push_back(sym_idx);
3614 type = eSymbolTypeScopeBegin;
3615 break;
3616
Charles Davis510938e2013-08-27 05:04:57 +00003617 case N_RBRAC:
3618 // right bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003619 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
3620 // so that we can always skip the entire symbol if we need to navigate
3621 // more quickly at the source level when parsing STABS
3622 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3623 if ( !N_BRAC_indexes.empty() )
3624 {
3625 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
3626 symbol_ptr->SetByteSize(sym_idx + 1);
3627 symbol_ptr->SetSizeIsSibling(true);
3628 N_BRAC_indexes.pop_back();
3629 }
3630 type = eSymbolTypeScopeEnd;
3631 break;
3632
Charles Davis510938e2013-08-27 05:04:57 +00003633 case N_EXCL:
3634 // deleted include file: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00003635 type = eSymbolTypeHeaderFile;
3636 break;
3637
3638 //----------------------------------------------------------------------
3639 // COMM scopes
3640 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003641 case N_BCOMM:
3642 // begin common: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003643 // We use the current number of symbols in the symbol table in lieu of
3644 // using nlist_idx in case we ever start trimming entries out
3645 type = eSymbolTypeScopeBegin;
3646 N_COMM_indexes.push_back(sym_idx);
3647 break;
3648
Charles Davis510938e2013-08-27 05:04:57 +00003649 case N_ECOML:
3650 // end common (local name): 0,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003651 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3652 // Fall through
3653
Charles Davis510938e2013-08-27 05:04:57 +00003654 case N_ECOMM:
3655 // end common: name,,n_sect,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003656 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
3657 // so that we can always skip the entire symbol if we need to navigate
3658 // more quickly at the source level when parsing STABS
3659 if ( !N_COMM_indexes.empty() )
3660 {
3661 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
3662 symbol_ptr->SetByteSize(sym_idx + 1);
3663 symbol_ptr->SetSizeIsSibling(true);
3664 N_COMM_indexes.pop_back();
3665 }
3666 type = eSymbolTypeScopeEnd;
3667 break;
3668
Charles Davis510938e2013-08-27 05:04:57 +00003669 case N_LENG:
3670 // second stab entry with length information
Greg Claytonfd814c52013-08-13 01:42:25 +00003671 type = eSymbolTypeAdditional;
3672 break;
3673
3674 default: break;
3675 }
3676 }
3677 else
3678 {
Charles Davis510938e2013-08-27 05:04:57 +00003679 //uint8_t n_pext = N_PEXT & nlist.n_type;
3680 uint8_t n_type = N_TYPE & nlist.n_type;
3681 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00003682
3683 switch (n_type)
3684 {
Charles Davis510938e2013-08-27 05:04:57 +00003685 case N_INDR:// Fall through
3686 case N_PBUD:// Fall through
3687 case N_UNDF:
Greg Claytonfd814c52013-08-13 01:42:25 +00003688 type = eSymbolTypeUndefined;
3689 break;
3690
Charles Davis510938e2013-08-27 05:04:57 +00003691 case N_ABS:
Greg Claytonfd814c52013-08-13 01:42:25 +00003692 type = eSymbolTypeAbsolute;
3693 break;
3694
Charles Davis510938e2013-08-27 05:04:57 +00003695 case N_SECT:
Greg Claytonfd814c52013-08-13 01:42:25 +00003696 {
3697 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3698
3699 if (!symbol_section)
3700 {
3701 // TODO: warn about this?
3702 add_nlist = false;
3703 break;
3704 }
3705
3706 if (TEXT_eh_frame_sectID == nlist.n_sect)
3707 {
3708 type = eSymbolTypeException;
3709 }
3710 else
3711 {
Charles Davis510938e2013-08-27 05:04:57 +00003712 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Greg Claytonfd814c52013-08-13 01:42:25 +00003713
3714 switch (section_type)
3715 {
Charles Davis510938e2013-08-27 05:04:57 +00003716 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
3717 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
3718 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
3719 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
3720 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
3721 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
3722 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
3723 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
3724 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00003725 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
3726 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
3727 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
3728 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00003729 default:
3730 switch (symbol_section->GetType())
3731 {
3732 case lldb::eSectionTypeCode:
3733 type = eSymbolTypeCode;
3734 break;
3735 case eSectionTypeData:
3736 case eSectionTypeDataCString: // Inlined C string data
3737 case eSectionTypeDataCStringPointers: // Pointers to C string data
3738 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
3739 case eSectionTypeData4:
3740 case eSectionTypeData8:
3741 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00003742 type = eSymbolTypeData;
3743 break;
3744 default:
3745 break;
3746 }
3747 break;
Greg Claytonfd814c52013-08-13 01:42:25 +00003748 }
3749
3750 if (type == eSymbolTypeInvalid)
3751 {
3752 const char *symbol_sect_name = symbol_section->GetName().AsCString();
3753 if (symbol_section->IsDescendant (text_section_sp.get()))
3754 {
Charles Davis510938e2013-08-27 05:04:57 +00003755 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3756 S_ATTR_SELF_MODIFYING_CODE |
3757 S_ATTR_SOME_INSTRUCTIONS))
Greg Claytonfd814c52013-08-13 01:42:25 +00003758 type = eSymbolTypeData;
3759 else
3760 type = eSymbolTypeCode;
3761 }
3762 else
3763 if (symbol_section->IsDescendant(data_section_sp.get()))
3764 {
3765 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
3766 {
3767 type = eSymbolTypeRuntime;
3768
3769 if (symbol_name &&
3770 symbol_name[0] == '_' &&
3771 symbol_name[1] == 'O' &&
3772 symbol_name[2] == 'B')
3773 {
3774 llvm::StringRef symbol_name_ref(symbol_name);
3775 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
3776 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
3777 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
3778 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3779 {
3780 symbol_name_non_abi_mangled = symbol_name + 1;
3781 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3782 type = eSymbolTypeObjCClass;
3783 demangled_is_synthesized = true;
3784 }
3785 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3786 {
3787 symbol_name_non_abi_mangled = symbol_name + 1;
3788 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3789 type = eSymbolTypeObjCMetaClass;
3790 demangled_is_synthesized = true;
3791 }
3792 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3793 {
3794 symbol_name_non_abi_mangled = symbol_name + 1;
3795 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3796 type = eSymbolTypeObjCIVar;
3797 demangled_is_synthesized = true;
3798 }
3799 }
3800 }
3801 else
3802 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
3803 {
3804 type = eSymbolTypeException;
3805 }
3806 else
3807 {
3808 type = eSymbolTypeData;
3809 }
3810 }
3811 else
3812 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
3813 {
3814 type = eSymbolTypeTrampoline;
3815 }
3816 else
3817 if (symbol_section->IsDescendant(objc_section_sp.get()))
3818 {
3819 type = eSymbolTypeRuntime;
3820 if (symbol_name && symbol_name[0] == '.')
3821 {
3822 llvm::StringRef symbol_name_ref(symbol_name);
3823 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
3824 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
3825 {
3826 symbol_name_non_abi_mangled = symbol_name;
3827 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
3828 type = eSymbolTypeObjCClass;
3829 demangled_is_synthesized = true;
3830 }
3831 }
3832 }
3833 }
3834 }
3835 }
3836 break;
Greg Claytondacc4a92013-05-14 22:19:37 +00003837 }
3838 }
3839
Greg Claytonfd814c52013-08-13 01:42:25 +00003840 if (add_nlist)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003841 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003842 uint64_t symbol_value = nlist.n_value;
3843
3844 if (symbol_name_non_abi_mangled)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003845 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003846 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
3847 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
3848 }
3849 else
3850 {
3851 bool symbol_name_is_mangled = false;
3852
3853 if (symbol_name && symbol_name[0] == '_')
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003854 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003855 symbol_name_is_mangled = symbol_name[1] == '_';
3856 symbol_name++; // Skip the leading underscore
3857 }
3858
3859 if (symbol_name)
3860 {
3861 ConstString const_symbol_name(symbol_name);
3862 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
3863 if (is_gsym && is_debug)
3864 {
3865 N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
3866 }
3867 }
3868 }
3869 if (symbol_section)
3870 {
3871 const addr_t section_file_addr = symbol_section->GetFileAddress();
3872 if (symbol_byte_size == 0 && function_starts_count > 0)
3873 {
3874 addr_t symbol_lookup_file_addr = nlist.n_value;
3875 // Do an exact address match for non-ARM addresses, else get the closest since
3876 // the symbol might be a thumb symbol which has an address with bit zero set
3877 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
3878 if (is_arm && func_start_entry)
3879 {
3880 // Verify that the function start address is the symbol address (ARM)
3881 // or the symbol address + 1 (thumb)
3882 if (func_start_entry->addr != symbol_lookup_file_addr &&
3883 func_start_entry->addr != (symbol_lookup_file_addr + 1))
3884 {
3885 // Not the right entry, NULL it out...
3886 func_start_entry = NULL;
3887 }
3888 }
3889 if (func_start_entry)
3890 {
3891 func_start_entry->data = true;
3892
3893 addr_t symbol_file_addr = func_start_entry->addr;
3894 if (is_arm)
3895 symbol_file_addr &= 0xfffffffffffffffeull;
3896
3897 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3898 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3899 if (next_func_start_entry)
3900 {
3901 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3902 // Be sure the clear the Thumb address bit when we calculate the size
3903 // from the current and next address
3904 if (is_arm)
3905 next_symbol_file_addr &= 0xfffffffffffffffeull;
3906 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
3907 }
3908 else
3909 {
3910 symbol_byte_size = section_end_file_addr - symbol_file_addr;
3911 }
3912 }
3913 }
3914 symbol_value -= section_file_addr;
3915 }
3916
3917 if (is_debug == false)
3918 {
3919 if (type == eSymbolTypeCode)
3920 {
3921 // See if we can find a N_FUN entry for any code symbols.
3922 // If we do find a match, and the name matches, then we
3923 // can merge the two into just the function symbol to avoid
3924 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003925 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3926 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3927 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00003928 {
Greg Claytond81088c2014-01-16 01:38:29 +00003929 bool found_it = false;
3930 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00003931 {
Greg Claytond81088c2014-01-16 01:38:29 +00003932 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3933 {
3934 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3935 // We just need the flags from the linker symbol, so put these flags
3936 // into the N_FUN flags to avoid duplicate symbols in the symbol table
3937 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3938 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3939 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
3940 sym[pos->second].SetType (eSymbolTypeResolver);
3941 sym[sym_idx].Clear();
3942 found_it = true;
3943 break;
3944 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003945 }
Greg Claytond81088c2014-01-16 01:38:29 +00003946 if (found_it)
3947 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00003948 }
Jim Inghamea3ac272014-01-10 22:55:37 +00003949 else
3950 {
3951 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00003952 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00003953 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003954 }
3955 else if (type == eSymbolTypeData)
3956 {
3957 // See if we can find a N_STSYM entry for any data symbols.
3958 // If we do find a match, and the name matches, then we
3959 // can merge the two into just the Static symbol to avoid
3960 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003961 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3962 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
3963 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00003964 {
Greg Claytond81088c2014-01-16 01:38:29 +00003965 bool found_it = false;
3966 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00003967 {
Greg Claytond81088c2014-01-16 01:38:29 +00003968 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3969 {
3970 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3971 // We just need the flags from the linker symbol, so put these flags
3972 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3973 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3974 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3975 sym[sym_idx].Clear();
3976 found_it = true;
3977 break;
3978 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003979 }
Greg Claytond81088c2014-01-16 01:38:29 +00003980 if (found_it)
3981 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00003982 }
3983 else
3984 {
3985 // Combine N_GSYM stab entries with the non stab symbol
3986 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
3987 if (pos != N_GSYM_name_to_sym_idx.end())
3988 {
3989 const uint32_t GSYM_sym_idx = pos->second;
3990 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
3991 // Copy the address, because often the N_GSYM address has an invalid address of zero
3992 // when the global is a common symbol
3993 sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
3994 sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
3995 // We just need the flags from the linker symbol, so put these flags
3996 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3997 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3998 sym[sym_idx].Clear();
3999 continue;
4000 }
4001 }
4002 }
4003 }
4004
4005 sym[sym_idx].SetID (nlist_idx);
4006 sym[sym_idx].SetType (type);
4007 sym[sym_idx].GetAddress().SetSection (symbol_section);
4008 sym[sym_idx].GetAddress().SetOffset (symbol_value);
4009 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4010
4011 if (symbol_byte_size > 0)
4012 sym[sym_idx].SetByteSize(symbol_byte_size);
4013
4014 if (demangled_is_synthesized)
4015 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4016
4017 ++sym_idx;
4018 }
4019 else
4020 {
4021 sym[sym_idx].Clear();
4022 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004023 }
4024 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004025
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004026 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4027
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004028 if (function_starts_count > 0)
4029 {
4030 char synthetic_function_symbol[PATH_MAX];
4031 uint32_t num_synthetic_function_symbols = 0;
4032 for (i=0; i<function_starts_count; ++i)
4033 {
4034 if (function_starts.GetEntryRef (i).data == false)
4035 ++num_synthetic_function_symbols;
4036 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004037
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004038 if (num_synthetic_function_symbols > 0)
4039 {
4040 if (num_syms < sym_idx + num_synthetic_function_symbols)
4041 {
4042 num_syms = sym_idx + num_synthetic_function_symbols;
4043 sym = symtab->Resize (num_syms);
4044 }
4045 uint32_t synthetic_function_symbol_idx = 0;
4046 for (i=0; i<function_starts_count; ++i)
4047 {
4048 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
4049 if (func_start_entry->data == false)
4050 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004051 addr_t symbol_file_addr = func_start_entry->addr;
4052 uint32_t symbol_flags = 0;
4053 if (is_arm)
4054 {
4055 if (symbol_file_addr & 1)
4056 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
4057 symbol_file_addr &= 0xfffffffffffffffeull;
4058 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004059 Address symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004060 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004061 {
4062 SectionSP symbol_section (symbol_addr.GetSection());
4063 uint32_t symbol_byte_size = 0;
4064 if (symbol_section)
4065 {
4066 const addr_t section_file_addr = symbol_section->GetFileAddress();
4067 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4068 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4069 if (next_func_start_entry)
4070 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004071 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4072 if (is_arm)
4073 next_symbol_file_addr &= 0xfffffffffffffffeull;
4074 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 +00004075 }
4076 else
4077 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004078 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004079 }
4080 snprintf (synthetic_function_symbol,
4081 sizeof(synthetic_function_symbol),
4082 "___lldb_unnamed_function%u$$%s",
4083 ++synthetic_function_symbol_idx,
4084 module_sp->GetFileSpec().GetFilename().GetCString());
4085 sym[sym_idx].SetID (synthetic_sym_id++);
Greg Clayton037520e2012-07-18 23:18:10 +00004086 sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004087 sym[sym_idx].SetType (eSymbolTypeCode);
4088 sym[sym_idx].SetIsSynthetic (true);
4089 sym[sym_idx].GetAddress() = symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004090 if (symbol_flags)
4091 sym[sym_idx].SetFlags (symbol_flags);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004092 if (symbol_byte_size)
4093 sym[sym_idx].SetByteSize (symbol_byte_size);
4094 ++sym_idx;
4095 }
4096 }
4097 }
4098 }
4099 }
4100 }
4101
4102 // Trim our symbols down to just what we ended up with after
4103 // removing any symbols.
4104 if (sym_idx < num_syms)
4105 {
4106 num_syms = sym_idx;
4107 sym = symtab->Resize (num_syms);
4108 }
4109
4110 // Now synthesize indirect symbols
4111 if (m_dysymtab.nindirectsyms != 0)
4112 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004113 if (indirect_symbol_index_data.GetByteSize())
4114 {
4115 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
4116
4117 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
4118 {
Charles Davis510938e2013-08-27 05:04:57 +00004119 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004120 {
4121 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4122 if (symbol_stub_byte_size == 0)
4123 continue;
4124
4125 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4126
4127 if (num_symbol_stubs == 0)
4128 continue;
4129
4130 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
4131 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
4132 {
4133 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
4134 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 +00004135 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004136 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
4137 {
4138 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
Charles Davis510938e2013-08-27 05:04:57 +00004139 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004140 continue;
4141
4142 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
4143 Symbol *stub_symbol = NULL;
4144 if (index_pos != end_index_pos)
4145 {
4146 // We have a remapping from the original nlist index to
4147 // a current symbol index, so just look this up by index
4148 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
4149 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004150 else
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004151 {
4152 // We need to lookup a symbol using the original nlist
Jason Molenda4e7511e2013-03-06 23:19:17 +00004153 // symbol index since this index is coming from the
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004154 // S_SYMBOL_STUBS
4155 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
4156 }
4157
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004158 if (stub_symbol)
4159 {
4160 Address so_addr(symbol_stub_addr, section_list);
4161
4162 if (stub_symbol->GetType() == eSymbolTypeUndefined)
4163 {
4164 // Change the external symbol into a trampoline that makes sense
4165 // These symbols were N_UNDF N_EXT, and are useless to us, so we
4166 // can re-use them so we don't have to make up a synthetic symbol
4167 // for no good reason.
Greg Clayton9191db42013-10-21 18:40:51 +00004168 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4169 stub_symbol->SetType (eSymbolTypeTrampoline);
4170 else
4171 stub_symbol->SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004172 stub_symbol->SetExternal (false);
4173 stub_symbol->GetAddress() = so_addr;
4174 stub_symbol->SetByteSize (symbol_stub_byte_size);
4175 }
4176 else
4177 {
4178 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda0a287e02012-04-24 02:09:58 +00004179 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004180 if (sym_idx >= num_syms)
Jason Molenda0a287e02012-04-24 02:09:58 +00004181 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004182 sym = symtab->Resize (++num_syms);
Jason Molenda0a287e02012-04-24 02:09:58 +00004183 stub_symbol = NULL; // this pointer no longer valid
4184 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004185 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda0a287e02012-04-24 02:09:58 +00004186 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton9191db42013-10-21 18:40:51 +00004187 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4188 sym[sym_idx].SetType (eSymbolTypeTrampoline);
4189 else
4190 sym[sym_idx].SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004191 sym[sym_idx].SetIsSynthetic (true);
4192 sym[sym_idx].GetAddress() = so_addr;
4193 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
4194 ++sym_idx;
4195 }
4196 }
Greg Clayton3f839a32012-09-05 01:38:55 +00004197 else
4198 {
4199 if (log)
4200 log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
4201 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004202 }
4203 }
4204 }
4205 }
4206 }
4207 }
Greg Clayton9191db42013-10-21 18:40:51 +00004208
4209
4210 if (!trie_entries.empty())
4211 {
4212 for (const auto &e : trie_entries)
4213 {
4214 if (e.entry.import_name)
4215 {
4216 // Make a synthetic symbol to describe re-exported symbol.
4217 if (sym_idx >= num_syms)
4218 sym = symtab->Resize (++num_syms);
4219 sym[sym_idx].SetID (synthetic_sym_id++);
4220 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4221 sym[sym_idx].SetType (eSymbolTypeReExported);
4222 sym[sym_idx].SetIsSynthetic (true);
4223 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4224 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
4225 {
4226 sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
4227 }
4228 ++sym_idx;
4229 }
4230 }
4231 }
4232
4233
Greg Clayton3046e662013-07-10 01:23:25 +00004234
4235// StreamFile s(stdout, false);
4236// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
4237// symtab->Dump(&s, NULL, eSortOrderNone);
4238 // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
4239 symtab->CalculateSymbolSizes();
4240
4241// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
4242// symtab->Dump(&s, NULL, eSortOrderNone);
4243
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004244 return symtab->GetNumSymbols();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004245 }
4246 return 0;
4247}
4248
4249
4250void
4251ObjectFileMachO::Dump (Stream *s)
4252{
Greg Claytona1743492012-03-13 23:14:29 +00004253 ModuleSP module_sp(GetModule());
4254 if (module_sp)
4255 {
4256 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004257 s->Printf("%p: ", static_cast<void*>(this));
Greg Claytona1743492012-03-13 23:14:29 +00004258 s->Indent();
Charles Davis510938e2013-08-27 05:04:57 +00004259 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
Greg Claytona1743492012-03-13 23:14:29 +00004260 s->PutCString("ObjectFileMachO64");
4261 else
4262 s->PutCString("ObjectFileMachO32");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004263
Greg Clayton7ab7f892014-05-29 21:33:45 +00004264 ArchSpec header_arch;
4265 GetArchitecture(header_arch);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004266
Greg Claytona1743492012-03-13 23:14:29 +00004267 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004268
Greg Clayton3046e662013-07-10 01:23:25 +00004269 SectionList *sections = GetSectionList();
4270 if (sections)
4271 sections->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004272
Greg Claytona1743492012-03-13 23:14:29 +00004273 if (m_symtab_ap.get())
4274 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
4275 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004276}
4277
Greg Claytonf4d6de62013-04-24 22:29:28 +00004278bool
4279ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header,
4280 const lldb_private::DataExtractor &data,
4281 lldb::offset_t lc_offset,
4282 lldb_private::UUID& uuid)
4283{
4284 uint32_t i;
4285 struct uuid_command load_cmd;
4286
4287 lldb::offset_t offset = lc_offset;
4288 for (i=0; i<header.ncmds; ++i)
4289 {
4290 const lldb::offset_t cmd_offset = offset;
4291 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4292 break;
4293
Charles Davis510938e2013-08-27 05:04:57 +00004294 if (load_cmd.cmd == LC_UUID)
Greg Claytonf4d6de62013-04-24 22:29:28 +00004295 {
4296 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4297
4298 if (uuid_bytes)
4299 {
4300 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4301 // We pretend these object files have no UUID to prevent crashing.
4302
4303 const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
4304 0x3b, 0xa8,
4305 0x4b, 0x16,
4306 0xb6, 0xa4,
4307 0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
4308
4309 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4310 return false;
4311
4312 uuid.SetBytes (uuid_bytes);
4313 return true;
4314 }
4315 return false;
4316 }
4317 offset = cmd_offset + load_cmd.cmdsize;
4318 }
4319 return false;
4320}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004321
Greg Clayton7ab7f892014-05-29 21:33:45 +00004322
4323bool
4324ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header,
4325 const lldb_private::DataExtractor &data,
4326 lldb::offset_t lc_offset,
4327 ArchSpec &arch)
4328{
4329 arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype);
4330
4331 if (arch.IsValid())
4332 {
4333 llvm::Triple &triple = arch.GetTriple();
4334 if (header.filetype == MH_PRELOAD)
4335 {
4336 // Set OS to "unknown" - this is a standalone binary with no dyld et al
4337 triple.setOS(llvm::Triple::UnknownOS);
4338 return true;
4339 }
4340 else
4341 {
4342 struct load_command load_cmd;
4343
4344 lldb::offset_t offset = lc_offset;
4345 for (uint32_t i=0; i<header.ncmds; ++i)
4346 {
4347 const lldb::offset_t cmd_offset = offset;
4348 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4349 break;
4350
4351 switch (load_cmd.cmd)
4352 {
4353 case LC_VERSION_MIN_IPHONEOS:
4354 triple.setOS (llvm::Triple::IOS);
4355 return true;
4356
4357 case LC_VERSION_MIN_MACOSX:
4358 triple.setOS (llvm::Triple::MacOSX);
4359 return true;
4360
4361 default:
4362 break;
4363 }
4364
4365 offset = cmd_offset + load_cmd.cmdsize;
4366 }
4367
4368 if (header.cputype == CPU_TYPE_ARM || header.cputype == CPU_TYPE_ARM64)
4369 triple.setOS (llvm::Triple::IOS);
4370 else
4371 triple.setOS (llvm::Triple::MacOSX);
4372 }
4373 }
4374 return arch.IsValid();
4375}
4376
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004377bool
Greg Clayton60830262011-02-04 18:53:10 +00004378ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004379{
Greg Claytona1743492012-03-13 23:14:29 +00004380 ModuleSP module_sp(GetModule());
4381 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004382 {
Greg Claytona1743492012-03-13 23:14:29 +00004383 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Claytonc7bece562013-01-25 18:06:21 +00004384 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +00004385 return GetUUID (m_header, m_data, offset, *uuid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004386 }
4387 return false;
4388}
4389
4390
4391uint32_t
4392ObjectFileMachO::GetDependentModules (FileSpecList& files)
4393{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004394 uint32_t count = 0;
Greg Claytona1743492012-03-13 23:14:29 +00004395 ModuleSP module_sp(GetModule());
4396 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004397 {
Greg Claytona1743492012-03-13 23:14:29 +00004398 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4399 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004400 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004401 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 +00004402 uint32_t i;
4403 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004404 {
Greg Claytona1743492012-03-13 23:14:29 +00004405 const uint32_t cmd_offset = offset;
4406 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4407 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004408
Greg Claytona1743492012-03-13 23:14:29 +00004409 switch (load_cmd.cmd)
4410 {
Charles Davis510938e2013-08-27 05:04:57 +00004411 case LC_LOAD_DYLIB:
4412 case LC_LOAD_WEAK_DYLIB:
4413 case LC_REEXPORT_DYLIB:
4414 case LC_LOAD_DYLINKER:
4415 case LC_LOADFVMLIB:
4416 case LC_LOAD_UPWARD_DYLIB:
Greg Claytona1743492012-03-13 23:14:29 +00004417 {
4418 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
4419 const char *path = m_data.PeekCStr(name_offset);
4420 // Skip any path that starts with '@' since these are usually:
4421 // @executable_path/.../file
4422 // @rpath/.../file
4423 if (path && path[0] != '@')
4424 {
4425 FileSpec file_spec(path, resolve_path);
4426 if (files.AppendIfUnique(file_spec))
4427 count++;
4428 }
4429 }
4430 break;
4431
4432 default:
4433 break;
4434 }
4435 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004436 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004437 }
4438 return count;
4439}
4440
Jim Ingham672e6f52011-03-07 23:44:08 +00004441lldb_private::Address
Jason Molenda4e7511e2013-03-06 23:19:17 +00004442ObjectFileMachO::GetEntryPointAddress ()
Jim Ingham672e6f52011-03-07 23:44:08 +00004443{
4444 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
4445 // is initialized to an invalid address, so we can just return that.
4446 // 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 +00004447
Jim Ingham672e6f52011-03-07 23:44:08 +00004448 if (!IsExecutable() || m_entry_point_address.IsValid())
4449 return m_entry_point_address;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004450
4451 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
Jim Ingham672e6f52011-03-07 23:44:08 +00004452 // /usr/include/mach-o.h, but it is basically:
4453 //
4454 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
4455 // uint32_t count - this is the count of longs in the thread state data
4456 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
4457 // <repeat this trio>
Jason Molenda4e7511e2013-03-06 23:19:17 +00004458 //
Jim Ingham672e6f52011-03-07 23:44:08 +00004459 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
4460 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
4461 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
4462 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
4463 //
4464 // For now we hard-code the offsets and flavors we need:
4465 //
4466 //
4467
Greg Claytona1743492012-03-13 23:14:29 +00004468 ModuleSP module_sp(GetModule());
4469 if (module_sp)
Jim Ingham672e6f52011-03-07 23:44:08 +00004470 {
Greg Claytona1743492012-03-13 23:14:29 +00004471 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4472 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004473 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00004474 uint32_t i;
4475 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
4476 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004477
Greg Claytona1743492012-03-13 23:14:29 +00004478 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham672e6f52011-03-07 23:44:08 +00004479 {
Greg Claytonc7bece562013-01-25 18:06:21 +00004480 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00004481 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4482 break;
4483
4484 switch (load_cmd.cmd)
Jim Ingham672e6f52011-03-07 23:44:08 +00004485 {
Charles Davis510938e2013-08-27 05:04:57 +00004486 case LC_UNIXTHREAD:
4487 case LC_THREAD:
Jim Ingham672e6f52011-03-07 23:44:08 +00004488 {
Greg Claytona1743492012-03-13 23:14:29 +00004489 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham672e6f52011-03-07 23:44:08 +00004490 {
Greg Claytona1743492012-03-13 23:14:29 +00004491 uint32_t flavor = m_data.GetU32(&offset);
4492 uint32_t count = m_data.GetU32(&offset);
4493 if (count == 0)
4494 {
4495 // We've gotten off somehow, log and exit;
4496 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00004497 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004498
Greg Claytona1743492012-03-13 23:14:29 +00004499 switch (m_header.cputype)
4500 {
Charles Davis510938e2013-08-27 05:04:57 +00004501 case llvm::MachO::CPU_TYPE_ARM:
Greg Claytona1743492012-03-13 23:14:29 +00004502 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
4503 {
4504 offset += 60; // This is the offset of pc in the GPR thread state data structure.
4505 start_address = m_data.GetU32(&offset);
4506 done = true;
4507 }
Jim Ingham672e6f52011-03-07 23:44:08 +00004508 break;
Jason Molendaa3329782014-03-29 18:54:20 +00004509 case llvm::MachO::CPU_TYPE_ARM64:
4510 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
4511 {
4512 offset += 256; // This is the offset of pc in the GPR thread state data structure.
4513 start_address = m_data.GetU64(&offset);
4514 done = true;
4515 }
4516 break;
Charles Davis510938e2013-08-27 05:04:57 +00004517 case llvm::MachO::CPU_TYPE_I386:
Greg Claytona1743492012-03-13 23:14:29 +00004518 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
4519 {
4520 offset += 40; // This is the offset of eip in the GPR thread state data structure.
4521 start_address = m_data.GetU32(&offset);
4522 done = true;
4523 }
4524 break;
Charles Davis510938e2013-08-27 05:04:57 +00004525 case llvm::MachO::CPU_TYPE_X86_64:
Greg Claytona1743492012-03-13 23:14:29 +00004526 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
4527 {
4528 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
4529 start_address = m_data.GetU64(&offset);
4530 done = true;
4531 }
4532 break;
4533 default:
4534 return m_entry_point_address;
4535 }
4536 // Haven't found the GPR flavor yet, skip over the data for this flavor:
4537 if (done)
4538 break;
4539 offset += count * 4;
4540 }
Jim Ingham672e6f52011-03-07 23:44:08 +00004541 }
Greg Claytona1743492012-03-13 23:14:29 +00004542 break;
Charles Davis510938e2013-08-27 05:04:57 +00004543 case LC_MAIN:
Sean Callanan226b70c2012-03-08 02:39:03 +00004544 {
Greg Claytona1743492012-03-13 23:14:29 +00004545 ConstString text_segment_name ("__TEXT");
4546 uint64_t entryoffset = m_data.GetU64(&offset);
4547 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
4548 if (text_segment_sp)
4549 {
4550 done = true;
4551 start_address = text_segment_sp->GetFileAddress() + entryoffset;
4552 }
Sean Callanan226b70c2012-03-08 02:39:03 +00004553 }
Greg Claytona1743492012-03-13 23:14:29 +00004554
4555 default:
4556 break;
Sean Callanan226b70c2012-03-08 02:39:03 +00004557 }
Greg Claytona1743492012-03-13 23:14:29 +00004558 if (done)
4559 break;
Jim Ingham672e6f52011-03-07 23:44:08 +00004560
Greg Claytona1743492012-03-13 23:14:29 +00004561 // Go to the next load command:
4562 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham672e6f52011-03-07 23:44:08 +00004563 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004564
Greg Claytona1743492012-03-13 23:14:29 +00004565 if (start_address != LLDB_INVALID_ADDRESS)
Greg Claytone72dfb32012-02-24 01:59:29 +00004566 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00004567 // We got the start address from the load commands, so now resolve that address in the sections
Greg Claytona1743492012-03-13 23:14:29 +00004568 // of this ObjectFile:
4569 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Claytone72dfb32012-02-24 01:59:29 +00004570 {
Greg Claytona1743492012-03-13 23:14:29 +00004571 m_entry_point_address.Clear();
4572 }
4573 }
4574 else
4575 {
4576 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
4577 // "start" symbol in the main executable.
Jason Molenda4e7511e2013-03-06 23:19:17 +00004578
Greg Claytona1743492012-03-13 23:14:29 +00004579 ModuleSP module_sp (GetModule());
Jason Molenda4e7511e2013-03-06 23:19:17 +00004580
Greg Claytona1743492012-03-13 23:14:29 +00004581 if (module_sp)
4582 {
4583 SymbolContextList contexts;
4584 SymbolContext context;
4585 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
4586 {
4587 if (contexts.GetContextAtIndex(0, context))
4588 m_entry_point_address = context.symbol->GetAddress();
4589 }
Greg Claytone72dfb32012-02-24 01:59:29 +00004590 }
4591 }
Jim Ingham672e6f52011-03-07 23:44:08 +00004592 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004593
Jim Ingham672e6f52011-03-07 23:44:08 +00004594 return m_entry_point_address;
4595
4596}
4597
Greg Claytonc9660542012-02-05 02:38:54 +00004598lldb_private::Address
4599ObjectFileMachO::GetHeaderAddress ()
4600{
4601 lldb_private::Address header_addr;
4602 SectionList *section_list = GetSectionList();
4603 if (section_list)
4604 {
4605 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
4606 if (text_segment_sp)
4607 {
Greg Claytone72dfb32012-02-24 01:59:29 +00004608 header_addr.SetSection (text_segment_sp);
Greg Claytonc9660542012-02-05 02:38:54 +00004609 header_addr.SetOffset (0);
4610 }
4611 }
4612 return header_addr;
4613}
4614
Greg Claytonc3776bf2012-02-09 06:16:32 +00004615uint32_t
4616ObjectFileMachO::GetNumThreadContexts ()
4617{
Greg Claytona1743492012-03-13 23:14:29 +00004618 ModuleSP module_sp(GetModule());
4619 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00004620 {
Greg Claytona1743492012-03-13 23:14:29 +00004621 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4622 if (!m_thread_context_offsets_valid)
Greg Claytonc3776bf2012-02-09 06:16:32 +00004623 {
Greg Claytona1743492012-03-13 23:14:29 +00004624 m_thread_context_offsets_valid = true;
Greg Claytonc7bece562013-01-25 18:06:21 +00004625 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00004626 FileRangeArray::Entry file_range;
4627 thread_command thread_cmd;
4628 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Claytonc3776bf2012-02-09 06:16:32 +00004629 {
Greg Claytona1743492012-03-13 23:14:29 +00004630 const uint32_t cmd_offset = offset;
4631 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
4632 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004633
Charles Davis510938e2013-08-27 05:04:57 +00004634 if (thread_cmd.cmd == LC_THREAD)
Greg Claytona1743492012-03-13 23:14:29 +00004635 {
4636 file_range.SetRangeBase (offset);
4637 file_range.SetByteSize (thread_cmd.cmdsize - 8);
4638 m_thread_context_offsets.Append (file_range);
4639 }
4640 offset = cmd_offset + thread_cmd.cmdsize;
Greg Claytonc3776bf2012-02-09 06:16:32 +00004641 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00004642 }
4643 }
4644 return m_thread_context_offsets.GetSize();
4645}
4646
4647lldb::RegisterContextSP
4648ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
4649{
Greg Claytonc3776bf2012-02-09 06:16:32 +00004650 lldb::RegisterContextSP reg_ctx_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +00004651
Greg Claytona1743492012-03-13 23:14:29 +00004652 ModuleSP module_sp(GetModule());
4653 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00004654 {
Greg Claytona1743492012-03-13 23:14:29 +00004655 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4656 if (!m_thread_context_offsets_valid)
4657 GetNumThreadContexts ();
4658
4659 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
Jim Ingham28eb5712012-10-12 17:34:26 +00004660 if (thread_context_file_range)
Greg Claytona1743492012-03-13 23:14:29 +00004661 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00004662
4663 DataExtractor data (m_data,
4664 thread_context_file_range->GetRangeBase(),
Jim Ingham28eb5712012-10-12 17:34:26 +00004665 thread_context_file_range->GetByteSize());
4666
4667 switch (m_header.cputype)
4668 {
Jason Molendaa3329782014-03-29 18:54:20 +00004669 case llvm::MachO::CPU_TYPE_ARM64:
4670 reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
4671 break;
4672
Charles Davis510938e2013-08-27 05:04:57 +00004673 case llvm::MachO::CPU_TYPE_ARM:
Jim Ingham28eb5712012-10-12 17:34:26 +00004674 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
4675 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004676
Charles Davis510938e2013-08-27 05:04:57 +00004677 case llvm::MachO::CPU_TYPE_I386:
Jim Ingham28eb5712012-10-12 17:34:26 +00004678 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
4679 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004680
Charles Davis510938e2013-08-27 05:04:57 +00004681 case llvm::MachO::CPU_TYPE_X86_64:
Jim Ingham28eb5712012-10-12 17:34:26 +00004682 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
4683 break;
4684 }
Greg Claytona1743492012-03-13 23:14:29 +00004685 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00004686 }
4687 return reg_ctx_sp;
4688}
4689
Greg Claytonc9660542012-02-05 02:38:54 +00004690
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004691ObjectFile::Type
4692ObjectFileMachO::CalculateType()
4693{
4694 switch (m_header.filetype)
4695 {
Charles Davis510938e2013-08-27 05:04:57 +00004696 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004697 if (GetAddressByteSize () == 4)
4698 {
4699 // 32 bit kexts are just object files, but they do have a valid
4700 // UUID load command.
4701 UUID uuid;
4702 if (GetUUID(&uuid))
4703 {
4704 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00004705 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004706 // "OSKextGetCurrentIdentifier" as this is required of kexts
4707 if (m_strata == eStrataInvalid)
4708 m_strata = eStrataKernel;
4709 return eTypeSharedLibrary;
4710 }
4711 }
4712 return eTypeObjectFile;
4713
Charles Davis510938e2013-08-27 05:04:57 +00004714 case MH_EXECUTE: return eTypeExecutable; // 0x2u
4715 case MH_FVMLIB: return eTypeSharedLibrary; // 0x3u
4716 case MH_CORE: return eTypeCoreFile; // 0x4u
4717 case MH_PRELOAD: return eTypeSharedLibrary; // 0x5u
4718 case MH_DYLIB: return eTypeSharedLibrary; // 0x6u
4719 case MH_DYLINKER: return eTypeDynamicLinker; // 0x7u
4720 case MH_BUNDLE: return eTypeSharedLibrary; // 0x8u
4721 case MH_DYLIB_STUB: return eTypeStubLibrary; // 0x9u
4722 case MH_DSYM: return eTypeDebugInfo; // 0xAu
4723 case MH_KEXT_BUNDLE: return eTypeSharedLibrary; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004724 default:
4725 break;
4726 }
4727 return eTypeUnknown;
4728}
4729
4730ObjectFile::Strata
4731ObjectFileMachO::CalculateStrata()
4732{
4733 switch (m_header.filetype)
4734 {
Charles Davis510938e2013-08-27 05:04:57 +00004735 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004736 {
4737 // 32 bit kexts are just object files, but they do have a valid
4738 // UUID load command.
4739 UUID uuid;
4740 if (GetUUID(&uuid))
4741 {
4742 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00004743 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004744 // "OSKextGetCurrentIdentifier" as this is required of kexts
4745 if (m_type == eTypeInvalid)
4746 m_type = eTypeSharedLibrary;
4747
4748 return eStrataKernel;
4749 }
4750 }
4751 return eStrataUnknown;
4752
Charles Davis510938e2013-08-27 05:04:57 +00004753 case MH_EXECUTE: // 0x2u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004754 // Check for the MH_DYLDLINK bit in the flags
Charles Davis510938e2013-08-27 05:04:57 +00004755 if (m_header.flags & MH_DYLDLINK)
Sean Callanan49bce8e2012-02-10 20:22:35 +00004756 {
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004757 return eStrataUser;
Sean Callanan49bce8e2012-02-10 20:22:35 +00004758 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004759 else
Sean Callanan49bce8e2012-02-10 20:22:35 +00004760 {
4761 SectionList *section_list = GetSectionList();
4762 if (section_list)
4763 {
4764 static ConstString g_kld_section_name ("__KLD");
4765 if (section_list->FindSectionByName(g_kld_section_name))
4766 return eStrataKernel;
4767 }
4768 }
4769 return eStrataRawImage;
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004770
Charles Davis510938e2013-08-27 05:04:57 +00004771 case MH_FVMLIB: return eStrataUser; // 0x3u
4772 case MH_CORE: return eStrataUnknown; // 0x4u
4773 case MH_PRELOAD: return eStrataRawImage; // 0x5u
4774 case MH_DYLIB: return eStrataUser; // 0x6u
4775 case MH_DYLINKER: return eStrataUser; // 0x7u
4776 case MH_BUNDLE: return eStrataUser; // 0x8u
4777 case MH_DYLIB_STUB: return eStrataUser; // 0x9u
4778 case MH_DSYM: return eStrataUnknown; // 0xAu
4779 case MH_KEXT_BUNDLE: return eStrataKernel; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00004780 default:
4781 break;
4782 }
4783 return eStrataUnknown;
4784}
4785
4786
Greg Claytonc2ff9312012-02-22 19:41:02 +00004787uint32_t
4788ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
4789{
Greg Claytona1743492012-03-13 23:14:29 +00004790 ModuleSP module_sp(GetModule());
4791 if (module_sp)
Greg Claytonc2ff9312012-02-22 19:41:02 +00004792 {
Greg Claytona1743492012-03-13 23:14:29 +00004793 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4794 struct dylib_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004795 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00004796 uint32_t version_cmd = 0;
4797 uint64_t version = 0;
4798 uint32_t i;
4799 for (i=0; i<m_header.ncmds; ++i)
Greg Claytonc2ff9312012-02-22 19:41:02 +00004800 {
Greg Claytonc7bece562013-01-25 18:06:21 +00004801 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00004802 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4803 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004804
Charles Davis510938e2013-08-27 05:04:57 +00004805 if (load_cmd.cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00004806 {
Greg Claytona1743492012-03-13 23:14:29 +00004807 if (version_cmd == 0)
4808 {
4809 version_cmd = load_cmd.cmd;
4810 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
4811 break;
4812 version = load_cmd.dylib.current_version;
4813 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004814 break; // Break for now unless there is another more complete version
Greg Claytona1743492012-03-13 23:14:29 +00004815 // number load command in the future.
Greg Claytonc2ff9312012-02-22 19:41:02 +00004816 }
Greg Claytona1743492012-03-13 23:14:29 +00004817 offset = cmd_offset + load_cmd.cmdsize;
Greg Claytonc2ff9312012-02-22 19:41:02 +00004818 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004819
Charles Davis510938e2013-08-27 05:04:57 +00004820 if (version_cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00004821 {
Greg Claytona1743492012-03-13 23:14:29 +00004822 if (versions != NULL && num_versions > 0)
4823 {
4824 if (num_versions > 0)
4825 versions[0] = (version & 0xFFFF0000ull) >> 16;
4826 if (num_versions > 1)
4827 versions[1] = (version & 0x0000FF00ull) >> 8;
4828 if (num_versions > 2)
4829 versions[2] = (version & 0x000000FFull);
4830 // Fill in an remaining version numbers with invalid values
4831 for (i=3; i<num_versions; ++i)
4832 versions[i] = UINT32_MAX;
4833 }
4834 // The LC_ID_DYLIB load command has a version with 3 version numbers
4835 // in it, so always return 3
4836 return 3;
Greg Claytonc2ff9312012-02-22 19:41:02 +00004837 }
Greg Claytonc2ff9312012-02-22 19:41:02 +00004838 }
4839 return false;
4840}
4841
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004842bool
Greg Clayton514487e2011-02-15 21:59:32 +00004843ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004844{
Greg Claytona1743492012-03-13 23:14:29 +00004845 ModuleSP module_sp(GetModule());
4846 if (module_sp)
Greg Clayton593577a2011-09-21 03:57:31 +00004847 {
Greg Claytona1743492012-03-13 23:14:29 +00004848 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Clayton7ab7f892014-05-29 21:33:45 +00004849 return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch);
Greg Clayton593577a2011-09-21 03:57:31 +00004850 }
Greg Claytona1743492012-03-13 23:14:29 +00004851 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004852}
4853
4854
Jason Molenda0e0954c2013-04-16 06:24:42 +00004855UUID
4856ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
4857{
4858 UUID uuid;
4859 if (process)
4860 {
4861 addr_t all_image_infos = process->GetImageInfoAddress();
4862
4863 // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
4864 // or it may be the address of the dyld_all_image_infos structure (want). The first four
4865 // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
4866 // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
4867
4868 Error err;
4869 uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00004870 if (version_or_magic != static_cast<uint32_t>(-1)
Charles Davis510938e2013-08-27 05:04:57 +00004871 && version_or_magic != MH_MAGIC
4872 && version_or_magic != MH_CIGAM
4873 && version_or_magic != MH_MAGIC_64
4874 && version_or_magic != MH_CIGAM_64
Jason Molenda0e0954c2013-04-16 06:24:42 +00004875 && version_or_magic >= 13)
4876 {
4877 addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
4878 int wordsize = process->GetAddressByteSize();
4879 if (wordsize == 8)
4880 {
4881 sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
4882 }
4883 if (wordsize == 4)
4884 {
4885 sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
4886 }
4887 if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
4888 {
4889 uuid_t shared_cache_uuid;
4890 if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
4891 {
4892 uuid.SetBytes (shared_cache_uuid);
4893 }
4894 }
4895 }
4896 }
4897 return uuid;
4898}
4899
4900UUID
4901ObjectFileMachO::GetLLDBSharedCacheUUID ()
4902{
4903 UUID uuid;
Todd Fiala013434e2014-07-09 01:29:05 +00004904#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +00004905 uint8_t *(*dyld_get_all_image_infos)(void);
4906 dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
4907 if (dyld_get_all_image_infos)
4908 {
4909 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
4910 if (dyld_all_image_infos_address)
4911 {
Jason Molendac9cb7d22013-04-16 21:42:58 +00004912 uint32_t *version = (uint32_t*) dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
4913 if (*version >= 13)
Jason Molenda0e0954c2013-04-16 06:24:42 +00004914 {
Jason Molendaa3329782014-03-29 18:54:20 +00004915 uuid_t *sharedCacheUUID_address = 0;
4916 int wordsize = sizeof (uint8_t *);
4917 if (wordsize == 8)
4918 {
4919 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
4920 }
4921 else
4922 {
4923 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84); // sharedCacheUUID <mach-o/dyld_images.h>
4924 }
Jason Molenda0e0954c2013-04-16 06:24:42 +00004925 uuid.SetBytes (sharedCacheUUID_address);
4926 }
4927 }
4928 }
4929#endif
4930 return uuid;
4931}
4932
Greg Clayton9b234982013-10-24 22:54:08 +00004933uint32_t
4934ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
4935{
4936 if (m_min_os_versions.empty())
4937 {
4938 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
4939 bool success = false;
4940 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
4941 {
4942 const lldb::offset_t load_cmd_offset = offset;
4943
4944 version_min_command lc;
4945 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
4946 break;
4947 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
4948 {
4949 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
4950 {
4951 const uint32_t xxxx = lc.version >> 16;
4952 const uint32_t yy = (lc.version >> 8) & 0xffu;
4953 const uint32_t zz = lc.version & 0xffu;
4954 if (xxxx)
4955 {
4956 m_min_os_versions.push_back(xxxx);
4957 if (yy)
4958 {
4959 m_min_os_versions.push_back(yy);
4960 if (zz)
4961 m_min_os_versions.push_back(zz);
4962 }
4963 }
4964 success = true;
4965 }
4966 }
4967 offset = load_cmd_offset + lc.cmdsize;
4968 }
4969
4970 if (success == false)
4971 {
4972 // Push an invalid value so we don't keep trying to
4973 m_min_os_versions.push_back(UINT32_MAX);
4974 }
4975 }
4976
4977 if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
4978 {
4979 if (versions != NULL && num_versions > 0)
4980 {
4981 for (size_t i=0; i<num_versions; ++i)
4982 {
4983 if (i < m_min_os_versions.size())
4984 versions[i] = m_min_os_versions[i];
4985 else
4986 versions[i] = 0;
4987 }
4988 }
4989 return m_min_os_versions.size();
4990 }
4991 // Call the superclasses version that will empty out the data
4992 return ObjectFile::GetMinimumOSVersion (versions, num_versions);
4993}
4994
4995uint32_t
4996ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions)
4997{
4998 if (m_sdk_versions.empty())
4999 {
5000 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5001 bool success = false;
5002 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5003 {
5004 const lldb::offset_t load_cmd_offset = offset;
5005
5006 version_min_command lc;
5007 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5008 break;
5009 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5010 {
5011 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5012 {
5013 const uint32_t xxxx = lc.reserved >> 16;
5014 const uint32_t yy = (lc.reserved >> 8) & 0xffu;
5015 const uint32_t zz = lc.reserved & 0xffu;
5016 if (xxxx)
5017 {
5018 m_sdk_versions.push_back(xxxx);
5019 if (yy)
5020 {
5021 m_sdk_versions.push_back(yy);
5022 if (zz)
5023 m_sdk_versions.push_back(zz);
5024 }
5025 }
5026 success = true;
5027 }
5028 }
5029 offset = load_cmd_offset + lc.cmdsize;
5030 }
5031
5032 if (success == false)
5033 {
5034 // Push an invalid value so we don't keep trying to
5035 m_sdk_versions.push_back(UINT32_MAX);
5036 }
5037 }
5038
5039 if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
5040 {
5041 if (versions != NULL && num_versions > 0)
5042 {
5043 for (size_t i=0; i<num_versions; ++i)
5044 {
5045 if (i < m_sdk_versions.size())
5046 versions[i] = m_sdk_versions[i];
5047 else
5048 versions[i] = 0;
5049 }
5050 }
5051 return m_sdk_versions.size();
5052 }
5053 // Call the superclasses version that will empty out the data
5054 return ObjectFile::GetSDKVersion (versions, num_versions);
5055}
5056
Jason Molenda0e0954c2013-04-16 06:24:42 +00005057
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005058//------------------------------------------------------------------
5059// PluginInterface protocol
5060//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00005061lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005062ObjectFileMachO::GetPluginName()
5063{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005064 return GetPluginNameStatic();
5065}
5066
5067uint32_t
5068ObjectFileMachO::GetPluginVersion()
5069{
5070 return 1;
5071}
5072
Greg Clayton7524e092014-02-06 20:10:16 +00005073
5074bool
Greg Clayton751caf62014-02-07 22:54:47 +00005075ObjectFileMachO::SetLoadAddress (Target &target,
5076 lldb::addr_t value,
5077 bool value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005078{
5079 bool changed = false;
5080 ModuleSP module_sp = GetModule();
5081 if (module_sp)
5082 {
5083 size_t num_loaded_sections = 0;
5084 SectionList *section_list = GetSectionList ();
5085 if (section_list)
5086 {
5087 lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
5088 const size_t num_sections = section_list->GetSize();
5089
Greg Clayton751caf62014-02-07 22:54:47 +00005090 const bool is_memory_image = (bool)m_process_wp.lock();
5091 const Strata strata = GetStrata();
5092 static ConstString g_linkedit_segname ("__LINKEDIT");
5093 if (value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005094 {
Greg Clayton751caf62014-02-07 22:54:47 +00005095 // "value" is an offset to apply to each top level segment
Greg Clayton7524e092014-02-06 20:10:16 +00005096 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5097 {
5098 // Iterate through the object file sections to find all
5099 // of the sections that size on disk (to avoid __PAGEZERO)
5100 // and load them
5101 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton751caf62014-02-07 22:54:47 +00005102 if (section_sp &&
5103 section_sp->GetFileSize() > 0 &&
5104 section_sp->IsThreadSpecific() == false &&
5105 module_sp.get() == section_sp->GetModule().get())
Greg Clayton7524e092014-02-06 20:10:16 +00005106 {
Greg Clayton751caf62014-02-07 22:54:47 +00005107 // Ignore __LINKEDIT and __DWARF segments
5108 if (section_sp->GetName() == g_linkedit_segname)
5109 {
5110 // Only map __LINKEDIT if we have an in memory image and this isn't
5111 // a kernel binary like a kext or mach_kernel.
5112 if (is_memory_image == false || strata == eStrataKernel)
5113 continue;
5114 }
5115 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
Greg Clayton7524e092014-02-06 20:10:16 +00005116 ++num_loaded_sections;
5117 }
5118 }
5119 }
Greg Clayton751caf62014-02-07 22:54:47 +00005120 else
5121 {
5122 // "value" is the new base address of the mach_header, adjust each
5123 // section accordingly
5124
5125 // First find the address of the mach header which is the first non-zero
5126 // file sized section whose file offset is zero as this will be subtracted
5127 // from each other valid section's vmaddr and then get "base_addr" added to
5128 // it when loading the module in the target
5129 for (size_t sect_idx = 0;
5130 sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
5131 ++sect_idx)
5132 {
5133 // Iterate through the object file sections to find all
5134 // of the sections that size on disk (to avoid __PAGEZERO)
5135 // and load them
5136 Section *section = section_list->GetSectionAtIndex (sect_idx).get();
5137 if (section &&
5138 section->GetFileSize() > 0 &&
5139 section->GetFileOffset() == 0 &&
5140 section->IsThreadSpecific() == false &&
5141 module_sp.get() == section->GetModule().get())
5142 {
5143 // Ignore __LINKEDIT and __DWARF segments
5144 if (section->GetName() == g_linkedit_segname)
5145 {
5146 // Only map __LINKEDIT if we have an in memory image and this isn't
5147 // a kernel binary like a kext or mach_kernel.
5148 if (is_memory_image == false || strata == eStrataKernel)
5149 continue;
5150 }
5151 mach_base_file_addr = section->GetFileAddress();
5152 }
5153 }
5154
5155 if (mach_base_file_addr != LLDB_INVALID_ADDRESS)
5156 {
5157 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5158 {
5159 // Iterate through the object file sections to find all
5160 // of the sections that size on disk (to avoid __PAGEZERO)
5161 // and load them
5162 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
5163 if (section_sp &&
5164 section_sp->GetFileSize() > 0 &&
5165 section_sp->IsThreadSpecific() == false &&
5166 module_sp.get() == section_sp->GetModule().get())
5167 {
5168 // Ignore __LINKEDIT and __DWARF segments
5169 if (section_sp->GetName() == g_linkedit_segname)
5170 {
5171 // Only map __LINKEDIT if we have an in memory image and this isn't
5172 // a kernel binary like a kext or mach_kernel.
5173 if (is_memory_image == false || strata == eStrataKernel)
5174 continue;
5175 }
5176 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() - mach_base_file_addr + value))
5177 ++num_loaded_sections;
5178 }
5179 }
5180 }
5181 }
Greg Clayton7524e092014-02-06 20:10:16 +00005182 }
5183 changed = num_loaded_sections > 0;
5184 return num_loaded_sections > 0;
5185 }
5186 return changed;
5187}
5188
Greg Claytona2715cf2014-06-13 00:54:12 +00005189bool
5190ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp,
5191 const FileSpec &outfile,
5192 Error &error)
5193{
5194 if (process_sp)
5195 {
5196 Target &target = process_sp->GetTarget();
5197 const ArchSpec target_arch = target.GetArchitecture();
5198 const llvm::Triple &target_triple = target_arch.GetTriple();
5199 if (target_triple.getVendor() == llvm::Triple::Apple &&
5200 (target_triple.getOS() == llvm::Triple::MacOSX ||
5201 target_triple.getOS() == llvm::Triple::IOS))
5202 {
5203 bool make_core = false;
5204 switch (target_arch.GetMachine())
5205 {
5206 case llvm::Triple::arm:
5207 case llvm::Triple::x86:
5208 case llvm::Triple::x86_64:
5209 make_core = true;
5210 break;
5211 default:
5212 error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str());
5213 break;
5214 }
5215
5216 if (make_core)
5217 {
5218 std::vector<segment_command_64> segment_load_commands;
Saleem Abdulrasool3924d752014-06-13 03:30:39 +00005219// uint32_t range_info_idx = 0;
Greg Claytona2715cf2014-06-13 00:54:12 +00005220 MemoryRegionInfo range_info;
5221 Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
5222 if (range_error.Success())
5223 {
5224 while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS)
5225 {
5226 const addr_t addr = range_info.GetRange().GetRangeBase();
5227 const addr_t size = range_info.GetRange().GetByteSize();
5228
5229 if (size == 0)
5230 break;
5231
5232 // Calculate correct protections
5233 uint32_t prot = 0;
5234 if (range_info.GetReadable() == MemoryRegionInfo::eYes)
5235 prot |= VM_PROT_READ;
5236 if (range_info.GetWritable() == MemoryRegionInfo::eYes)
5237 prot |= VM_PROT_WRITE;
5238 if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
5239 prot |= VM_PROT_EXECUTE;
5240
5241// printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n",
5242// range_info_idx,
5243// addr,
5244// size,
5245// (prot & VM_PROT_READ ) ? 'r' : '-',
5246// (prot & VM_PROT_WRITE ) ? 'w' : '-',
5247// (prot & VM_PROT_EXECUTE) ? 'x' : '-');
5248
5249 if (prot != 0)
5250 {
5251 segment_command_64 segment = {
5252 LC_SEGMENT_64, // uint32_t cmd;
5253 sizeof(segment), // uint32_t cmdsize;
5254 {0}, // char segname[16];
5255 addr, // uint64_t vmaddr;
5256 size, // uint64_t vmsize;
5257 0, // uint64_t fileoff;
5258 size, // uint64_t filesize;
5259 prot, // uint32_t maxprot;
5260 prot, // uint32_t initprot;
5261 0, // uint32_t nsects;
5262 0 }; // uint32_t flags;
5263 segment_load_commands.push_back(segment);
5264 }
5265 else
5266 {
5267 // No protections and a size of 1 used to be returned from old
5268 // debugservers when we asked about a region that was past the
5269 // last memory region and it indicates the end...
5270 if (size == 1)
5271 break;
5272 }
5273
5274 range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info);
5275 if (range_error.Fail())
5276 break;
5277 }
5278
5279 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
5280 const ByteOrder byte_order = target_arch.GetByteOrder();
5281 StreamString buffer (Stream::eBinary,
5282 addr_byte_size,
5283 byte_order);
5284
5285 mach_header_64 mach_header;
5286 mach_header.magic = MH_MAGIC_64;
5287 mach_header.cputype = target_arch.GetMachOCPUType();
5288 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
5289 mach_header.filetype = MH_CORE;
5290 mach_header.ncmds = segment_load_commands.size();
5291 mach_header.flags = 0;
5292 mach_header.reserved = 0;
5293 ThreadList &thread_list = process_sp->GetThreadList();
5294 const uint32_t num_threads = thread_list.GetSize();
5295
5296 // Make an array of LC_THREAD data items. Each one contains
5297 // the contents of the LC_THREAD load command. The data doesn't
5298 // contain the load command + load command size, we will
5299 // add the load command and load command size as we emit the data.
5300 std::vector<StreamString> LC_THREAD_datas(num_threads);
5301 for (auto &LC_THREAD_data : LC_THREAD_datas)
5302 {
5303 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
5304 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
5305 LC_THREAD_data.SetByteOrder(byte_order);
5306 }
5307 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
5308 {
5309 ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx));
5310 if (thread_sp)
5311 {
5312 switch (mach_header.cputype)
5313 {
5314 case llvm::MachO::CPU_TYPE_ARM:
5315 //RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), thread_load_commands);
5316 break;
5317
5318 case llvm::MachO::CPU_TYPE_I386:
5319 //RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), thread_load_commands);
5320 break;
5321
5322 case llvm::MachO::CPU_TYPE_X86_64:
5323 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5324 break;
5325 }
5326
5327 }
5328 }
5329
5330 // The size of the load command is the size of the segments...
5331 mach_header.sizeofcmds = segment_load_commands.size() * segment_load_commands[0].cmdsize;
5332
5333 // and the size of all LC_THREAD load command
5334 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5335 {
5336 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
5337 }
5338
5339 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",
5340 mach_header.magic,
5341 mach_header.cputype,
5342 mach_header.cpusubtype,
5343 mach_header.filetype,
5344 mach_header.ncmds,
5345 mach_header.sizeofcmds,
5346 mach_header.flags,
5347 mach_header.reserved);
5348
5349 // Write the mach header
5350 buffer.PutHex32(mach_header.magic);
5351 buffer.PutHex32(mach_header.cputype);
5352 buffer.PutHex32(mach_header.cpusubtype);
5353 buffer.PutHex32(mach_header.filetype);
5354 buffer.PutHex32(mach_header.ncmds);
5355 buffer.PutHex32(mach_header.sizeofcmds);
5356 buffer.PutHex32(mach_header.flags);
5357 buffer.PutHex32(mach_header.reserved);
5358
5359 // Skip the mach header and all load commands and align to the next
5360 // 0x1000 byte boundary
5361 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
5362 if (file_offset & 0x00000fff)
5363 {
5364 file_offset += 0x00001000ull;
5365 file_offset &= (~0x00001000ull + 1);
5366 }
5367
5368 for (auto &segment : segment_load_commands)
5369 {
5370 segment.fileoff = file_offset;
5371 file_offset += segment.filesize;
5372 }
5373
5374 // Write out all of the LC_THREAD load commands
5375 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5376 {
5377 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
5378 buffer.PutHex32(LC_THREAD);
5379 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
5380 buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size);
5381 }
5382
5383 // Write out all of the segment load commands
5384 for (const auto &segment : segment_load_commands)
5385 {
5386 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",
5387 segment.cmd,
5388 segment.cmdsize,
5389 segment.vmaddr,
5390 segment.vmaddr + segment.vmsize,
5391 segment.fileoff,
5392 segment.filesize,
5393 segment.maxprot,
5394 segment.initprot,
5395 segment.nsects,
5396 segment.flags);
5397
5398 buffer.PutHex32(segment.cmd);
5399 buffer.PutHex32(segment.cmdsize);
5400 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
5401 buffer.PutHex64(segment.vmaddr);
5402 buffer.PutHex64(segment.vmsize);
5403 buffer.PutHex64(segment.fileoff);
5404 buffer.PutHex64(segment.filesize);
5405 buffer.PutHex32(segment.maxprot);
5406 buffer.PutHex32(segment.initprot);
5407 buffer.PutHex32(segment.nsects);
5408 buffer.PutHex32(segment.flags);
5409 }
5410
5411 File core_file;
5412 std::string core_file_path(outfile.GetPath());
5413 error = core_file.Open(core_file_path.c_str(),
5414 File::eOpenOptionWrite |
5415 File::eOpenOptionTruncate |
5416 File::eOpenOptionCanCreate);
5417 if (error.Success())
5418 {
5419 // Read 1 page at a time
5420 uint8_t bytes[0x1000];
5421 // Write the mach header and load commands out to the core file
5422 size_t bytes_written = buffer.GetString().size();
5423 error = core_file.Write(buffer.GetString().data(), bytes_written);
5424 if (error.Success())
5425 {
5426 // Now write the file data for all memory segments in the process
5427 for (const auto &segment : segment_load_commands)
5428 {
5429 if (segment.fileoff != core_file.SeekFromStart(segment.fileoff))
5430 {
5431 error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str());
5432 break;
5433 }
5434
Joerg Sonnenberger968697d2014-07-18 11:58:19 +00005435 printf ("Saving data for segment at 0x%" PRIx64 "\n", segment.vmaddr);
Greg Claytona2715cf2014-06-13 00:54:12 +00005436 addr_t bytes_left = segment.vmsize;
5437 addr_t addr = segment.vmaddr;
5438 Error memory_read_error;
5439 while (bytes_left > 0 && error.Success())
5440 {
5441 const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
5442 const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error);
5443 if (bytes_read == bytes_to_read)
5444 {
5445 size_t bytes_written = bytes_read;
5446 error = core_file.Write(bytes, bytes_written);
5447 bytes_left -= bytes_read;
5448 addr += bytes_read;
5449 }
5450 else
5451 {
5452 // Some pages within regions are not readable, those
5453 // should be zero filled
5454 memset (bytes, 0, bytes_to_read);
5455 size_t bytes_written = bytes_to_read;
5456 error = core_file.Write(bytes, bytes_written);
5457 bytes_left -= bytes_to_read;
5458 addr += bytes_to_read;
5459 }
5460 }
5461 }
5462 }
5463 }
5464 }
5465 else
5466 {
5467 error.SetErrorString("process doesn't support getting memory region info");
5468 }
5469 }
5470 return true; // This is the right plug to handle saving core files for this process
5471 }
5472 }
5473 return false;
5474}
5475