blob: 4decef691137bc513883b81c527caa456bb3300e [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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Core/ArchSpec.h"
13#include "lldb/Core/DataBuffer.h"
Jason Molendaf6ce26f2013-04-10 05:58:57 +000014#include "lldb/Core/Debugger.h"
Greg Claytona2715cf2014-06-13 00:54:12 +000015#include "lldb/Core/Error.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/FileSpecList.h"
Greg Clayton3f839a32012-09-05 01:38:55 +000017#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Module.h"
Greg Claytonf4d6de62013-04-24 22:29:28 +000019#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/PluginManager.h"
Greg Clayton1eac0c72012-04-24 03:06:13 +000021#include "lldb/Core/RangeMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/Section.h"
23#include "lldb/Core/StreamFile.h"
24#include "lldb/Core/StreamString.h"
25#include "lldb/Core/Timer.h"
26#include "lldb/Core/UUID.h"
Greg Claytone38a5ed2012-01-05 03:57:59 +000027#include "lldb/Host/Host.h"
28#include "lldb/Host/FileSpec.h"
Jason Molenda5635f772013-03-21 03:36:01 +000029#include "lldb/Symbol/DWARFCallFrameInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Symbol/ObjectFile.h"
Zachary Turner93749ab2015-03-03 21:51:25 +000031#include "lldb/Target/MemoryRegionInfo.h"
Greg Clayton26b47e22012-04-18 05:19:20 +000032#include "lldb/Target/Platform.h"
Greg Claytonc9660542012-02-05 02:38:54 +000033#include "lldb/Target/Process.h"
Greg Clayton7524e092014-02-06 20:10:16 +000034#include "lldb/Target/SectionLoadList.h"
Greg Clayton26b47e22012-04-18 05:19:20 +000035#include "lldb/Target/Target.h"
Greg Claytona2715cf2014-06-13 00:54:12 +000036#include "lldb/Target/Thread.h"
37#include "lldb/Target/ThreadList.h"
Greg Claytonc859e2d2012-02-13 23:10:39 +000038#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
Jason Molendaa3329782014-03-29 18:54:20 +000039#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
Greg Claytonc859e2d2012-02-13 23:10:39 +000040#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
Greg Claytonc3776bf2012-02-09 06:16:32 +000041#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
Jim Ingham46d005d2014-04-02 22:53:21 +000043#include "lldb/Utility/SafeMachO.h"
44
45#include "ObjectFileMachO.h"
46
Todd Fiala013434e2014-07-09 01:29:05 +000047#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +000048// GetLLDBSharedCacheUUID() needs to call dlsym()
49#include <dlfcn.h>
50#endif
51
Daniel Maleaffeb4b62013-04-17 19:24:22 +000052#ifndef __APPLE__
53#include "Utility/UuidCompatibility.h"
54#endif
55
Greg Claytonb887da12015-07-16 19:50:57 +000056#define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057using namespace lldb;
58using namespace lldb_private;
Greg Claytone1a916a2010-07-21 22:12:05 +000059using namespace llvm::MachO;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060
Jason Molenda4e7511e2013-03-06 23:19:17 +000061class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
Greg Claytonc3776bf2012-02-09 06:16:32 +000062{
63public:
64 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
65 RegisterContextDarwin_x86_64 (thread, 0)
66 {
67 SetRegisterDataFrom_LC_THREAD (data);
68 }
69
70 virtual void
71 InvalidateAllRegisters ()
72 {
73 // Do nothing... registers are always valid...
74 }
75
76 void
77 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
78 {
Greg Claytonc7bece562013-01-25 18:06:21 +000079 lldb::offset_t offset = 0;
Greg Claytonc3776bf2012-02-09 06:16:32 +000080 SetError (GPRRegSet, Read, -1);
81 SetError (FPURegSet, Read, -1);
82 SetError (EXCRegSet, Read, -1);
Greg Claytonc859e2d2012-02-13 23:10:39 +000083 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +000084
Greg Claytonc859e2d2012-02-13 23:10:39 +000085 while (!done)
Greg Claytonc3776bf2012-02-09 06:16:32 +000086 {
Greg Claytonc859e2d2012-02-13 23:10:39 +000087 int flavor = data.GetU32 (&offset);
88 if (flavor == 0)
89 done = true;
90 else
Greg Claytonc3776bf2012-02-09 06:16:32 +000091 {
Greg Claytonc859e2d2012-02-13 23:10:39 +000092 uint32_t i;
93 uint32_t count = data.GetU32 (&offset);
94 switch (flavor)
95 {
96 case GPRRegSet:
97 for (i=0; i<count; ++i)
98 (&gpr.rax)[i] = data.GetU64(&offset);
99 SetError (GPRRegSet, Read, 0);
100 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000101
Greg Claytonc859e2d2012-02-13 23:10:39 +0000102 break;
103 case FPURegSet:
104 // TODO: fill in FPU regs....
105 //SetError (FPURegSet, Read, -1);
106 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000107
Greg Claytonc859e2d2012-02-13 23:10:39 +0000108 break;
109 case EXCRegSet:
110 exc.trapno = data.GetU32(&offset);
111 exc.err = data.GetU32(&offset);
112 exc.faultvaddr = data.GetU64(&offset);
113 SetError (EXCRegSet, Read, 0);
114 done = true;
115 break;
116 case 7:
117 case 8:
118 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000119 // fancy flavors that encapsulate of the above
120 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000121 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000122
Greg Claytonc859e2d2012-02-13 23:10:39 +0000123 default:
124 done = true;
125 break;
126 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000127 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000128 }
129 }
Greg Claytona2715cf2014-06-13 00:54:12 +0000130
Jason Molendad20359d2014-11-11 10:59:15 +0000131
Greg Claytona2715cf2014-06-13 00:54:12 +0000132 static size_t
133 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
134 {
135 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
136 if (reg_info == NULL)
137 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
138 if (reg_info)
139 {
140 lldb_private::RegisterValue reg_value;
141 if (reg_ctx->ReadRegister(reg_info, reg_value))
142 {
143 if (reg_info->byte_size >= reg_byte_size)
144 data.Write(reg_value.GetBytes(), reg_byte_size);
145 else
146 {
147 data.Write(reg_value.GetBytes(), reg_info->byte_size);
148 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
149 data.PutChar(0);
150 }
151 return reg_byte_size;
152 }
153 }
154 // Just write zeros if all else fails
155 for (size_t i=0; i<reg_byte_size; ++ i)
156 data.PutChar(0);
157 return reg_byte_size;
158 }
Jason Molendad20359d2014-11-11 10:59:15 +0000159
Greg Claytona2715cf2014-06-13 00:54:12 +0000160 static bool
161 Create_LC_THREAD (Thread *thread, Stream &data)
162 {
163 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
164 if (reg_ctx_sp)
165 {
166 RegisterContext *reg_ctx = reg_ctx_sp.get();
167
168 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000169 data.PutHex32 (GPRWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000170 WriteRegister (reg_ctx, "rax", NULL, 8, data);
171 WriteRegister (reg_ctx, "rbx", NULL, 8, data);
172 WriteRegister (reg_ctx, "rcx", NULL, 8, data);
173 WriteRegister (reg_ctx, "rdx", NULL, 8, data);
174 WriteRegister (reg_ctx, "rdi", NULL, 8, data);
175 WriteRegister (reg_ctx, "rsi", NULL, 8, data);
176 WriteRegister (reg_ctx, "rbp", NULL, 8, data);
177 WriteRegister (reg_ctx, "rsp", NULL, 8, data);
178 WriteRegister (reg_ctx, "r8", NULL, 8, data);
179 WriteRegister (reg_ctx, "r9", NULL, 8, data);
180 WriteRegister (reg_ctx, "r10", NULL, 8, data);
181 WriteRegister (reg_ctx, "r11", NULL, 8, data);
182 WriteRegister (reg_ctx, "r12", NULL, 8, data);
183 WriteRegister (reg_ctx, "r13", NULL, 8, data);
184 WriteRegister (reg_ctx, "r14", NULL, 8, data);
185 WriteRegister (reg_ctx, "r15", NULL, 8, data);
186 WriteRegister (reg_ctx, "rip", NULL, 8, data);
187 WriteRegister (reg_ctx, "rflags", NULL, 8, data);
188 WriteRegister (reg_ctx, "cs", NULL, 8, data);
189 WriteRegister (reg_ctx, "fs", NULL, 8, data);
190 WriteRegister (reg_ctx, "gs", NULL, 8, data);
191
192// // Write out the FPU registers
193// const size_t fpu_byte_size = sizeof(FPU);
194// size_t bytes_written = 0;
195// data.PutHex32 (FPURegSet);
196// data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
197// bytes_written += data.PutHex32(0); // uint32_t pad[0]
198// bytes_written += data.PutHex32(0); // uint32_t pad[1]
199// bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, data); // uint16_t fcw; // "fctrl"
200// bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, data); // uint16_t fsw; // "fstat"
201// bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, data); // uint8_t ftw; // "ftag"
202// bytes_written += data.PutHex8 (0); // uint8_t pad1;
203// bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, data); // uint16_t fop; // "fop"
204// bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, data); // uint32_t ip; // "fioff"
205// bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, data); // uint16_t cs; // "fiseg"
206// bytes_written += data.PutHex16 (0); // uint16_t pad2;
207// bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, data); // uint32_t dp; // "fooff"
208// bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, data); // uint16_t ds; // "foseg"
209// bytes_written += data.PutHex16 (0); // uint16_t pad3;
210// bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, data); // uint32_t mxcsr;
211// bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, 4, data);// uint32_t mxcsrmask;
212// bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, sizeof(MMSReg), data);
213// bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, sizeof(MMSReg), data);
214// bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, sizeof(MMSReg), data);
215// bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, sizeof(MMSReg), data);
216// bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, sizeof(MMSReg), data);
217// bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, sizeof(MMSReg), data);
218// bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, sizeof(MMSReg), data);
219// bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, sizeof(MMSReg), data);
220// bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, sizeof(XMMReg), data);
221// bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, sizeof(XMMReg), data);
222// bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, sizeof(XMMReg), data);
223// bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, sizeof(XMMReg), data);
224// bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, sizeof(XMMReg), data);
225// bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, sizeof(XMMReg), data);
226// bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, sizeof(XMMReg), data);
227// bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, sizeof(XMMReg), data);
228// bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, sizeof(XMMReg), data);
229// bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, sizeof(XMMReg), data);
230// bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, sizeof(XMMReg), data);
231// bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, sizeof(XMMReg), data);
232// bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, sizeof(XMMReg), data);
233// bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, sizeof(XMMReg), data);
234// bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, sizeof(XMMReg), data);
235// bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, sizeof(XMMReg), data);
236//
237// // Fill rest with zeros
238// for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ i)
239// data.PutChar(0);
240
241 // Write out the EXC registers
242 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000243 data.PutHex32 (EXCWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000244 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
245 WriteRegister (reg_ctx, "err", NULL, 4, data);
246 WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data);
247 return true;
248 }
249 return false;
250 }
251
Greg Claytonc859e2d2012-02-13 23:10:39 +0000252protected:
253 virtual int
254 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
255 {
256 return 0;
257 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000258
Greg Claytonc859e2d2012-02-13 23:10:39 +0000259 virtual int
260 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
261 {
262 return 0;
263 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000264
Greg Claytonc859e2d2012-02-13 23:10:39 +0000265 virtual int
266 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
267 {
268 return 0;
269 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000270
Greg Claytonc859e2d2012-02-13 23:10:39 +0000271 virtual int
272 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
273 {
274 return 0;
275 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000276
Greg Claytonc859e2d2012-02-13 23:10:39 +0000277 virtual int
278 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
279 {
280 return 0;
281 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000282
Greg Claytonc859e2d2012-02-13 23:10:39 +0000283 virtual int
284 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
285 {
286 return 0;
287 }
288};
Greg Claytonc3776bf2012-02-09 06:16:32 +0000289
Greg Claytonc859e2d2012-02-13 23:10:39 +0000290
Jason Molenda4e7511e2013-03-06 23:19:17 +0000291class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
Greg Claytonc859e2d2012-02-13 23:10:39 +0000292{
293public:
294 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
295 RegisterContextDarwin_i386 (thread, 0)
296 {
297 SetRegisterDataFrom_LC_THREAD (data);
298 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000299
Greg Claytonc859e2d2012-02-13 23:10:39 +0000300 virtual void
301 InvalidateAllRegisters ()
302 {
303 // Do nothing... registers are always valid...
304 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000305
Greg Claytonc859e2d2012-02-13 23:10:39 +0000306 void
307 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
308 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000309 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000310 SetError (GPRRegSet, Read, -1);
311 SetError (FPURegSet, Read, -1);
312 SetError (EXCRegSet, Read, -1);
313 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000314
Greg Claytonc859e2d2012-02-13 23:10:39 +0000315 while (!done)
316 {
317 int flavor = data.GetU32 (&offset);
318 if (flavor == 0)
319 done = true;
320 else
Greg Claytonc3776bf2012-02-09 06:16:32 +0000321 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000322 uint32_t i;
323 uint32_t count = data.GetU32 (&offset);
324 switch (flavor)
325 {
326 case GPRRegSet:
327 for (i=0; i<count; ++i)
328 (&gpr.eax)[i] = data.GetU32(&offset);
329 SetError (GPRRegSet, Read, 0);
330 done = true;
331
332 break;
333 case FPURegSet:
334 // TODO: fill in FPU regs....
335 //SetError (FPURegSet, Read, -1);
336 done = true;
337
338 break;
339 case EXCRegSet:
340 exc.trapno = data.GetU32(&offset);
341 exc.err = data.GetU32(&offset);
342 exc.faultvaddr = data.GetU32(&offset);
343 SetError (EXCRegSet, Read, 0);
344 done = true;
345 break;
346 case 7:
347 case 8:
348 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000349 // fancy flavors that encapsulate of the above
350 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000351 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000352
Greg Claytonc859e2d2012-02-13 23:10:39 +0000353 default:
354 done = true;
355 break;
356 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000357 }
358 }
359 }
Jason Molendad20359d2014-11-11 10:59:15 +0000360
361 static size_t
362 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
363 {
364 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
365 if (reg_info == NULL)
366 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
367 if (reg_info)
368 {
369 lldb_private::RegisterValue reg_value;
370 if (reg_ctx->ReadRegister(reg_info, reg_value))
371 {
372 if (reg_info->byte_size >= reg_byte_size)
373 data.Write(reg_value.GetBytes(), reg_byte_size);
374 else
375 {
376 data.Write(reg_value.GetBytes(), reg_info->byte_size);
377 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
378 data.PutChar(0);
379 }
380 return reg_byte_size;
381 }
382 }
383 // Just write zeros if all else fails
384 for (size_t i=0; i<reg_byte_size; ++ i)
385 data.PutChar(0);
386 return reg_byte_size;
387 }
388
389 static bool
390 Create_LC_THREAD (Thread *thread, Stream &data)
391 {
392 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
393 if (reg_ctx_sp)
394 {
395 RegisterContext *reg_ctx = reg_ctx_sp.get();
396
397 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000398 data.PutHex32 (GPRWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000399 WriteRegister (reg_ctx, "eax", NULL, 4, data);
400 WriteRegister (reg_ctx, "ebx", NULL, 4, data);
401 WriteRegister (reg_ctx, "ecx", NULL, 4, data);
402 WriteRegister (reg_ctx, "edx", NULL, 4, data);
403 WriteRegister (reg_ctx, "edi", NULL, 4, data);
404 WriteRegister (reg_ctx, "esi", NULL, 4, data);
405 WriteRegister (reg_ctx, "ebp", NULL, 4, data);
406 WriteRegister (reg_ctx, "esp", NULL, 4, data);
407 WriteRegister (reg_ctx, "ss", NULL, 4, data);
408 WriteRegister (reg_ctx, "eflags", NULL, 4, data);
409 WriteRegister (reg_ctx, "eip", NULL, 4, data);
410 WriteRegister (reg_ctx, "cs", NULL, 4, data);
411 WriteRegister (reg_ctx, "ds", NULL, 4, data);
412 WriteRegister (reg_ctx, "es", NULL, 4, data);
413 WriteRegister (reg_ctx, "fs", NULL, 4, data);
414 WriteRegister (reg_ctx, "gs", NULL, 4, data);
415
416 // Write out the EXC registers
417 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000418 data.PutHex32 (EXCWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000419 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
420 WriteRegister (reg_ctx, "err", NULL, 4, data);
Jason Molenda22952582014-11-12 01:11:36 +0000421 WriteRegister (reg_ctx, "faultvaddr", NULL, 4, data);
Jason Molendad20359d2014-11-11 10:59:15 +0000422 return true;
423 }
424 return false;
425 }
426
Greg Claytonc3776bf2012-02-09 06:16:32 +0000427protected:
428 virtual int
429 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
430 {
431 return 0;
432 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000433
Greg Claytonc3776bf2012-02-09 06:16:32 +0000434 virtual int
435 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
436 {
437 return 0;
438 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000439
Greg Claytonc3776bf2012-02-09 06:16:32 +0000440 virtual int
441 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
442 {
443 return 0;
444 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000445
Greg Claytonc3776bf2012-02-09 06:16:32 +0000446 virtual int
447 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
448 {
449 return 0;
450 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000451
Greg Claytonc3776bf2012-02-09 06:16:32 +0000452 virtual int
453 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
454 {
455 return 0;
456 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000457
Greg Claytonc3776bf2012-02-09 06:16:32 +0000458 virtual int
459 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
460 {
461 return 0;
462 }
463};
464
Jason Molenda4e7511e2013-03-06 23:19:17 +0000465class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000466{
467public:
468 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
Greg Claytonc2807462012-10-30 23:57:32 +0000469 RegisterContextDarwin_arm (thread, 0)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000470 {
471 SetRegisterDataFrom_LC_THREAD (data);
472 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000473
Greg Claytonc859e2d2012-02-13 23:10:39 +0000474 virtual void
475 InvalidateAllRegisters ()
476 {
477 // Do nothing... registers are always valid...
478 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000479
Greg Claytonc859e2d2012-02-13 23:10:39 +0000480 void
481 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
482 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000483 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000484 SetError (GPRRegSet, Read, -1);
485 SetError (FPURegSet, Read, -1);
486 SetError (EXCRegSet, Read, -1);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000487 bool done = false;
488
489 while (!done)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000490 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000491 int flavor = data.GetU32 (&offset);
492 uint32_t count = data.GetU32 (&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000493 lldb::offset_t next_thread_state = offset + (count * 4);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000494 switch (flavor)
495 {
496 case GPRRegSet:
497 for (uint32_t i=0; i<count; ++i)
Jason Molendaddf91772013-05-14 04:50:47 +0000498 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000499 gpr.r[i] = data.GetU32(&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000500 }
501
502 // Note that gpr.cpsr is also copied by the above loop; this loop technically extends
503 // one element past the end of the gpr.r[] array.
504
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000505 SetError (GPRRegSet, Read, 0);
Jason Molendaddf91772013-05-14 04:50:47 +0000506 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000507 break;
508
509 case FPURegSet:
510 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000511 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0];
512 const int fpu_reg_buf_size = sizeof (fpu.floats);
513 if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000514 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000515 offset += fpu_reg_buf_size;
516 fpu.fpscr = data.GetU32(&offset);
517 SetError (FPURegSet, Read, 0);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000518 }
Jason Molenda663d2e12013-05-14 03:52:22 +0000519 else
520 {
521 done = true;
522 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000523 }
Jason Molendaddf91772013-05-14 04:50:47 +0000524 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000525 break;
526
527 case EXCRegSet:
Jason Molendaddf91772013-05-14 04:50:47 +0000528 if (count == 3)
529 {
530 exc.exception = data.GetU32(&offset);
531 exc.fsr = data.GetU32(&offset);
532 exc.far = data.GetU32(&offset);
533 SetError (EXCRegSet, Read, 0);
534 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000535 done = true;
Jason Molendaddf91772013-05-14 04:50:47 +0000536 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000537 break;
538
539 // Unknown register set flavor, stop trying to parse.
540 default:
541 done = true;
542 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000543 }
544 }
Jason Molenda22952582014-11-12 01:11:36 +0000545
546 static size_t
547 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
548 {
549 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
550 if (reg_info == NULL)
551 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
552 if (reg_info)
553 {
554 lldb_private::RegisterValue reg_value;
555 if (reg_ctx->ReadRegister(reg_info, reg_value))
556 {
557 if (reg_info->byte_size >= reg_byte_size)
558 data.Write(reg_value.GetBytes(), reg_byte_size);
559 else
560 {
561 data.Write(reg_value.GetBytes(), reg_info->byte_size);
562 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
563 data.PutChar(0);
564 }
565 return reg_byte_size;
566 }
567 }
568 // Just write zeros if all else fails
569 for (size_t i=0; i<reg_byte_size; ++ i)
570 data.PutChar(0);
571 return reg_byte_size;
572 }
573
574 static bool
575 Create_LC_THREAD (Thread *thread, Stream &data)
576 {
577 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
578 if (reg_ctx_sp)
579 {
580 RegisterContext *reg_ctx = reg_ctx_sp.get();
581
582 data.PutHex32 (GPRRegSet); // Flavor
583 data.PutHex32 (GPRWordCount);
584 WriteRegister (reg_ctx, "r0", NULL, 4, data);
585 WriteRegister (reg_ctx, "r1", NULL, 4, data);
586 WriteRegister (reg_ctx, "r2", NULL, 4, data);
587 WriteRegister (reg_ctx, "r3", NULL, 4, data);
588 WriteRegister (reg_ctx, "r4", NULL, 4, data);
589 WriteRegister (reg_ctx, "r5", NULL, 4, data);
590 WriteRegister (reg_ctx, "r6", NULL, 4, data);
591 WriteRegister (reg_ctx, "r7", NULL, 4, data);
592 WriteRegister (reg_ctx, "r8", NULL, 4, data);
593 WriteRegister (reg_ctx, "r9", NULL, 4, data);
594 WriteRegister (reg_ctx, "r10", NULL, 4, data);
595 WriteRegister (reg_ctx, "r11", NULL, 4, data);
596 WriteRegister (reg_ctx, "r12", NULL, 4, data);
597 WriteRegister (reg_ctx, "sp", NULL, 4, data);
598 WriteRegister (reg_ctx, "lr", NULL, 4, data);
599 WriteRegister (reg_ctx, "pc", NULL, 4, data);
600 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
601
602 // Write out the EXC registers
603// data.PutHex32 (EXCRegSet);
604// data.PutHex32 (EXCWordCount);
605// WriteRegister (reg_ctx, "exception", NULL, 4, data);
606// WriteRegister (reg_ctx, "fsr", NULL, 4, data);
607// WriteRegister (reg_ctx, "far", NULL, 4, data);
608 return true;
609 }
610 return false;
611 }
612
Greg Claytonc859e2d2012-02-13 23:10:39 +0000613protected:
614 virtual int
615 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
616 {
Jason Molendaddf91772013-05-14 04:50:47 +0000617 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000618 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000619
Greg Claytonc859e2d2012-02-13 23:10:39 +0000620 virtual int
621 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
622 {
Jason Molendaddf91772013-05-14 04:50:47 +0000623 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000624 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000625
Greg Claytonc859e2d2012-02-13 23:10:39 +0000626 virtual int
627 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
628 {
Jason Molendaddf91772013-05-14 04:50:47 +0000629 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000630 }
Greg Claytonc2807462012-10-30 23:57:32 +0000631
632 virtual int
633 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
634 {
635 return -1;
636 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000637
Greg Claytonc859e2d2012-02-13 23:10:39 +0000638 virtual int
639 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
640 {
641 return 0;
642 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000643
Greg Claytonc859e2d2012-02-13 23:10:39 +0000644 virtual int
645 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
646 {
647 return 0;
648 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000649
Greg Claytonc859e2d2012-02-13 23:10:39 +0000650 virtual int
651 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
652 {
653 return 0;
654 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000655
Greg Claytonc2807462012-10-30 23:57:32 +0000656 virtual int
657 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
658 {
659 return -1;
660 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000661};
662
Jason Molendaa3329782014-03-29 18:54:20 +0000663class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
664{
665public:
666 RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
667 RegisterContextDarwin_arm64 (thread, 0)
668 {
669 SetRegisterDataFrom_LC_THREAD (data);
670 }
671
672 virtual void
673 InvalidateAllRegisters ()
674 {
675 // Do nothing... registers are always valid...
676 }
677
678 void
679 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
680 {
681 lldb::offset_t offset = 0;
682 SetError (GPRRegSet, Read, -1);
683 SetError (FPURegSet, Read, -1);
684 SetError (EXCRegSet, Read, -1);
685 bool done = false;
686 while (!done)
687 {
688 int flavor = data.GetU32 (&offset);
689 uint32_t count = data.GetU32 (&offset);
690 lldb::offset_t next_thread_state = offset + (count * 4);
691 switch (flavor)
692 {
693 case GPRRegSet:
694 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
695 if (count >= (33 * 2) + 1)
696 {
697 for (uint32_t i=0; i<33; ++i)
698 gpr.x[i] = data.GetU64(&offset);
699 gpr.cpsr = data.GetU32(&offset);
700 SetError (GPRRegSet, Read, 0);
701 }
702 offset = next_thread_state;
703 break;
704 case FPURegSet:
705 {
706 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
707 const int fpu_reg_buf_size = sizeof (fpu);
708 if (fpu_reg_buf_size == count
709 && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
710 {
711 SetError (FPURegSet, Read, 0);
712 }
713 else
714 {
715 done = true;
716 }
717 }
718 offset = next_thread_state;
719 break;
720 case EXCRegSet:
721 if (count == 4)
722 {
723 exc.far = data.GetU64(&offset);
724 exc.esr = data.GetU32(&offset);
725 exc.exception = data.GetU32(&offset);
726 SetError (EXCRegSet, Read, 0);
727 }
728 offset = next_thread_state;
729 break;
730 default:
731 done = true;
732 break;
733 }
734 }
735 }
Jason Molenda22952582014-11-12 01:11:36 +0000736
737 static size_t
738 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
739 {
740 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
741 if (reg_info == NULL)
742 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
743 if (reg_info)
744 {
745 lldb_private::RegisterValue reg_value;
746 if (reg_ctx->ReadRegister(reg_info, reg_value))
747 {
748 if (reg_info->byte_size >= reg_byte_size)
749 data.Write(reg_value.GetBytes(), reg_byte_size);
750 else
751 {
752 data.Write(reg_value.GetBytes(), reg_info->byte_size);
753 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
754 data.PutChar(0);
755 }
756 return reg_byte_size;
757 }
758 }
759 // Just write zeros if all else fails
760 for (size_t i=0; i<reg_byte_size; ++ i)
761 data.PutChar(0);
762 return reg_byte_size;
763 }
764
765 static bool
766 Create_LC_THREAD (Thread *thread, Stream &data)
767 {
768 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
769 if (reg_ctx_sp)
770 {
771 RegisterContext *reg_ctx = reg_ctx_sp.get();
772
773 data.PutHex32 (GPRRegSet); // Flavor
774 data.PutHex32 (GPRWordCount);
775 WriteRegister (reg_ctx, "x0", NULL, 8, data);
776 WriteRegister (reg_ctx, "x1", NULL, 8, data);
777 WriteRegister (reg_ctx, "x2", NULL, 8, data);
778 WriteRegister (reg_ctx, "x3", NULL, 8, data);
779 WriteRegister (reg_ctx, "x4", NULL, 8, data);
780 WriteRegister (reg_ctx, "x5", NULL, 8, data);
781 WriteRegister (reg_ctx, "x6", NULL, 8, data);
782 WriteRegister (reg_ctx, "x7", NULL, 8, data);
783 WriteRegister (reg_ctx, "x8", NULL, 8, data);
784 WriteRegister (reg_ctx, "x9", NULL, 8, data);
785 WriteRegister (reg_ctx, "x10", NULL, 8, data);
786 WriteRegister (reg_ctx, "x11", NULL, 8, data);
787 WriteRegister (reg_ctx, "x12", NULL, 8, data);
788 WriteRegister (reg_ctx, "x13", NULL, 8, data);
789 WriteRegister (reg_ctx, "x14", NULL, 8, data);
790 WriteRegister (reg_ctx, "x15", NULL, 8, data);
791 WriteRegister (reg_ctx, "x16", NULL, 8, data);
792 WriteRegister (reg_ctx, "x17", NULL, 8, data);
793 WriteRegister (reg_ctx, "x18", NULL, 8, data);
794 WriteRegister (reg_ctx, "x19", NULL, 8, data);
795 WriteRegister (reg_ctx, "x20", NULL, 8, data);
796 WriteRegister (reg_ctx, "x21", NULL, 8, data);
797 WriteRegister (reg_ctx, "x22", NULL, 8, data);
798 WriteRegister (reg_ctx, "x23", NULL, 8, data);
799 WriteRegister (reg_ctx, "x24", NULL, 8, data);
800 WriteRegister (reg_ctx, "x25", NULL, 8, data);
801 WriteRegister (reg_ctx, "x26", NULL, 8, data);
802 WriteRegister (reg_ctx, "x27", NULL, 8, data);
803 WriteRegister (reg_ctx, "x28", NULL, 8, data);
804 WriteRegister (reg_ctx, "fp", NULL, 8, data);
805 WriteRegister (reg_ctx, "lr", NULL, 8, data);
806 WriteRegister (reg_ctx, "sp", NULL, 8, data);
807 WriteRegister (reg_ctx, "pc", NULL, 8, data);
808 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
809
810 // Write out the EXC registers
811// data.PutHex32 (EXCRegSet);
812// data.PutHex32 (EXCWordCount);
813// WriteRegister (reg_ctx, "far", NULL, 8, data);
814// WriteRegister (reg_ctx, "esr", NULL, 4, data);
815// WriteRegister (reg_ctx, "exception", NULL, 4, data);
816 return true;
817 }
818 return false;
819 }
820
Jason Molendaa3329782014-03-29 18:54:20 +0000821protected:
822 virtual int
823 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
824 {
825 return -1;
826 }
827
828 virtual int
829 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
830 {
831 return -1;
832 }
833
834 virtual int
835 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
836 {
837 return -1;
838 }
839
840 virtual int
841 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
842 {
843 return -1;
844 }
845
846 virtual int
847 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
848 {
849 return 0;
850 }
851
852 virtual int
853 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
854 {
855 return 0;
856 }
857
858 virtual int
859 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
860 {
861 return 0;
862 }
863
864 virtual int
865 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
866 {
867 return -1;
868 }
869};
870
Greg Clayton9aae0a12013-05-15 19:52:08 +0000871static uint32_t
872MachHeaderSizeFromMagic(uint32_t magic)
873{
874 switch (magic)
875 {
Charles Davis510938e2013-08-27 05:04:57 +0000876 case MH_MAGIC:
877 case MH_CIGAM:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000878 return sizeof(struct mach_header);
879
Charles Davis510938e2013-08-27 05:04:57 +0000880 case MH_MAGIC_64:
881 case MH_CIGAM_64:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000882 return sizeof(struct mach_header_64);
883 break;
884
885 default:
886 break;
887 }
888 return 0;
889}
890
Greg Claytonded470d2011-03-19 01:12:21 +0000891#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892
893void
894ObjectFileMachO::Initialize()
895{
896 PluginManager::RegisterPlugin (GetPluginNameStatic(),
897 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000898 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000899 CreateMemoryInstance,
Greg Claytona2715cf2014-06-13 00:54:12 +0000900 GetModuleSpecifications,
901 SaveCore);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000902}
903
904void
905ObjectFileMachO::Terminate()
906{
907 PluginManager::UnregisterPlugin (CreateInstance);
908}
909
910
Greg Clayton57abc5d2013-05-10 21:47:16 +0000911lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000912ObjectFileMachO::GetPluginNameStatic()
913{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000914 static ConstString g_name("mach-o");
915 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916}
917
918const char *
919ObjectFileMachO::GetPluginDescriptionStatic()
920{
921 return "Mach-o object file reader (32 and 64 bit)";
922}
923
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924ObjectFile *
Greg Clayton5ce9c562013-02-06 17:22:03 +0000925ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
926 DataBufferSP& data_sp,
927 lldb::offset_t data_offset,
928 const FileSpec* file,
929 lldb::offset_t file_offset,
930 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000932 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000933 {
Greg Clayton736888c2015-02-23 23:47:09 +0000934 data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
Greg Clayton5ce9c562013-02-06 17:22:03 +0000935 data_offset = 0;
936 }
937
938 if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
939 {
940 // Update the data to contain the entire file if it doesn't already
941 if (data_sp->GetByteSize() < length)
942 {
Greg Clayton736888c2015-02-23 23:47:09 +0000943 data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
Greg Clayton5ce9c562013-02-06 17:22:03 +0000944 data_offset = 0;
945 }
Greg Clayton7b0992d2013-04-18 22:45:39 +0000946 std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000947 if (objfile_ap.get() && objfile_ap->ParseHeader())
948 return objfile_ap.release();
949 }
950 return NULL;
951}
952
Greg Claytonc9660542012-02-05 02:38:54 +0000953ObjectFile *
Jason Molenda4e7511e2013-03-06 23:19:17 +0000954ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
955 DataBufferSP& data_sp,
956 const ProcessSP &process_sp,
Greg Claytonc9660542012-02-05 02:38:54 +0000957 lldb::addr_t header_addr)
958{
959 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
960 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000961 std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonc9660542012-02-05 02:38:54 +0000962 if (objfile_ap.get() && objfile_ap->ParseHeader())
963 return objfile_ap.release();
964 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000965 return NULL;
Greg Claytonc9660542012-02-05 02:38:54 +0000966}
967
Greg Claytonf4d6de62013-04-24 22:29:28 +0000968size_t
969ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
970 lldb::DataBufferSP& data_sp,
971 lldb::offset_t data_offset,
972 lldb::offset_t file_offset,
973 lldb::offset_t length,
974 lldb_private::ModuleSpecList &specs)
975{
976 const size_t initial_count = specs.GetSize();
977
978 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
979 {
980 DataExtractor data;
981 data.SetData(data_sp);
982 llvm::MachO::mach_header header;
983 if (ParseHeader (data, &data_offset, header))
984 {
Jason Molenda48cd3332014-04-22 04:52:30 +0000985 size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
986 if (header_and_load_cmds >= data_sp->GetByteSize())
Greg Claytonf4d6de62013-04-24 22:29:28 +0000987 {
Jason Molenda48cd3332014-04-22 04:52:30 +0000988 data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);
Greg Clayton2540a8a2013-07-12 22:07:46 +0000989 data.SetData(data_sp);
990 data_offset = MachHeaderSizeFromMagic(header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000991 }
992 if (data_sp)
993 {
994 ModuleSpec spec;
995 spec.GetFileSpec() = file;
Greg Clayton7ab7f892014-05-29 21:33:45 +0000996 spec.SetObjectOffset(file_offset);
Oleksiy Vyalov63acdfd2015-03-10 01:15:28 +0000997 spec.SetObjectSize(length);
998
Greg Clayton7ab7f892014-05-29 21:33:45 +0000999 if (GetArchitecture (header, data, data_offset, spec.GetArchitecture()))
Jason Molendab000e4d2013-08-27 02:22:06 +00001000 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001001 if (spec.GetArchitecture().IsValid())
1002 {
1003 GetUUID (header, data, data_offset, spec.GetUUID());
1004 specs.Append(spec);
1005 }
Greg Claytonf4d6de62013-04-24 22:29:28 +00001006 }
1007 }
1008 }
1009 }
1010 return specs.GetSize() - initial_count;
1011}
1012
1013
Greg Claytonc9660542012-02-05 02:38:54 +00001014
1015const ConstString &
1016ObjectFileMachO::GetSegmentNameTEXT()
1017{
1018 static ConstString g_segment_name_TEXT ("__TEXT");
1019 return g_segment_name_TEXT;
1020}
1021
1022const ConstString &
1023ObjectFileMachO::GetSegmentNameDATA()
1024{
1025 static ConstString g_segment_name_DATA ("__DATA");
1026 return g_segment_name_DATA;
1027}
1028
1029const ConstString &
Greg Claytona381e102015-07-27 23:21:05 +00001030ObjectFileMachO::GetSegmentNameDATA_DIRTY()
1031{
1032 static ConstString g_segment_name ("__DATA_DIRTY");
1033 return g_segment_name;
1034}
1035
1036const ConstString &
1037ObjectFileMachO::GetSegmentNameDATA_CONST()
1038{
1039 static ConstString g_segment_name ("__DATA_CONST");
1040 return g_segment_name;
1041}
1042
1043const ConstString &
Greg Claytonc9660542012-02-05 02:38:54 +00001044ObjectFileMachO::GetSegmentNameOBJC()
1045{
1046 static ConstString g_segment_name_OBJC ("__OBJC");
1047 return g_segment_name_OBJC;
1048}
1049
1050const ConstString &
1051ObjectFileMachO::GetSegmentNameLINKEDIT()
1052{
1053 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
1054 return g_section_name_LINKEDIT;
1055}
1056
1057const ConstString &
1058ObjectFileMachO::GetSectionNameEHFrame()
1059{
1060 static ConstString g_section_name_eh_frame ("__eh_frame");
1061 return g_section_name_eh_frame;
1062}
1063
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001064bool
Jason Molenda4e7511e2013-03-06 23:19:17 +00001065ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
1066 lldb::addr_t data_offset,
Greg Clayton44435ed2012-01-12 05:25:17 +00001067 lldb::addr_t data_length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068{
Greg Clayton44435ed2012-01-12 05:25:17 +00001069 DataExtractor data;
1070 data.SetData (data_sp, data_offset, data_length);
Greg Claytonc7bece562013-01-25 18:06:21 +00001071 lldb::offset_t offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072 uint32_t magic = data.GetU32(&offset);
1073 return MachHeaderSizeFromMagic(magic) != 0;
1074}
1075
1076
Greg Clayton5ce9c562013-02-06 17:22:03 +00001077ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
1078 DataBufferSP& data_sp,
1079 lldb::offset_t data_offset,
1080 const FileSpec* file,
1081 lldb::offset_t file_offset,
1082 lldb::offset_t length) :
1083 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001084 m_mach_segments(),
1085 m_mach_sections(),
1086 m_entry_point_address(),
1087 m_thread_context_offsets(),
1088 m_thread_context_offsets_valid(false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089{
Greg Clayton72b77eb2011-02-04 21:13:05 +00001090 ::memset (&m_header, 0, sizeof(m_header));
1091 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001092}
1093
Greg Claytone72dfb32012-02-24 01:59:29 +00001094ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonc9660542012-02-05 02:38:54 +00001095 lldb::DataBufferSP& header_data_sp,
1096 const lldb::ProcessSP &process_sp,
1097 lldb::addr_t header_addr) :
Greg Claytone72dfb32012-02-24 01:59:29 +00001098 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001099 m_mach_segments(),
1100 m_mach_sections(),
1101 m_entry_point_address(),
1102 m_thread_context_offsets(),
1103 m_thread_context_offsets_valid(false)
Greg Claytonc9660542012-02-05 02:38:54 +00001104{
1105 ::memset (&m_header, 0, sizeof(m_header));
1106 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1107}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001108
1109ObjectFileMachO::~ObjectFileMachO()
1110{
1111}
1112
Greg Claytonf4d6de62013-04-24 22:29:28 +00001113bool
1114ObjectFileMachO::ParseHeader (DataExtractor &data,
1115 lldb::offset_t *data_offset_ptr,
1116 llvm::MachO::mach_header &header)
1117{
1118 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1119 // Leave magic in the original byte order
1120 header.magic = data.GetU32(data_offset_ptr);
1121 bool can_parse = false;
1122 bool is_64_bit = false;
1123 switch (header.magic)
1124 {
Charles Davis510938e2013-08-27 05:04:57 +00001125 case MH_MAGIC:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001126 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1127 data.SetAddressByteSize(4);
1128 can_parse = true;
1129 break;
1130
Charles Davis510938e2013-08-27 05:04:57 +00001131 case MH_MAGIC_64:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001132 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1133 data.SetAddressByteSize(8);
1134 can_parse = true;
1135 is_64_bit = true;
1136 break;
1137
Charles Davis510938e2013-08-27 05:04:57 +00001138 case MH_CIGAM:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001139 data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1140 data.SetAddressByteSize(4);
1141 can_parse = true;
1142 break;
1143
Charles Davis510938e2013-08-27 05:04:57 +00001144 case MH_CIGAM_64:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001145 data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1146 data.SetAddressByteSize(8);
1147 is_64_bit = true;
1148 can_parse = true;
1149 break;
1150
1151 default:
1152 break;
1153 }
1154
1155 if (can_parse)
1156 {
1157 data.GetU32(data_offset_ptr, &header.cputype, 6);
1158 if (is_64_bit)
1159 *data_offset_ptr += 4;
1160 return true;
1161 }
1162 else
1163 {
1164 memset(&header, 0, sizeof(header));
1165 }
1166 return false;
1167}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001168
1169bool
1170ObjectFileMachO::ParseHeader ()
1171{
Greg Claytona1743492012-03-13 23:14:29 +00001172 ModuleSP module_sp(GetModule());
1173 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174 {
Greg Claytona1743492012-03-13 23:14:29 +00001175 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1176 bool can_parse = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00001177 lldb::offset_t offset = 0;
Greg Clayton7fb56d02011-02-01 01:31:41 +00001178 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001179 // Leave magic in the original byte order
1180 m_header.magic = m_data.GetU32(&offset);
1181 switch (m_header.magic)
Greg Claytonc9660542012-02-05 02:38:54 +00001182 {
Charles Davis510938e2013-08-27 05:04:57 +00001183 case MH_MAGIC:
Greg Claytona1743492012-03-13 23:14:29 +00001184 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
1185 m_data.SetAddressByteSize(4);
1186 can_parse = true;
1187 break;
1188
Charles Davis510938e2013-08-27 05:04:57 +00001189 case MH_MAGIC_64:
Greg Claytona1743492012-03-13 23:14:29 +00001190 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
1191 m_data.SetAddressByteSize(8);
1192 can_parse = true;
1193 break;
1194
Charles Davis510938e2013-08-27 05:04:57 +00001195 case MH_CIGAM:
Greg Claytona1743492012-03-13 23:14:29 +00001196 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1197 m_data.SetAddressByteSize(4);
1198 can_parse = true;
1199 break;
1200
Charles Davis510938e2013-08-27 05:04:57 +00001201 case MH_CIGAM_64:
Greg Claytona1743492012-03-13 23:14:29 +00001202 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1203 m_data.SetAddressByteSize(8);
1204 can_parse = true;
1205 break;
1206
1207 default:
1208 break;
Greg Claytonc9660542012-02-05 02:38:54 +00001209 }
Greg Claytona1743492012-03-13 23:14:29 +00001210
1211 if (can_parse)
1212 {
1213 m_data.GetU32(&offset, &m_header.cputype, 6);
1214
Greg Clayton7ab7f892014-05-29 21:33:45 +00001215
1216 ArchSpec mach_arch;
1217
1218 if (GetArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001219 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001220 // Check if the module has a required architecture
1221 const ArchSpec &module_arch = module_sp->GetArchitecture();
1222 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
1223 return false;
1224
1225 if (SetModulesArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001226 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001227 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
1228 if (m_data.GetByteSize() < header_and_lc_size)
Greg Claytona1743492012-03-13 23:14:29 +00001229 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001230 DataBufferSP data_sp;
1231 ProcessSP process_sp (m_process_wp.lock());
1232 if (process_sp)
1233 {
1234 data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
1235 }
1236 else
1237 {
1238 // Read in all only the load command data from the file on disk
1239 data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
1240 if (data_sp->GetByteSize() != header_and_lc_size)
1241 return false;
1242 }
1243 if (data_sp)
1244 m_data.SetData (data_sp);
Greg Claytona1743492012-03-13 23:14:29 +00001245 }
Greg Claytona1743492012-03-13 23:14:29 +00001246 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00001247 return true;
Greg Claytona1743492012-03-13 23:14:29 +00001248 }
Greg Claytona1743492012-03-13 23:14:29 +00001249 }
1250 else
1251 {
1252 memset(&m_header, 0, sizeof(struct mach_header));
1253 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001254 }
1255 return false;
1256}
1257
1258
1259ByteOrder
1260ObjectFileMachO::GetByteOrder () const
1261{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 return m_data.GetByteOrder ();
1263}
1264
Jim Ingham5aee1622010-08-09 23:31:02 +00001265bool
1266ObjectFileMachO::IsExecutable() const
1267{
Charles Davis510938e2013-08-27 05:04:57 +00001268 return m_header.filetype == MH_EXECUTE;
Jim Ingham5aee1622010-08-09 23:31:02 +00001269}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001270
Greg Claytonc7bece562013-01-25 18:06:21 +00001271uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001272ObjectFileMachO::GetAddressByteSize () const
1273{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001274 return m_data.GetAddressByteSize ();
1275}
1276
Greg Claytone0d378b2011-03-24 21:19:54 +00001277AddressClass
Greg Claytonded470d2011-03-19 01:12:21 +00001278ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
1279{
1280 Symtab *symtab = GetSymtab();
1281 if (symtab)
1282 {
1283 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
1284 if (symbol)
1285 {
Greg Claytone7612132012-03-07 21:03:09 +00001286 if (symbol->ValueIsAddress())
Greg Claytonded470d2011-03-19 01:12:21 +00001287 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00001288 SectionSP section_sp (symbol->GetAddressRef().GetSection());
Greg Claytone72dfb32012-02-24 01:59:29 +00001289 if (section_sp)
Greg Claytonded470d2011-03-19 01:12:21 +00001290 {
Charles Davis510938e2013-08-27 05:04:57 +00001291 const lldb::SectionType section_type = section_sp->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001292 switch (section_type)
1293 {
Jason Molendae589e7e2014-12-08 03:09:00 +00001294 case eSectionTypeInvalid:
1295 return eAddressClassUnknown;
1296
Greg Claytonded470d2011-03-19 01:12:21 +00001297 case eSectionTypeCode:
Charles Davis510938e2013-08-27 05:04:57 +00001298 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001299 {
1300 // For ARM we have a bit in the n_desc field of the symbol
1301 // that tells us ARM/Thumb which is bit 0x0008.
1302 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1303 return eAddressClassCodeAlternateISA;
1304 }
1305 return eAddressClassCode;
1306
Jason Molendae589e7e2014-12-08 03:09:00 +00001307 case eSectionTypeContainer:
1308 return eAddressClassUnknown;
1309
Greg Clayton5009f9d2011-10-27 17:55:14 +00001310 case eSectionTypeData:
1311 case eSectionTypeDataCString:
1312 case eSectionTypeDataCStringPointers:
1313 case eSectionTypeDataSymbolAddress:
1314 case eSectionTypeData4:
1315 case eSectionTypeData8:
1316 case eSectionTypeData16:
1317 case eSectionTypeDataPointers:
1318 case eSectionTypeZeroFill:
1319 case eSectionTypeDataObjCMessageRefs:
1320 case eSectionTypeDataObjCCFStrings:
1321 return eAddressClassData;
Jason Molendae589e7e2014-12-08 03:09:00 +00001322
Greg Clayton5009f9d2011-10-27 17:55:14 +00001323 case eSectionTypeDebug:
1324 case eSectionTypeDWARFDebugAbbrev:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001325 case eSectionTypeDWARFDebugAddr:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001326 case eSectionTypeDWARFDebugAranges:
1327 case eSectionTypeDWARFDebugFrame:
1328 case eSectionTypeDWARFDebugInfo:
1329 case eSectionTypeDWARFDebugLine:
1330 case eSectionTypeDWARFDebugLoc:
1331 case eSectionTypeDWARFDebugMacInfo:
1332 case eSectionTypeDWARFDebugPubNames:
1333 case eSectionTypeDWARFDebugPubTypes:
1334 case eSectionTypeDWARFDebugRanges:
1335 case eSectionTypeDWARFDebugStr:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001336 case eSectionTypeDWARFDebugStrOffsets:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001337 case eSectionTypeDWARFAppleNames:
1338 case eSectionTypeDWARFAppleTypes:
1339 case eSectionTypeDWARFAppleNamespaces:
1340 case eSectionTypeDWARFAppleObjC:
1341 return eAddressClassDebug;
Jason Molendae589e7e2014-12-08 03:09:00 +00001342
1343 case eSectionTypeEHFrame:
1344 case eSectionTypeCompactUnwind:
1345 return eAddressClassRuntime;
1346
Michael Sartaina7499c92013-07-01 19:45:50 +00001347 case eSectionTypeELFSymbolTable:
1348 case eSectionTypeELFDynamicSymbols:
1349 case eSectionTypeELFRelocationEntries:
1350 case eSectionTypeELFDynamicLinkInfo:
Jason Molendae589e7e2014-12-08 03:09:00 +00001351 case eSectionTypeOther:
1352 return eAddressClassUnknown;
Greg Claytonded470d2011-03-19 01:12:21 +00001353 }
1354 }
1355 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001356
Greg Claytone0d378b2011-03-24 21:19:54 +00001357 const SymbolType symbol_type = symbol->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001358 switch (symbol_type)
1359 {
1360 case eSymbolTypeAny: return eAddressClassUnknown;
1361 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Jason Molenda4e7511e2013-03-06 23:19:17 +00001362
Greg Claytonded470d2011-03-19 01:12:21 +00001363 case eSymbolTypeCode:
1364 case eSymbolTypeTrampoline:
Greg Clayton059f7242013-02-27 21:16:04 +00001365 case eSymbolTypeResolver:
Charles Davis510938e2013-08-27 05:04:57 +00001366 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001367 {
1368 // For ARM we have a bit in the n_desc field of the symbol
1369 // that tells us ARM/Thumb which is bit 0x0008.
1370 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1371 return eAddressClassCodeAlternateISA;
1372 }
1373 return eAddressClassCode;
1374
1375 case eSymbolTypeData: return eAddressClassData;
1376 case eSymbolTypeRuntime: return eAddressClassRuntime;
1377 case eSymbolTypeException: return eAddressClassRuntime;
1378 case eSymbolTypeSourceFile: return eAddressClassDebug;
1379 case eSymbolTypeHeaderFile: return eAddressClassDebug;
1380 case eSymbolTypeObjectFile: return eAddressClassDebug;
1381 case eSymbolTypeCommonBlock: return eAddressClassDebug;
1382 case eSymbolTypeBlock: return eAddressClassDebug;
1383 case eSymbolTypeLocal: return eAddressClassData;
1384 case eSymbolTypeParam: return eAddressClassData;
1385 case eSymbolTypeVariable: return eAddressClassData;
1386 case eSymbolTypeVariableType: return eAddressClassDebug;
1387 case eSymbolTypeLineEntry: return eAddressClassDebug;
1388 case eSymbolTypeLineHeader: return eAddressClassDebug;
1389 case eSymbolTypeScopeBegin: return eAddressClassDebug;
1390 case eSymbolTypeScopeEnd: return eAddressClassDebug;
1391 case eSymbolTypeAdditional: return eAddressClassUnknown;
1392 case eSymbolTypeCompiler: return eAddressClassDebug;
1393 case eSymbolTypeInstrumentation:return eAddressClassDebug;
1394 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton456809c2011-12-03 02:30:59 +00001395 case eSymbolTypeObjCClass: return eAddressClassRuntime;
1396 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
1397 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Clayton9191db42013-10-21 18:40:51 +00001398 case eSymbolTypeReExported: return eAddressClassRuntime;
Greg Claytonded470d2011-03-19 01:12:21 +00001399 }
1400 }
1401 }
1402 return eAddressClassUnknown;
1403}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404
1405Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001406ObjectFileMachO::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001407{
Greg Claytona1743492012-03-13 23:14:29 +00001408 ModuleSP module_sp(GetModule());
1409 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001410 {
Greg Claytona1743492012-03-13 23:14:29 +00001411 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1412 if (m_symtab_ap.get() == NULL)
1413 {
1414 m_symtab_ap.reset(new Symtab(this));
1415 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
Greg Clayton3046e662013-07-10 01:23:25 +00001416 ParseSymtab ();
Greg Claytona1743492012-03-13 23:14:29 +00001417 m_symtab_ap->Finalize ();
1418 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001419 }
1420 return m_symtab_ap.get();
1421}
1422
Greg Clayton3046e662013-07-10 01:23:25 +00001423bool
1424ObjectFileMachO::IsStripped ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001425{
Greg Clayton3046e662013-07-10 01:23:25 +00001426 if (m_dysymtab.cmd == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001427 {
Greg Clayton3046e662013-07-10 01:23:25 +00001428 ModuleSP module_sp(GetModule());
1429 if (module_sp)
Greg Claytona1743492012-03-13 23:14:29 +00001430 {
Greg Clayton3046e662013-07-10 01:23:25 +00001431 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1432 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton4d78c402012-05-25 18:09:55 +00001433 {
Greg Clayton3046e662013-07-10 01:23:25 +00001434 const lldb::offset_t load_cmd_offset = offset;
1435
1436 load_command lc;
1437 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
1438 break;
Charles Davis510938e2013-08-27 05:04:57 +00001439 if (lc.cmd == LC_DYSYMTAB)
Greg Clayton4d78c402012-05-25 18:09:55 +00001440 {
Greg Clayton3046e662013-07-10 01:23:25 +00001441 m_dysymtab.cmd = lc.cmd;
1442 m_dysymtab.cmdsize = lc.cmdsize;
1443 if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
1444 {
1445 // Clear m_dysymtab if we were unable to read all items from the load command
1446 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1447 }
Greg Clayton4d78c402012-05-25 18:09:55 +00001448 }
Greg Clayton3046e662013-07-10 01:23:25 +00001449 offset = load_cmd_offset + lc.cmdsize;
Greg Clayton4d78c402012-05-25 18:09:55 +00001450 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001451 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001452 }
Greg Clayton3046e662013-07-10 01:23:25 +00001453 if (m_dysymtab.cmd)
Greg Clayton93e28612013-10-11 22:03:48 +00001454 return m_dysymtab.nlocalsym <= 1;
Greg Clayton3046e662013-07-10 01:23:25 +00001455 return false;
1456}
Greg Clayton1eac0c72012-04-24 03:06:13 +00001457
Greg Clayton3046e662013-07-10 01:23:25 +00001458void
1459ObjectFileMachO::CreateSections (SectionList &unified_section_list)
1460{
1461 if (!m_sections_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001462 {
Greg Clayton3046e662013-07-10 01:23:25 +00001463 m_sections_ap.reset(new SectionList());
1464
Charles Davis510938e2013-08-27 05:04:57 +00001465 const bool is_dsym = (m_header.filetype == MH_DSYM);
Greg Clayton3046e662013-07-10 01:23:25 +00001466 lldb::user_id_t segID = 0;
1467 lldb::user_id_t sectID = 0;
1468 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1469 uint32_t i;
1470 const bool is_core = GetType() == eTypeCoreFile;
1471 //bool dump_sections = false;
1472 ModuleSP module_sp (GetModule());
1473 // First look up any LC_ENCRYPTION_INFO load commands
1474 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
1475 EncryptedFileRanges encrypted_file_ranges;
1476 encryption_info_command encryption_cmd;
1477 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001478 {
Greg Clayton3046e662013-07-10 01:23:25 +00001479 const lldb::offset_t load_cmd_offset = offset;
1480 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
1481 break;
1482
Jason Molendadfb02a92015-04-02 05:19:33 +00001483 // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
1484 // the 3 fields we care about, so treat them the same.
1485 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO || encryption_cmd.cmd == LC_ENCRYPTION_INFO_64)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001486 {
Greg Clayton3046e662013-07-10 01:23:25 +00001487 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001488 {
Greg Clayton3046e662013-07-10 01:23:25 +00001489 if (encryption_cmd.cryptid != 0)
Greg Claytond37d6922013-04-16 16:51:19 +00001490 {
Greg Clayton3046e662013-07-10 01:23:25 +00001491 EncryptedFileRanges::Entry entry;
1492 entry.SetRangeBase(encryption_cmd.cryptoff);
1493 entry.SetByteSize(encryption_cmd.cryptsize);
1494 encrypted_file_ranges.Append(entry);
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001495 }
1496 }
Greg Clayton3046e662013-07-10 01:23:25 +00001497 }
1498 offset = load_cmd_offset + encryption_cmd.cmdsize;
1499 }
1500
Jason Molenda05a09c62014-08-22 02:46:46 +00001501 bool section_file_addresses_changed = false;
1502
Greg Clayton3046e662013-07-10 01:23:25 +00001503 offset = MachHeaderSizeFromMagic(m_header.magic);
1504
1505 struct segment_command_64 load_cmd;
1506 for (i=0; i<m_header.ncmds; ++i)
1507 {
1508 const lldb::offset_t load_cmd_offset = offset;
1509 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1510 break;
1511
Charles Davis510938e2013-08-27 05:04:57 +00001512 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
Greg Clayton3046e662013-07-10 01:23:25 +00001513 {
1514 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001515 {
Greg Clayton3046e662013-07-10 01:23:25 +00001516 bool add_section = true;
1517 bool add_to_unified = true;
1518 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 +00001519
Greg Clayton3046e662013-07-10 01:23:25 +00001520 SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
1521 if (is_dsym && unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001522 {
Greg Clayton3046e662013-07-10 01:23:25 +00001523 if (const_segname == GetSegmentNameLINKEDIT())
1524 {
1525 // We need to keep the __LINKEDIT segment private to this object file only
1526 add_to_unified = false;
1527 }
1528 else
1529 {
1530 // This is the dSYM file and this section has already been created by
1531 // the object file, no need to create it.
1532 add_section = false;
1533 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001534 }
Greg Clayton3046e662013-07-10 01:23:25 +00001535 load_cmd.vmaddr = m_data.GetAddress(&offset);
1536 load_cmd.vmsize = m_data.GetAddress(&offset);
1537 load_cmd.fileoff = m_data.GetAddress(&offset);
1538 load_cmd.filesize = m_data.GetAddress(&offset);
1539 if (m_length != 0 && load_cmd.filesize != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001540 {
Greg Clayton3046e662013-07-10 01:23:25 +00001541 if (load_cmd.fileoff > m_length)
1542 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001543 // 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 +00001544 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001545 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001546 // is null out the SectionList vector and if a process has been set up, dump a message
1547 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001548 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001549 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 +00001550 i,
1551 lc_segment_name,
1552 load_cmd.fileoff,
1553 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001554
1555 load_cmd.fileoff = 0;
1556 load_cmd.filesize = 0;
1557 }
1558
1559 if (load_cmd.fileoff + load_cmd.filesize > m_length)
1560 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001561 // 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 +00001562 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001563 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001564 // is null out the SectionList vector and if a process has been set up, dump a message
1565 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001566 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001567 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 +00001568 i,
1569 lc_segment_name,
1570 load_cmd.fileoff + load_cmd.filesize,
1571 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001572
1573 // Tuncase the length
1574 load_cmd.filesize = m_length - load_cmd.fileoff;
1575 }
1576 }
1577 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
1578 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001579
Charles Davis510938e2013-08-27 05:04:57 +00001580 const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001581
Greg Clayton3046e662013-07-10 01:23:25 +00001582 // Keep a list of mach segments around in case we need to
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001583 // get at data that isn't stored in the abstracted Sections.
Greg Clayton3046e662013-07-10 01:23:25 +00001584 m_mach_segments.push_back (load_cmd);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001585
Greg Clayton3046e662013-07-10 01:23:25 +00001586 // Use a segment ID of the segment index shifted left by 8 so they
1587 // never conflict with any of the sections.
1588 SectionSP segment_sp;
1589 if (add_section && (const_segname || is_core))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001590 {
Greg Clayton3046e662013-07-10 01:23:25 +00001591 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
1592 this, // Object file to which this sections belongs
1593 ++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
1594 const_segname, // Name of this section
1595 eSectionTypeContainer, // This section is a container of other sections.
1596 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
1597 load_cmd.vmsize, // VM size in bytes of this section
1598 load_cmd.fileoff, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001599 load_cmd.filesize, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001600 0, // Segments have no alignment information
Greg Clayton3046e662013-07-10 01:23:25 +00001601 load_cmd.flags)); // Flags for this section
Greg Clayton8d38ac42010-06-28 23:51:11 +00001602
Greg Clayton3046e662013-07-10 01:23:25 +00001603 segment_sp->SetIsEncrypted (segment_is_encrypted);
1604 m_sections_ap->AddSection(segment_sp);
1605 if (add_to_unified)
1606 unified_section_list.AddSection(segment_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001607 }
Greg Clayton3046e662013-07-10 01:23:25 +00001608 else if (unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001609 {
Jason Molenda20eb31b2013-08-16 03:20:42 +00001610 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr)
1611 {
1612 // Check to see if the module was read from memory?
1613 if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid())
1614 {
1615 // We have a module that is in memory and needs to have its
1616 // file address adjusted. We need to do this because when we
1617 // load a file from memory, its addresses will be slid already,
1618 // yet the addresses in the new symbol file will still be unslid.
1619 // Since everything is stored as section offset, this shouldn't
1620 // cause any problems.
Jason Molenda5894a732013-08-17 03:39:52 +00001621
1622 // Make sure we've parsed the symbol table from the
1623 // ObjectFile before we go around changing its Sections.
1624 module_sp->GetObjectFile()->GetSymtab();
1625 // eh_frame would present the same problems but we parse that on
1626 // a per-function basis as-needed so it's more difficult to
1627 // remove its use of the Sections. Realistically, the environments
1628 // where this code path will be taken will not have eh_frame sections.
1629
Jason Molenda20eb31b2013-08-16 03:20:42 +00001630 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
Jason Molenda05a09c62014-08-22 02:46:46 +00001631
1632 // Notify the module that the section addresses have been changed once
1633 // we're done so any file-address caches can be updated.
1634 section_file_addresses_changed = true;
Jason Molenda20eb31b2013-08-16 03:20:42 +00001635 }
1636 }
Greg Clayton3046e662013-07-10 01:23:25 +00001637 m_sections_ap->AddSection(unified_section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001638 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001639
Greg Clayton3046e662013-07-10 01:23:25 +00001640 struct section_64 sect64;
1641 ::memset (&sect64, 0, sizeof(sect64));
1642 // Push a section into our mach sections for the section at
Charles Davis510938e2013-08-27 05:04:57 +00001643 // index zero (NO_SECT) if we don't have any mach sections yet...
Greg Clayton3046e662013-07-10 01:23:25 +00001644 if (m_mach_sections.empty())
1645 m_mach_sections.push_back(sect64);
1646 uint32_t segment_sect_idx;
1647 const lldb::user_id_t first_segment_sectID = sectID + 1;
1648
1649
Charles Davis510938e2013-08-27 05:04:57 +00001650 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
Greg Clayton3046e662013-07-10 01:23:25 +00001651 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001652 {
Greg Clayton3046e662013-07-10 01:23:25 +00001653 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
Greg Clayton89411422010-10-08 00:21:05 +00001654 break;
Greg Clayton3046e662013-07-10 01:23:25 +00001655 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
1656 break;
1657 sect64.addr = m_data.GetAddress(&offset);
1658 sect64.size = m_data.GetAddress(&offset);
1659
1660 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
1661 break;
1662
1663 // Keep a list of mach sections around in case we need to
1664 // get at data that isn't stored in the abstracted Sections.
1665 m_mach_sections.push_back (sect64);
1666
1667 if (add_section)
1668 {
1669 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
1670 if (!const_segname)
1671 {
1672 // We have a segment with no name so we need to conjure up
1673 // segments that correspond to the section's segname if there
1674 // isn't already such a section. If there is such a section,
1675 // we resize the section so that it spans all sections.
1676 // We also mark these sections as fake so address matches don't
1677 // hit if they land in the gaps between the child sections.
1678 const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
1679 segment_sp = unified_section_list.FindSectionByName (const_segname);
1680 if (segment_sp.get())
1681 {
1682 Section *segment = segment_sp.get();
1683 // Grow the section size as needed.
1684 const lldb::addr_t sect64_min_addr = sect64.addr;
1685 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1686 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
1687 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
1688 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
1689 if (sect64_min_addr >= curr_seg_min_addr)
1690 {
1691 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
1692 // Only grow the section size if needed
1693 if (new_seg_byte_size > curr_seg_byte_size)
1694 segment->SetByteSize (new_seg_byte_size);
1695 }
1696 else
1697 {
1698 // We need to change the base address of the segment and
1699 // adjust the child section offsets for all existing children.
1700 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
1701 segment->Slide(slide_amount, false);
1702 segment->GetChildren().Slide(-slide_amount, false);
1703 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
1704 }
1705
1706 // Grow the section size as needed.
1707 if (sect64.offset)
1708 {
1709 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
1710 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
1711
1712 const lldb::addr_t section_min_file_offset = sect64.offset;
1713 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
1714 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
1715 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
1716 segment->SetFileOffset (new_file_offset);
1717 segment->SetFileSize (new_file_size);
1718 }
1719 }
1720 else
1721 {
1722 // Create a fake section for the section's named segment
1723 segment_sp.reset(new Section (segment_sp, // Parent section
1724 module_sp, // Module to which this section belongs
1725 this, // Object file to which this section belongs
1726 ++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
1727 const_segname, // Name of this section
1728 eSectionTypeContainer, // This section is a container of other sections.
1729 sect64.addr, // File VM address == addresses as they are found in the object file
1730 sect64.size, // VM size in bytes of this section
1731 sect64.offset, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001732 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001733 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001734 load_cmd.flags)); // Flags for this section
1735 segment_sp->SetIsFake(true);
1736
1737 m_sections_ap->AddSection(segment_sp);
1738 if (add_to_unified)
1739 unified_section_list.AddSection(segment_sp);
1740 segment_sp->SetIsEncrypted (segment_is_encrypted);
1741 }
1742 }
1743 assert (segment_sp.get());
1744
Charles Davis510938e2013-08-27 05:04:57 +00001745 lldb::SectionType sect_type = eSectionTypeOther;
Greg Clayton3046e662013-07-10 01:23:25 +00001746
Greg Clayton38f9cc42014-06-16 22:53:16 +00001747 if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1748 sect_type = eSectionTypeCode;
1749 else
Greg Clayton3046e662013-07-10 01:23:25 +00001750 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001751 uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
1752 static ConstString g_sect_name_objc_data ("__objc_data");
1753 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
1754 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
1755 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
1756 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
1757 static ConstString g_sect_name_objc_const ("__objc_const");
1758 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
1759 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton3046e662013-07-10 01:23:25 +00001760
Greg Clayton38f9cc42014-06-16 22:53:16 +00001761 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
1762 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
1763 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
1764 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
1765 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
1766 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
1767 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
1768 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
1769 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
1770 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
1771 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
1772 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
1773 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
1774 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
1775 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
1776 static ConstString g_sect_name_eh_frame ("__eh_frame");
Jason Molendae589e7e2014-12-08 03:09:00 +00001777 static ConstString g_sect_name_compact_unwind ("__unwind_info");
Greg Clayton38f9cc42014-06-16 22:53:16 +00001778 static ConstString g_sect_name_text ("__text");
1779 static ConstString g_sect_name_data ("__data");
1780
1781
1782 if (section_name == g_sect_name_dwarf_debug_abbrev)
1783 sect_type = eSectionTypeDWARFDebugAbbrev;
1784 else if (section_name == g_sect_name_dwarf_debug_aranges)
1785 sect_type = eSectionTypeDWARFDebugAranges;
1786 else if (section_name == g_sect_name_dwarf_debug_frame)
1787 sect_type = eSectionTypeDWARFDebugFrame;
1788 else if (section_name == g_sect_name_dwarf_debug_info)
1789 sect_type = eSectionTypeDWARFDebugInfo;
1790 else if (section_name == g_sect_name_dwarf_debug_line)
1791 sect_type = eSectionTypeDWARFDebugLine;
1792 else if (section_name == g_sect_name_dwarf_debug_loc)
1793 sect_type = eSectionTypeDWARFDebugLoc;
1794 else if (section_name == g_sect_name_dwarf_debug_macinfo)
1795 sect_type = eSectionTypeDWARFDebugMacInfo;
1796 else if (section_name == g_sect_name_dwarf_debug_pubnames)
1797 sect_type = eSectionTypeDWARFDebugPubNames;
1798 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
1799 sect_type = eSectionTypeDWARFDebugPubTypes;
1800 else if (section_name == g_sect_name_dwarf_debug_ranges)
1801 sect_type = eSectionTypeDWARFDebugRanges;
1802 else if (section_name == g_sect_name_dwarf_debug_str)
1803 sect_type = eSectionTypeDWARFDebugStr;
1804 else if (section_name == g_sect_name_dwarf_apple_names)
1805 sect_type = eSectionTypeDWARFAppleNames;
1806 else if (section_name == g_sect_name_dwarf_apple_types)
1807 sect_type = eSectionTypeDWARFAppleTypes;
1808 else if (section_name == g_sect_name_dwarf_apple_namespaces)
1809 sect_type = eSectionTypeDWARFAppleNamespaces;
1810 else if (section_name == g_sect_name_dwarf_apple_objc)
1811 sect_type = eSectionTypeDWARFAppleObjC;
1812 else if (section_name == g_sect_name_objc_selrefs)
1813 sect_type = eSectionTypeDataCStringPointers;
1814 else if (section_name == g_sect_name_objc_msgrefs)
1815 sect_type = eSectionTypeDataObjCMessageRefs;
1816 else if (section_name == g_sect_name_eh_frame)
1817 sect_type = eSectionTypeEHFrame;
Jason Molendae589e7e2014-12-08 03:09:00 +00001818 else if (section_name == g_sect_name_compact_unwind)
1819 sect_type = eSectionTypeCompactUnwind;
Greg Clayton38f9cc42014-06-16 22:53:16 +00001820 else if (section_name == g_sect_name_cfstring)
1821 sect_type = eSectionTypeDataObjCCFStrings;
1822 else if (section_name == g_sect_name_objc_data ||
1823 section_name == g_sect_name_objc_classrefs ||
1824 section_name == g_sect_name_objc_superrefs ||
1825 section_name == g_sect_name_objc_const ||
1826 section_name == g_sect_name_objc_classlist)
Greg Clayton3046e662013-07-10 01:23:25 +00001827 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001828 sect_type = eSectionTypeDataPointers;
1829 }
1830
1831 if (sect_type == eSectionTypeOther)
1832 {
1833 switch (mach_sect_type)
1834 {
1835 // TODO: categorize sections by other flags for regular sections
1836 case S_REGULAR:
1837 if (section_name == g_sect_name_text)
1838 sect_type = eSectionTypeCode;
1839 else if (section_name == g_sect_name_data)
1840 sect_type = eSectionTypeData;
1841 else
1842 sect_type = eSectionTypeOther;
1843 break;
1844 case S_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1845 case S_CSTRING_LITERALS: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1846 case S_4BYTE_LITERALS: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1847 case S_8BYTE_LITERALS: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1848 case S_LITERAL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1849 case S_NON_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1850 case S_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1851 case S_SYMBOL_STUBS: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1852 case S_MOD_INIT_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1853 case S_MOD_TERM_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1854 case S_COALESCED: sect_type = eSectionTypeOther; break;
1855 case S_GB_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1856 case S_INTERPOSING: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1857 case S_16BYTE_LITERALS: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1858 case S_DTRACE_DOF: sect_type = eSectionTypeDebug; break;
1859 case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break;
1860 default: break;
1861 }
Greg Clayton3046e662013-07-10 01:23:25 +00001862 }
1863 }
1864
1865 SectionSP section_sp(new Section (segment_sp,
1866 module_sp,
1867 this,
1868 ++sectID,
1869 section_name,
1870 sect_type,
1871 sect64.addr - segment_sp->GetFileAddress(),
1872 sect64.size,
1873 sect64.offset,
1874 sect64.offset == 0 ? 0 : sect64.size,
Greg Clayton48672af2014-06-24 22:22:43 +00001875 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001876 sect64.flags));
1877 // Set the section to be encrypted to match the segment
1878
1879 bool section_is_encrypted = false;
1880 if (!segment_is_encrypted && load_cmd.filesize != 0)
1881 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
1882
1883 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
1884 segment_sp->GetChildren().AddSection(section_sp);
1885
1886 if (segment_sp->IsFake())
1887 {
1888 segment_sp.reset();
1889 const_segname.Clear();
1890 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001891 }
1892 }
Greg Clayton3046e662013-07-10 01:23:25 +00001893 if (segment_sp && is_dsym)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001894 {
Greg Clayton3046e662013-07-10 01:23:25 +00001895 if (first_segment_sectID <= sectID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001896 {
Greg Clayton3046e662013-07-10 01:23:25 +00001897 lldb::user_id_t sect_uid;
1898 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001899 {
Greg Clayton3046e662013-07-10 01:23:25 +00001900 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1901 SectionSP next_section_sp;
1902 if (sect_uid + 1 <= sectID)
1903 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1904
1905 if (curr_section_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001906 {
Greg Clayton3046e662013-07-10 01:23:25 +00001907 if (curr_section_sp->GetByteSize() == 0)
1908 {
1909 if (next_section_sp.get() != NULL)
1910 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1911 else
1912 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1913 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001914 }
1915 }
1916 }
1917 }
1918 }
1919 }
1920 }
Charles Davis510938e2013-08-27 05:04:57 +00001921 else if (load_cmd.cmd == LC_DYSYMTAB)
Greg Clayton3046e662013-07-10 01:23:25 +00001922 {
1923 m_dysymtab.cmd = load_cmd.cmd;
1924 m_dysymtab.cmdsize = load_cmd.cmdsize;
1925 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1926 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001927
Greg Clayton3046e662013-07-10 01:23:25 +00001928 offset = load_cmd_offset + load_cmd.cmdsize;
1929 }
Jason Molenda05a09c62014-08-22 02:46:46 +00001930
1931
1932 if (section_file_addresses_changed && module_sp.get())
1933 {
1934 module_sp->SectionFileAddressesChanged();
1935 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001936 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001937}
1938
1939class MachSymtabSectionInfo
1940{
1941public:
1942
1943 MachSymtabSectionInfo (SectionList *section_list) :
1944 m_section_list (section_list),
1945 m_section_infos()
1946 {
1947 // Get the number of sections down to a depth of 1 to include
1948 // all segments and their sections, but no other sections that
1949 // may be added for debug map or
1950 m_section_infos.resize(section_list->GetNumSections(1));
1951 }
1952
1953
Greg Claytone72dfb32012-02-24 01:59:29 +00001954 SectionSP
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001955 GetSection (uint8_t n_sect, addr_t file_addr)
1956 {
1957 if (n_sect == 0)
Greg Claytone72dfb32012-02-24 01:59:29 +00001958 return SectionSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001959 if (n_sect < m_section_infos.size())
1960 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001961 if (!m_section_infos[n_sect].section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001962 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001963 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1964 m_section_infos[n_sect].section_sp = section_sp;
Sean Callanan9a028512012-08-09 00:50:26 +00001965 if (section_sp)
Greg Claytondda0d122011-07-10 17:32:33 +00001966 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001967 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1968 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Claytondda0d122011-07-10 17:32:33 +00001969 }
1970 else
1971 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00001972 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Claytondda0d122011-07-10 17:32:33 +00001973 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001974 }
1975 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton8f258512011-08-26 20:01:35 +00001976 {
1977 // Symbol is in section.
Greg Claytone72dfb32012-02-24 01:59:29 +00001978 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001979 }
1980 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1981 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1982 {
1983 // Symbol is in section with zero size, but has the same start
1984 // address as the section. This can happen with linker symbols
1985 // (symbols that start with the letter 'l' or 'L'.
Greg Claytone72dfb32012-02-24 01:59:29 +00001986 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001987 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001988 }
Greg Claytone72dfb32012-02-24 01:59:29 +00001989 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001990 }
1991
1992protected:
1993 struct SectionInfo
1994 {
1995 SectionInfo () :
1996 vm_range(),
Greg Claytone72dfb32012-02-24 01:59:29 +00001997 section_sp ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001998 {
1999 }
2000
2001 VMRange vm_range;
Greg Claytone72dfb32012-02-24 01:59:29 +00002002 SectionSP section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002003 };
2004 SectionList *m_section_list;
2005 std::vector<SectionInfo> m_section_infos;
2006};
2007
Greg Clayton9191db42013-10-21 18:40:51 +00002008struct TrieEntry
2009{
2010 TrieEntry () :
2011 name(),
2012 address(LLDB_INVALID_ADDRESS),
2013 flags (0),
2014 other(0),
2015 import_name()
2016 {
2017 }
2018
2019 void
2020 Clear ()
2021 {
2022 name.Clear();
2023 address = LLDB_INVALID_ADDRESS;
2024 flags = 0;
2025 other = 0;
2026 import_name.Clear();
2027 }
2028
2029 void
2030 Dump () const
2031 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002032 printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2033 static_cast<unsigned long long>(address),
2034 static_cast<unsigned long long>(flags),
2035 static_cast<unsigned long long>(other), name.GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +00002036 if (import_name)
2037 printf (" -> \"%s\"\n", import_name.GetCString());
2038 else
2039 printf ("\n");
2040 }
2041 ConstString name;
2042 uint64_t address;
2043 uint64_t flags;
2044 uint64_t other;
2045 ConstString import_name;
2046};
2047
2048struct TrieEntryWithOffset
2049{
2050 lldb::offset_t nodeOffset;
2051 TrieEntry entry;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002052
Greg Clayton9191db42013-10-21 18:40:51 +00002053 TrieEntryWithOffset (lldb::offset_t offset) :
2054 nodeOffset (offset),
2055 entry()
2056 {
2057 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002058
Greg Clayton9191db42013-10-21 18:40:51 +00002059 void
2060 Dump (uint32_t idx) const
2061 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002062 printf ("[%3u] 0x%16.16llx: ", idx,
2063 static_cast<unsigned long long>(nodeOffset));
Greg Clayton9191db42013-10-21 18:40:51 +00002064 entry.Dump();
2065 }
2066
2067 bool
2068 operator<(const TrieEntryWithOffset& other) const
2069 {
2070 return ( nodeOffset < other.nodeOffset );
2071 }
2072};
2073
2074static void
2075ParseTrieEntries (DataExtractor &data,
2076 lldb::offset_t offset,
Greg Claytonb887da12015-07-16 19:50:57 +00002077 const bool is_arm,
Greg Clayton9191db42013-10-21 18:40:51 +00002078 std::vector<llvm::StringRef> &nameSlices,
2079 std::set<lldb::addr_t> &resolver_addresses,
2080 std::vector<TrieEntryWithOffset>& output)
2081{
2082 if (!data.ValidOffset(offset))
2083 return;
2084
2085 const uint64_t terminalSize = data.GetULEB128(&offset);
2086 lldb::offset_t children_offset = offset + terminalSize;
2087 if ( terminalSize != 0 ) {
2088 TrieEntryWithOffset e (offset);
2089 e.entry.flags = data.GetULEB128(&offset);
2090 const char *import_name = NULL;
2091 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
2092 e.entry.address = 0;
2093 e.entry.other = data.GetULEB128(&offset); // dylib ordinal
2094 import_name = data.GetCStr(&offset);
2095 }
2096 else {
2097 e.entry.address = data.GetULEB128(&offset);
2098 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
2099 {
Greg Clayton9191db42013-10-21 18:40:51 +00002100 e.entry.other = data.GetULEB128(&offset);
Greg Claytonb887da12015-07-16 19:50:57 +00002101 uint64_t resolver_addr = e.entry.other;
2102 if (is_arm)
2103 resolver_addr &= THUMB_ADDRESS_BIT_MASK;
2104 resolver_addresses.insert(resolver_addr);
Greg Clayton9191db42013-10-21 18:40:51 +00002105 }
2106 else
2107 e.entry.other = 0;
2108 }
2109 // Only add symbols that are reexport symbols with a valid import name
2110 if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
2111 {
2112 std::string name;
2113 if (!nameSlices.empty())
2114 {
2115 for (auto name_slice: nameSlices)
2116 name.append(name_slice.data(), name_slice.size());
2117 }
2118 if (name.size() > 1)
2119 {
2120 // Skip the leading '_'
2121 e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
2122 }
2123 if (import_name)
2124 {
2125 // Skip the leading '_'
2126 e.entry.import_name.SetCString(import_name+1);
2127 }
2128 output.push_back(e);
2129 }
2130 }
2131
2132 const uint8_t childrenCount = data.GetU8(&children_offset);
2133 for (uint8_t i=0; i < childrenCount; ++i) {
2134 nameSlices.push_back(data.GetCStr(&children_offset));
2135 lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
2136 if (childNodeOffset)
2137 {
2138 ParseTrieEntries(data,
2139 childNodeOffset,
Greg Claytonb887da12015-07-16 19:50:57 +00002140 is_arm,
Greg Clayton9191db42013-10-21 18:40:51 +00002141 nameSlices,
2142 resolver_addresses,
2143 output);
2144 }
2145 nameSlices.pop_back();
2146 }
2147}
2148
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002149size_t
Greg Clayton3046e662013-07-10 01:23:25 +00002150ObjectFileMachO::ParseSymtab ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002151{
2152 Timer scoped_timer(__PRETTY_FUNCTION__,
2153 "ObjectFileMachO::ParseSymtab () module = %s",
2154 m_file.GetFilename().AsCString(""));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002155 ModuleSP module_sp (GetModule());
2156 if (!module_sp)
2157 return 0;
2158
2159 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
2160 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
Greg Clayton9191db42013-10-21 18:40:51 +00002161 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 +00002162 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
2163 FunctionStarts function_starts;
Greg Claytonc7bece562013-01-25 18:06:21 +00002164 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002165 uint32_t i;
Greg Clayton9191db42013-10-21 18:40:51 +00002166 FileSpecList dylib_files;
Greg Clayton5160ce52013-03-27 23:08:40 +00002167 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
Greg Clayton1e28adf2015-02-25 17:25:02 +00002168 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2169 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2170 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
Greg Clayton77ccca72011-12-30 00:32:24 +00002171
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002172 for (i=0; i<m_header.ncmds; ++i)
2173 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002174 const lldb::offset_t cmd_offset = offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002175 // Read in the load command and load command size
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002176 struct load_command lc;
2177 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002178 break;
2179 // Watch for the symbol table load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002180 switch (lc.cmd)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002181 {
Charles Davis510938e2013-08-27 05:04:57 +00002182 case LC_SYMTAB:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002183 symtab_load_command.cmd = lc.cmd;
2184 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002185 // Read in the rest of the symtab load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002186 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
2187 return 0;
2188 if (symtab_load_command.symoff == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002189 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002190 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002191 module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002192 return 0;
2193 }
2194
2195 if (symtab_load_command.stroff == 0)
2196 {
2197 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002198 module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002199 return 0;
2200 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002201
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002202 if (symtab_load_command.nsyms == 0)
2203 {
2204 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002205 module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002206 return 0;
2207 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002208
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002209 if (symtab_load_command.strsize == 0)
2210 {
2211 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002212 module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002213 return 0;
2214 }
2215 break;
2216
Greg Clayton9191db42013-10-21 18:40:51 +00002217 case LC_DYLD_INFO:
2218 case LC_DYLD_INFO_ONLY:
2219 if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
2220 {
2221 dyld_info.cmd = lc.cmd;
2222 dyld_info.cmdsize = lc.cmdsize;
2223 }
2224 else
2225 {
2226 memset (&dyld_info, 0, sizeof(dyld_info));
2227 }
2228 break;
2229
2230 case LC_LOAD_DYLIB:
2231 case LC_LOAD_WEAK_DYLIB:
2232 case LC_REEXPORT_DYLIB:
2233 case LC_LOADFVMLIB:
2234 case LC_LOAD_UPWARD_DYLIB:
2235 {
2236 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2237 const char *path = m_data.PeekCStr(name_offset);
2238 if (path)
2239 {
2240 FileSpec file_spec(path, false);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002241 // Strip the path if there is @rpath, @executable, etc so we just use the basename
Greg Clayton9191db42013-10-21 18:40:51 +00002242 if (path[0] == '@')
2243 file_spec.GetDirectory().Clear();
Jim Inghamfbe0b9a2014-05-21 03:58:03 +00002244
2245 if (lc.cmd == LC_REEXPORT_DYLIB)
2246 {
2247 m_reexported_dylibs.AppendIfUnique(file_spec);
2248 }
Greg Clayton9191db42013-10-21 18:40:51 +00002249
2250 dylib_files.Append(file_spec);
2251 }
2252 }
2253 break;
2254
Charles Davis510938e2013-08-27 05:04:57 +00002255 case LC_FUNCTION_STARTS:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002256 function_starts_load_command.cmd = lc.cmd;
2257 function_starts_load_command.cmdsize = lc.cmdsize;
2258 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 +00002259 memset (&function_starts_load_command, 0, sizeof(function_starts_load_command));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002260 break;
2261
2262 default:
2263 break;
2264 }
2265 offset = cmd_offset + lc.cmdsize;
2266 }
2267
2268 if (symtab_load_command.cmd)
2269 {
2270 Symtab *symtab = m_symtab_ap.get();
2271 SectionList *section_list = GetSectionList();
2272 if (section_list == NULL)
2273 return 0;
2274
Greg Claytonc7bece562013-01-25 18:06:21 +00002275 const uint32_t addr_byte_size = m_data.GetAddressByteSize();
2276 const ByteOrder byte_order = m_data.GetByteOrder();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002277 bool bit_width_32 = addr_byte_size == 4;
2278 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
2279
Greg Claytonc7bece562013-01-25 18:06:21 +00002280 DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
2281 DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
2282 DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
Jason Molendad34e6522013-02-05 22:31:24 +00002283 DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002284 DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);
Jason Molenda4e7511e2013-03-06 23:19:17 +00002285
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002286 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
2287 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Clayton4c82d422012-05-18 23:20:01 +00002288 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
Greg Claytonfd814c52013-08-13 01:42:25 +00002289
2290 ProcessSP process_sp (m_process_wp.lock());
2291 Process *process = process_sp.get();
2292
Greg Clayton86eac942013-08-13 21:32:34 +00002293 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
2294
Greg Clayton48672af2014-06-24 22:22:43 +00002295 if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002296 {
Greg Clayton4c82d422012-05-18 23:20:01 +00002297 Target &target = process->GetTarget();
Greg Claytonfd814c52013-08-13 01:42:25 +00002298
Greg Clayton86eac942013-08-13 21:32:34 +00002299 memory_module_load_level = target.GetMemoryModuleLoadLevel();
Greg Claytonfd814c52013-08-13 01:42:25 +00002300
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002301 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2302 // Reading mach file from memory in a process or core file...
2303
2304 if (linkedit_section_sp)
2305 {
Greg Clayton07347372015-06-08 21:53:11 +00002306 addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
2307 if (linkedit_load_addr == LLDB_INVALID_ADDRESS)
2308 {
2309 // We might be trying to access the symbol table before the __LINKEDIT's load
2310 // address has been set in the target. We can't fail to read the symbol table,
2311 // so calculate the right address manually
2312 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2313 }
2314
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002315 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2316 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Clayton4c82d422012-05-18 23:20:01 +00002317 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton26b47e22012-04-18 05:19:20 +00002318
2319 bool data_was_read = false;
2320
Todd Fiala013434e2014-07-09 01:29:05 +00002321#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa3329782014-03-29 18:54:20 +00002322 if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
Greg Clayton77ccca72011-12-30 00:32:24 +00002323 {
Greg Clayton26b47e22012-04-18 05:19:20 +00002324 // This mach-o memory file is in the dyld shared cache. If this
2325 // program is not remote and this is iOS, then this process will
2326 // share the same shared cache as the process we are debugging and
2327 // we can read the entire __LINKEDIT from the address space in this
2328 // process. This is a needed optimization that is used for local iOS
2329 // debugging only since all shared libraries in the shared cache do
2330 // not have corresponding files that exist in the file system of the
2331 // device. They have been combined into a single file. This means we
2332 // always have to load these files from memory. All of the symbol and
2333 // string tables from all of the __LINKEDIT sections from the shared
2334 // libraries in the shared cache have been merged into a single large
2335 // symbol and string table. Reading all of this symbol and string table
2336 // data across can slow down debug launch times, so we optimize this by
2337 // reading the memory for the __LINKEDIT section from this process.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002338
2339 UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
2340 UUID process_shared_cache(GetProcessSharedCacheUUID(process));
2341 bool use_lldb_cache = true;
2342 if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache)
2343 {
2344 use_lldb_cache = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002345 ModuleSP module_sp (GetModule());
2346 if (module_sp)
2347 module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow.");
2348
Jason Molenda0e0954c2013-04-16 06:24:42 +00002349 }
2350
Greg Clayton26b47e22012-04-18 05:19:20 +00002351 PlatformSP platform_sp (target.GetPlatform());
Jason Molenda0e0954c2013-04-16 06:24:42 +00002352 if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
Greg Clayton26b47e22012-04-18 05:19:20 +00002353 {
2354 data_was_read = true;
2355 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Clayton4c82d422012-05-18 23:20:01 +00002356 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton26b47e22012-04-18 05:19:20 +00002357 if (function_starts_load_command.cmd)
2358 {
2359 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2360 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
2361 }
2362 }
2363 }
2364#endif
2365
2366 if (!data_was_read)
2367 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002368 if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
Jason Molendad34e6522013-02-05 22:31:24 +00002369 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002370 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
2371 if (nlist_data_sp)
2372 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2373 // Load strings individually from memory when loading from memory since shared cache
2374 // string tables contain strings for all symbols from all shared cached libraries
2375 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
2376 //if (strtab_data_sp)
2377 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
2378 if (m_dysymtab.nindirectsyms != 0)
2379 {
2380 const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
2381 DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
2382 if (indirect_syms_data_sp)
2383 indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2384 }
Jason Molendad34e6522013-02-05 22:31:24 +00002385 }
Greg Claytonfd814c52013-08-13 01:42:25 +00002386
2387 if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
Greg Clayton26b47e22012-04-18 05:19:20 +00002388 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002389 if (function_starts_load_command.cmd)
2390 {
2391 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2392 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
2393 if (func_start_data_sp)
2394 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
2395 }
Greg Clayton26b47e22012-04-18 05:19:20 +00002396 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002397 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002398 }
2399 }
2400 else
2401 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002402 nlist_data.SetData (m_data,
2403 symtab_load_command.symoff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002404 nlist_data_byte_size);
2405 strtab_data.SetData (m_data,
Jason Molenda4e7511e2013-03-06 23:19:17 +00002406 symtab_load_command.stroff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002407 strtab_data_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002408
2409 if (dyld_info.export_size > 0)
2410 {
2411 dyld_trie_data.SetData (m_data,
2412 dyld_info.export_off,
2413 dyld_info.export_size);
2414 }
2415
Jason Molendad34e6522013-02-05 22:31:24 +00002416 if (m_dysymtab.nindirectsyms != 0)
2417 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002418 indirect_symbol_index_data.SetData (m_data,
2419 m_dysymtab.indirectsymoff,
Jason Molendad34e6522013-02-05 22:31:24 +00002420 m_dysymtab.nindirectsyms * 4);
2421 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002422 if (function_starts_load_command.cmd)
2423 {
2424 function_starts_data.SetData (m_data,
2425 function_starts_load_command.dataoff,
2426 function_starts_load_command.datasize);
2427 }
2428 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002429
Greg Clayton86eac942013-08-13 21:32:34 +00002430 if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete)
2431 {
2432 if (log)
2433 module_sp->LogMessage(log, "failed to read nlist data");
2434 return 0;
2435 }
2436
2437
Greg Claytondebb8812012-05-25 17:04:00 +00002438 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2439 if (!have_strtab_data)
Greg Clayton4c82d422012-05-18 23:20:01 +00002440 {
Greg Claytondebb8812012-05-25 17:04:00 +00002441 if (process)
2442 {
2443 if (strtab_addr == LLDB_INVALID_ADDRESS)
2444 {
2445 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002446 module_sp->LogMessage(log, "failed to locate the strtab in memory");
Greg Claytondebb8812012-05-25 17:04:00 +00002447 return 0;
2448 }
2449 }
2450 else
Greg Clayton4c82d422012-05-18 23:20:01 +00002451 {
2452 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002453 module_sp->LogMessage(log, "failed to read strtab data");
Greg Clayton4c82d422012-05-18 23:20:01 +00002454 return 0;
2455 }
2456 }
Greg Clayton4c82d422012-05-18 23:20:01 +00002457
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002458 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
2459 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
Greg Claytona381e102015-07-27 23:21:05 +00002460 const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
2461 const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002462 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
2463 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
2464 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
2465 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
Greg Claytona381e102015-07-27 23:21:05 +00002466 SectionSP data_dirty_section_sp(section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2467 SectionSP data_const_section_sp(section_list->FindSectionByName(g_segment_name_DATA_CONST));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002468 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
2469 SectionSP eh_frame_section_sp;
2470 if (text_section_sp.get())
2471 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
2472 else
2473 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
2474
Charles Davis510938e2013-08-27 05:04:57 +00002475 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
Jason Molenda5635f772013-03-21 03:36:01 +00002476
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002477 // lldb works best if it knows the start address of all functions in a module.
Jason Molenda5635f772013-03-21 03:36:01 +00002478 // Linker symbols or debug info are normally the best source of information for start addr / size but
2479 // they may be stripped in a released binary.
Jason Molendad63d3c72013-04-16 00:18:44 +00002480 // Two additional sources of information exist in Mach-O binaries:
Jason Molenda5635f772013-03-21 03:36:01 +00002481 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
2482 // binary, relative to the text section.
2483 // eh_frame - the eh_frame FDEs have the start addr & size of each function
2484 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
2485 // Binaries built to run on older releases may need to use eh_frame information.
2486
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002487 if (text_section_sp && function_starts_data.GetByteSize())
2488 {
2489 FunctionStarts::Entry function_start_entry;
2490 function_start_entry.data = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00002491 lldb::offset_t function_start_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002492 function_start_entry.addr = text_section_sp->GetFileAddress();
2493 uint64_t delta;
2494 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
2495 {
2496 // Now append the current entry
2497 function_start_entry.addr += delta;
2498 function_starts.Append(function_start_entry);
2499 }
Jason Molendad63d3c72013-04-16 00:18:44 +00002500 }
Jason Molenda5635f772013-03-21 03:36:01 +00002501 else
2502 {
Jason Molenda584ce2f2013-03-22 00:38:45 +00002503 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
2504 // but it doesn't actually have the eh_frame content. And if we have a dSYM, we don't need to do any
2505 // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
2506 // the module.
2507 if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
Jason Molenda5635f772013-03-21 03:36:01 +00002508 {
Jason Molendaa18f7072015-08-15 01:21:01 +00002509 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindEHFrame, true);
Jason Molenda5635f772013-03-21 03:36:01 +00002510 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
2511 eh_frame.GetFunctionAddressAndSizeVector (functions);
2512 addr_t text_base_addr = text_section_sp->GetFileAddress();
2513 size_t count = functions.GetSize();
2514 for (size_t i = 0; i < count; ++i)
2515 {
2516 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
2517 if (func)
2518 {
2519 FunctionStarts::Entry function_start_entry;
2520 function_start_entry.addr = func->base - text_base_addr;
2521 function_starts.Append(function_start_entry);
2522 }
2523 }
2524 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002525 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002526
Greg Claytonc7bece562013-01-25 18:06:21 +00002527 const size_t function_starts_count = function_starts.GetSize();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002528
Saleem Abdulrasoolb5c128b2014-07-23 01:53:52 +00002529 const user_id_t TEXT_eh_frame_sectID =
2530 eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
2531 : static_cast<user_id_t>(NO_SECT);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002532
Greg Claytonc7bece562013-01-25 18:06:21 +00002533 lldb::offset_t nlist_data_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002534
2535 uint32_t N_SO_index = UINT32_MAX;
2536
2537 MachSymtabSectionInfo section_info (section_list);
2538 std::vector<uint32_t> N_FUN_indexes;
2539 std::vector<uint32_t> N_NSYM_indexes;
2540 std::vector<uint32_t> N_INCL_indexes;
2541 std::vector<uint32_t> N_BRAC_indexes;
2542 std::vector<uint32_t> N_COMM_indexes;
Greg Claytond81088c2014-01-16 01:38:29 +00002543 typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002544 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
Greg Claytondacc4a92013-05-14 22:19:37 +00002545 typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002546 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2547 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
Greg Claytondacc4a92013-05-14 22:19:37 +00002548 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002549 // Any symbols that get merged into another will get an entry
2550 // in this map so we know
2551 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2552 uint32_t nlist_idx = 0;
2553 Symbol *symbol_ptr = NULL;
2554
2555 uint32_t sym_idx = 0;
Jason Molendaa5609c82012-06-21 01:51:02 +00002556 Symbol *sym = NULL;
Greg Claytonc7bece562013-01-25 18:06:21 +00002557 size_t num_syms = 0;
Greg Clayton4c82d422012-05-18 23:20:01 +00002558 std::string memory_symbol_name;
Jason Molendaa5609c82012-06-21 01:51:02 +00002559 uint32_t unmapped_local_symbols_found = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002560
Jim Inghamea3ac272014-01-10 22:55:37 +00002561 std::vector<TrieEntryWithOffset> trie_entries;
2562 std::set<lldb::addr_t> resolver_addresses;
2563
2564 if (dyld_trie_data.GetByteSize() > 0)
2565 {
2566 std::vector<llvm::StringRef> nameSlices;
2567 ParseTrieEntries (dyld_trie_data,
2568 0,
Greg Claytonb887da12015-07-16 19:50:57 +00002569 is_arm,
Jim Inghamea3ac272014-01-10 22:55:37 +00002570 nameSlices,
2571 resolver_addresses,
2572 trie_entries);
2573
2574 ConstString text_segment_name ("__TEXT");
2575 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2576 if (text_segment_sp)
2577 {
2578 const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
2579 if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
2580 {
2581 for (auto &e : trie_entries)
2582 e.entry.address += text_segment_file_addr;
2583 }
2584 }
2585 }
2586
Greg Claytonb65c6292015-02-20 22:20:05 +00002587 typedef std::set<ConstString> IndirectSymbols;
2588 IndirectSymbols indirect_symbol_names;
2589
Todd Fiala013434e2014-07-09 01:29:05 +00002590#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa5609c82012-06-21 01:51:02 +00002591
2592 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
2593 // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
2594 // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
2595 // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
2596 // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
2597 // nlist parser to ignore all LOCAL symbols.
2598
2599 if (m_header.flags & 0x80000000u)
2600 {
2601 // Before we can start mapping the DSC, we need to make certain the target process is actually
2602 // using the cache we can find.
2603
Jason Molendaa5609c82012-06-21 01:51:02 +00002604 // Next we need to determine the correct path for the dyld shared cache.
2605
Greg Clayton7ab7f892014-05-29 21:33:45 +00002606 ArchSpec header_arch;
2607 GetArchitecture(header_arch);
Jason Molendaa5609c82012-06-21 01:51:02 +00002608 char dsc_path[PATH_MAX];
2609
2610 snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
Jason Molenda4e7511e2013-03-06 23:19:17 +00002611 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
2612 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
Jason Molendaa5609c82012-06-21 01:51:02 +00002613 header_arch.GetArchitectureName());
2614
2615 FileSpec dsc_filespec(dsc_path, false);
2616
2617 // We need definitions of two structures in the on-disk DSC, copy them here manually
Jason Molendad63d3c72013-04-16 00:18:44 +00002618 struct lldb_copy_dyld_cache_header_v0
Greg Clayton946f8902012-09-05 22:30:51 +00002619 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002620 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2621 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2622 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
Jason Molenda4e7511e2013-03-06 23:19:17 +00002623 uint32_t imagesOffset;
2624 uint32_t imagesCount;
2625 uint64_t dyldBaseAddress;
2626 uint64_t codeSignatureOffset;
2627 uint64_t codeSignatureSize;
2628 uint64_t slideInfoOffset;
2629 uint64_t slideInfoSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002630 uint64_t localSymbolsOffset; // file offset of where local symbols are stored
2631 uint64_t localSymbolsSize; // size of local symbols information
2632 };
2633 struct lldb_copy_dyld_cache_header_v1
2634 {
2635 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2636 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2637 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
2638 uint32_t imagesOffset;
2639 uint32_t imagesCount;
2640 uint64_t dyldBaseAddress;
2641 uint64_t codeSignatureOffset;
2642 uint64_t codeSignatureSize;
2643 uint64_t slideInfoOffset;
2644 uint64_t slideInfoSize;
Jason Molenda4e7511e2013-03-06 23:19:17 +00002645 uint64_t localSymbolsOffset;
2646 uint64_t localSymbolsSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002647 uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later
Greg Clayton946f8902012-09-05 22:30:51 +00002648 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002649
Jason Molendad63d3c72013-04-16 00:18:44 +00002650 struct lldb_copy_dyld_cache_mapping_info
2651 {
2652 uint64_t address;
2653 uint64_t size;
2654 uint64_t fileOffset;
2655 uint32_t maxProt;
2656 uint32_t initProt;
2657 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002658
Greg Clayton946f8902012-09-05 22:30:51 +00002659 struct lldb_copy_dyld_cache_local_symbols_info
2660 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002661 uint32_t nlistOffset;
2662 uint32_t nlistCount;
2663 uint32_t stringsOffset;
2664 uint32_t stringsSize;
2665 uint32_t entriesOffset;
2666 uint32_t entriesCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002667 };
2668 struct lldb_copy_dyld_cache_local_symbols_entry
2669 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002670 uint32_t dylibOffset;
2671 uint32_t nlistStartIndex;
2672 uint32_t nlistCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002673 };
Jason Molendaa5609c82012-06-21 01:51:02 +00002674
Jason Molendaf8130862012-06-22 03:28:35 +00002675 /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
2676 The dyld_cache_local_symbols_info structure gives us three things:
2677 1. The start and count of the nlist records in the dyld_shared_cache file
2678 2. The start and size of the strings for these nlist records
2679 3. The start and count of dyld_cache_local_symbols_entry entries
2680
2681 There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
2682 The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
Jason Molenda4e7511e2013-03-06 23:19:17 +00002683 The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
Jason Molendaf8130862012-06-22 03:28:35 +00002684 and the count of how many nlist records there are for this dylib/framework.
2685 */
2686
Jason Molendaa5609c82012-06-21 01:51:02 +00002687 // Process the dsc header to find the unmapped symbols
2688 //
2689 // Save some VM space, do not map the entire cache in one shot.
2690
Jason Molenda255f9bb2013-03-06 23:17:36 +00002691 DataBufferSP dsc_data_sp;
Greg Clayton736888c2015-02-23 23:47:09 +00002692 dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
Jason Molenda255f9bb2013-03-06 23:17:36 +00002693
2694 if (dsc_data_sp)
Jason Molendaa5609c82012-06-21 01:51:02 +00002695 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002696 DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002697
Jason Molenda255f9bb2013-03-06 23:17:36 +00002698 char version_str[17];
2699 int version = -1;
2700 lldb::offset_t offset = 0;
2701 memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16);
2702 version_str[16] = '\0';
2703 if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6]))
2704 {
2705 int v;
2706 if (::sscanf (version_str + 6, "%d", &v) == 1)
2707 {
2708 version = v;
2709 }
2710 }
2711
Jason Molenda0e0954c2013-04-16 06:24:42 +00002712 UUID dsc_uuid;
2713 if (version >= 1)
2714 {
2715 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
2716 uint8_t uuid_bytes[sizeof (uuid_t)];
2717 memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
2718 dsc_uuid.SetBytes (uuid_bytes);
2719 }
2720
2721 bool uuid_match = true;
2722 if (dsc_uuid.IsValid() && process)
2723 {
2724 UUID shared_cache_uuid(GetProcessSharedCacheUUID(process));
2725
2726 if (shared_cache_uuid.IsValid() && dsc_uuid != shared_cache_uuid)
2727 {
2728 // The on-disk dyld_shared_cache file is not the same as the one in this
2729 // process' memory, don't use it.
2730 uuid_match = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002731 ModuleSP module_sp (GetModule());
2732 if (module_sp)
2733 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 +00002734 }
2735 }
2736
Jason Molenda4e7511e2013-03-06 23:19:17 +00002737 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);
Jason Molenda255f9bb2013-03-06 23:17:36 +00002738
Jason Molendaa5609c82012-06-21 01:51:02 +00002739 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
2740
2741 // If the mappingOffset points to a location inside the header, we've
2742 // opened an old dyld shared cache, and should not proceed further.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002743 if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
Jason Molendaa5609c82012-06-21 01:51:02 +00002744 {
2745
Greg Clayton736888c2015-02-23 23:47:09 +00002746 DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
Jason Molenda255f9bb2013-03-06 23:17:36 +00002747 DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
2748 offset = 0;
2749
2750 // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
2751 // in the shared library cache need to be adjusted by an offset to match up with the
2752 // dylibOffset identifying field in the dyld_cache_local_symbol_entry's. This offset is
2753 // recorded in mapping_offset_value.
2754 const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
2755
2756 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
Jason Molendaa5609c82012-06-21 01:51:02 +00002757 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
2758 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
2759
Jason Molenda4e7511e2013-03-06 23:19:17 +00002760 if (localSymbolsOffset && localSymbolsSize)
Jason Molendaa5609c82012-06-21 01:51:02 +00002761 {
2762 // Map the local symbols
Greg Clayton736888c2015-02-23 23:47:09 +00002763 if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(localSymbolsOffset, localSymbolsSize))
Jason Molendaa5609c82012-06-21 01:51:02 +00002764 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002765 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002766
2767 offset = 0;
2768
Greg Claytonb65c6292015-02-20 22:20:05 +00002769 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
2770 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
2771 UndefinedNameToDescMap undefined_name_to_desc;
2772 SymbolIndexToName reexport_shlib_needs_fixup;
2773
2774
Jason Molendaa5609c82012-06-21 01:51:02 +00002775 // Read the local_symbols_infos struct in one shot
2776 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
2777 dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
2778
Jason Molendaa5609c82012-06-21 01:51:02 +00002779 SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
2780
Jason Molenda255f9bb2013-03-06 23:17:36 +00002781 uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00002782
2783 offset = local_symbols_info.entriesOffset;
2784 for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
2785 {
2786 struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
2787 local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
2788 local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
2789 local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
2790
Jason Molenda4e7511e2013-03-06 23:19:17 +00002791 if (header_file_offset == local_symbols_entry.dylibOffset)
Jason Molendaa5609c82012-06-21 01:51:02 +00002792 {
2793 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
2794
2795 // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
2796 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2797 num_syms = symtab->GetNumSymbols();
2798
2799 nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
2800 uint32_t string_table_offset = local_symbols_info.stringsOffset;
2801
Jason Molenda4e7511e2013-03-06 23:19:17 +00002802 for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
Jason Molendaa5609c82012-06-21 01:51:02 +00002803 {
2804 /////////////////////////////
2805 {
2806 struct nlist_64 nlist;
2807 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2808 break;
2809
2810 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
2811 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2812 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2813 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
2814 nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
2815
2816 SymbolType type = eSymbolTypeInvalid;
2817 const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
2818
2819 if (symbol_name == NULL)
2820 {
2821 // No symbol should be NULL, even the symbols with no
2822 // string values should have an offset zero which points
2823 // to an empty C-string
2824 Host::SystemLog (Host::eSystemLogError,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002825 "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 +00002826 entry_index,
2827 nlist.n_strx,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002828 module_sp->GetFileSpec().GetPath().c_str());
Jason Molendaa5609c82012-06-21 01:51:02 +00002829 continue;
2830 }
2831 if (symbol_name[0] == '\0')
2832 symbol_name = NULL;
2833
2834 const char *symbol_name_non_abi_mangled = NULL;
2835
2836 SectionSP symbol_section;
2837 uint32_t symbol_byte_size = 0;
2838 bool add_nlist = true;
Charles Davis510938e2013-08-27 05:04:57 +00002839 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002840 bool demangled_is_synthesized = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00002841 bool is_gsym = false;
Greg Clayton60038be2015-02-14 00:51:13 +00002842 bool set_value = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00002843
2844 assert (sym_idx < num_syms);
2845
2846 sym[sym_idx].SetDebug (is_debug);
2847
2848 if (is_debug)
2849 {
2850 switch (nlist.n_type)
2851 {
Charles Davis510938e2013-08-27 05:04:57 +00002852 case N_GSYM:
2853 // global symbol: name,,NO_SECT,type,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002854 // Sometimes the N_GSYM value contains the address.
2855
2856 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
2857 // have the same address, but we want to ensure that we always find only the real symbol,
2858 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
2859 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
2860 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
2861 // same address.
2862
Greg Clayton1e28adf2015-02-25 17:25:02 +00002863 is_gsym = true;
2864 sym[sym_idx].SetExternal(true);
2865
2866 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
2867 {
2868 llvm::StringRef symbol_name_ref(symbol_name);
2869 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
2870 {
2871 symbol_name_non_abi_mangled = symbol_name + 1;
2872 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2873 type = eSymbolTypeObjCClass;
2874 demangled_is_synthesized = true;
2875
2876 }
2877 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
2878 {
2879 symbol_name_non_abi_mangled = symbol_name + 1;
2880 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2881 type = eSymbolTypeObjCMetaClass;
2882 demangled_is_synthesized = true;
2883 }
2884 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
2885 {
2886 symbol_name_non_abi_mangled = symbol_name + 1;
2887 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2888 type = eSymbolTypeObjCIVar;
2889 demangled_is_synthesized = true;
2890 }
2891 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002892 else
2893 {
Jason Molendaa5609c82012-06-21 01:51:02 +00002894 if (nlist.n_value != 0)
2895 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2896 type = eSymbolTypeData;
2897 }
2898 break;
2899
Charles Davis510938e2013-08-27 05:04:57 +00002900 case N_FNAME:
2901 // procedure name (f77 kludge): name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002902 type = eSymbolTypeCompiler;
2903 break;
2904
Charles Davis510938e2013-08-27 05:04:57 +00002905 case N_FUN:
2906 // procedure: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002907 if (symbol_name)
2908 {
2909 type = eSymbolTypeCode;
2910 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2911
Greg Claytond81088c2014-01-16 01:38:29 +00002912 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002913 // We use the current number of symbols in the symbol table in lieu of
2914 // using nlist_idx in case we ever start trimming entries out
2915 N_FUN_indexes.push_back(sym_idx);
2916 }
2917 else
2918 {
2919 type = eSymbolTypeCompiler;
2920
2921 if ( !N_FUN_indexes.empty() )
2922 {
2923 // Copy the size of the function into the original STAB entry so we don't have
2924 // to hunt for it later
2925 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
2926 N_FUN_indexes.pop_back();
2927 // We don't really need the end function STAB as it contains the size which
2928 // we already placed with the original symbol, so don't add it if we want a
2929 // minimal symbol table
Greg Clayton3046e662013-07-10 01:23:25 +00002930 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002931 }
2932 }
2933 break;
2934
Charles Davis510938e2013-08-27 05:04:57 +00002935 case N_STSYM:
2936 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00002937 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002938 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2939 type = eSymbolTypeData;
2940 break;
2941
Charles Davis510938e2013-08-27 05:04:57 +00002942 case N_LCSYM:
2943 // .lcomm symbol: name,,n_sect,type,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002944 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2945 type = eSymbolTypeCommonBlock;
2946 break;
2947
Charles Davis510938e2013-08-27 05:04:57 +00002948 case N_BNSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002949 // We use the current number of symbols in the symbol table in lieu of
2950 // using nlist_idx in case we ever start trimming entries out
Greg Clayton3046e662013-07-10 01:23:25 +00002951 // Skip these if we want minimal symbol tables
2952 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002953 break;
2954
Charles Davis510938e2013-08-27 05:04:57 +00002955 case N_ENSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002956 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
2957 // so that we can always skip the entire symbol if we need to navigate
2958 // more quickly at the source level when parsing STABS
Greg Clayton3046e662013-07-10 01:23:25 +00002959 // Skip these if we want minimal symbol tables
2960 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002961 break;
2962
2963
Charles Davis510938e2013-08-27 05:04:57 +00002964 case N_OPT:
2965 // emitted with gcc2_compiled and in gcc source
Jason Molendaa5609c82012-06-21 01:51:02 +00002966 type = eSymbolTypeCompiler;
2967 break;
2968
Charles Davis510938e2013-08-27 05:04:57 +00002969 case N_RSYM:
2970 // register sym: name,,NO_SECT,type,register
Jason Molendaa5609c82012-06-21 01:51:02 +00002971 type = eSymbolTypeVariable;
2972 break;
2973
Charles Davis510938e2013-08-27 05:04:57 +00002974 case N_SLINE:
2975 // src line: 0,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002976 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2977 type = eSymbolTypeLineEntry;
2978 break;
2979
Charles Davis510938e2013-08-27 05:04:57 +00002980 case N_SSYM:
2981 // structure elt: name,,NO_SECT,type,struct_offset
Jason Molendaa5609c82012-06-21 01:51:02 +00002982 type = eSymbolTypeVariableType;
2983 break;
2984
Charles Davis510938e2013-08-27 05:04:57 +00002985 case N_SO:
2986 // source file name
Jason Molendaa5609c82012-06-21 01:51:02 +00002987 type = eSymbolTypeSourceFile;
2988 if (symbol_name == NULL)
2989 {
Greg Clayton3046e662013-07-10 01:23:25 +00002990 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002991 if (N_SO_index != UINT32_MAX)
2992 {
2993 // Set the size of the N_SO to the terminating index of this N_SO
2994 // so that we can always skip the entire N_SO if we need to navigate
2995 // more quickly at the source level when parsing STABS
2996 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
Greg Clayton3046e662013-07-10 01:23:25 +00002997 symbol_ptr->SetByteSize(sym_idx);
Jason Molendaa5609c82012-06-21 01:51:02 +00002998 symbol_ptr->SetSizeIsSibling(true);
2999 }
3000 N_NSYM_indexes.clear();
3001 N_INCL_indexes.clear();
3002 N_BRAC_indexes.clear();
3003 N_COMM_indexes.clear();
3004 N_FUN_indexes.clear();
3005 N_SO_index = UINT32_MAX;
3006 }
3007 else
3008 {
3009 // We use the current number of symbols in the symbol table in lieu of
3010 // using nlist_idx in case we ever start trimming entries out
3011 const bool N_SO_has_full_path = symbol_name[0] == '/';
3012 if (N_SO_has_full_path)
3013 {
Greg Clayton3046e662013-07-10 01:23:25 +00003014 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00003015 {
3016 // We have two consecutive N_SO entries where the first contains a directory
3017 // and the second contains a full path.
Jason Molendad9d5cf52012-07-20 03:35:44 +00003018 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00003019 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3020 add_nlist = false;
3021 }
3022 else
3023 {
3024 // This is the first entry in a N_SO that contains a directory or
3025 // a full path to the source file
3026 N_SO_index = sym_idx;
3027 }
3028 }
Greg Clayton3046e662013-07-10 01:23:25 +00003029 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00003030 {
3031 // This is usually the second N_SO entry that contains just the filename,
3032 // so here we combine it with the first one if we are minimizing the symbol table
3033 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
3034 if (so_path && so_path[0])
3035 {
3036 std::string full_so_path (so_path);
Greg Clayton0662d962012-09-07 20:29:13 +00003037 const size_t double_slash_pos = full_so_path.find("//");
3038 if (double_slash_pos != std::string::npos)
3039 {
3040 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003041 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Clayton0662d962012-09-07 20:29:13 +00003042 // and the second is the directory for the source file so you end up with
3043 // a path that looks like "/tmp/src//tmp/src/"
3044 FileSpec so_dir(so_path, false);
3045 if (!so_dir.Exists())
3046 {
3047 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3048 if (so_dir.Exists())
3049 {
3050 // Trim off the incorrect path
3051 full_so_path.erase(0, double_slash_pos + 1);
3052 }
3053 }
3054 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003055 if (*full_so_path.rbegin() != '/')
3056 full_so_path += '/';
3057 full_so_path += symbol_name;
Jason Molendad9d5cf52012-07-20 03:35:44 +00003058 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00003059 add_nlist = false;
3060 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3061 }
3062 }
Greg Clayton946f8902012-09-05 22:30:51 +00003063 else
3064 {
3065 // This could be a relative path to a N_SO
3066 N_SO_index = sym_idx;
3067 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003068 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003069 break;
3070
Charles Davis510938e2013-08-27 05:04:57 +00003071 case N_OSO:
3072 // object file name: name,,0,0,st_mtime
Jason Molendaa5609c82012-06-21 01:51:02 +00003073 type = eSymbolTypeObjectFile;
3074 break;
3075
Charles Davis510938e2013-08-27 05:04:57 +00003076 case N_LSYM:
3077 // local sym: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003078 type = eSymbolTypeLocal;
3079 break;
3080
3081 //----------------------------------------------------------------------
3082 // INCL scopes
3083 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003084 case N_BINCL:
3085 // include file beginning: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003086 // We use the current number of symbols in the symbol table in lieu of
3087 // using nlist_idx in case we ever start trimming entries out
3088 N_INCL_indexes.push_back(sym_idx);
3089 type = eSymbolTypeScopeBegin;
3090 break;
3091
Charles Davis510938e2013-08-27 05:04:57 +00003092 case N_EINCL:
3093 // include file end: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003094 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3095 // so that we can always skip the entire symbol if we need to navigate
3096 // more quickly at the source level when parsing STABS
3097 if ( !N_INCL_indexes.empty() )
3098 {
3099 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3100 symbol_ptr->SetByteSize(sym_idx + 1);
3101 symbol_ptr->SetSizeIsSibling(true);
3102 N_INCL_indexes.pop_back();
3103 }
3104 type = eSymbolTypeScopeEnd;
3105 break;
3106
Charles Davis510938e2013-08-27 05:04:57 +00003107 case N_SOL:
3108 // #included file name: name,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003109 type = eSymbolTypeHeaderFile;
3110
3111 // We currently don't use the header files on darwin
Greg Clayton3046e662013-07-10 01:23:25 +00003112 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00003113 break;
3114
Charles Davis510938e2013-08-27 05:04:57 +00003115 case N_PARAMS:
3116 // compiler parameters: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003117 type = eSymbolTypeCompiler;
3118 break;
3119
Charles Davis510938e2013-08-27 05:04:57 +00003120 case N_VERSION:
3121 // compiler version: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003122 type = eSymbolTypeCompiler;
3123 break;
3124
Charles Davis510938e2013-08-27 05:04:57 +00003125 case N_OLEVEL:
3126 // compiler -O level: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003127 type = eSymbolTypeCompiler;
3128 break;
3129
Charles Davis510938e2013-08-27 05:04:57 +00003130 case N_PSYM:
3131 // parameter: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003132 type = eSymbolTypeVariable;
3133 break;
3134
Charles Davis510938e2013-08-27 05:04:57 +00003135 case N_ENTRY:
3136 // alternate entry: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003137 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3138 type = eSymbolTypeLineEntry;
3139 break;
3140
3141 //----------------------------------------------------------------------
3142 // Left and Right Braces
3143 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003144 case N_LBRAC:
3145 // left bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003146 // We use the current number of symbols in the symbol table in lieu of
3147 // using nlist_idx in case we ever start trimming entries out
3148 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3149 N_BRAC_indexes.push_back(sym_idx);
3150 type = eSymbolTypeScopeBegin;
3151 break;
3152
Charles Davis510938e2013-08-27 05:04:57 +00003153 case N_RBRAC:
3154 // right bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003155 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
3156 // so that we can always skip the entire symbol if we need to navigate
3157 // more quickly at the source level when parsing STABS
3158 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3159 if ( !N_BRAC_indexes.empty() )
3160 {
3161 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
3162 symbol_ptr->SetByteSize(sym_idx + 1);
3163 symbol_ptr->SetSizeIsSibling(true);
3164 N_BRAC_indexes.pop_back();
3165 }
3166 type = eSymbolTypeScopeEnd;
3167 break;
3168
Charles Davis510938e2013-08-27 05:04:57 +00003169 case N_EXCL:
3170 // deleted include file: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003171 type = eSymbolTypeHeaderFile;
3172 break;
3173
3174 //----------------------------------------------------------------------
3175 // COMM scopes
3176 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003177 case N_BCOMM:
3178 // begin common: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003179 // We use the current number of symbols in the symbol table in lieu of
3180 // using nlist_idx in case we ever start trimming entries out
3181 type = eSymbolTypeScopeBegin;
3182 N_COMM_indexes.push_back(sym_idx);
3183 break;
3184
Charles Davis510938e2013-08-27 05:04:57 +00003185 case N_ECOML:
3186 // end common (local name): 0,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003187 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3188 // Fall through
3189
Charles Davis510938e2013-08-27 05:04:57 +00003190 case N_ECOMM:
3191 // end common: name,,n_sect,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003192 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
3193 // so that we can always skip the entire symbol if we need to navigate
3194 // more quickly at the source level when parsing STABS
3195 if ( !N_COMM_indexes.empty() )
3196 {
3197 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
3198 symbol_ptr->SetByteSize(sym_idx + 1);
3199 symbol_ptr->SetSizeIsSibling(true);
3200 N_COMM_indexes.pop_back();
3201 }
3202 type = eSymbolTypeScopeEnd;
3203 break;
3204
Charles Davis510938e2013-08-27 05:04:57 +00003205 case N_LENG:
3206 // second stab entry with length information
Jason Molendaa5609c82012-06-21 01:51:02 +00003207 type = eSymbolTypeAdditional;
3208 break;
3209
3210 default: break;
3211 }
3212 }
3213 else
3214 {
Charles Davis510938e2013-08-27 05:04:57 +00003215 //uint8_t n_pext = N_PEXT & nlist.n_type;
3216 uint8_t n_type = N_TYPE & nlist.n_type;
3217 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Jason Molendaa5609c82012-06-21 01:51:02 +00003218
3219 switch (n_type)
3220 {
Greg Clayton60038be2015-02-14 00:51:13 +00003221 case N_INDR:
3222 {
3223 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3224 if (reexport_name_cstr && reexport_name_cstr[0])
3225 {
3226 type = eSymbolTypeReExported;
3227 ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
3228 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3229 set_value = false;
3230 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3231 indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3232 }
3233 else
3234 type = eSymbolTypeUndefined;
3235 }
3236 break;
3237
Charles Davis510938e2013-08-27 05:04:57 +00003238 case N_UNDF:
Greg Clayton786ad182015-03-03 01:40:46 +00003239 if (symbol_name && symbol_name[0])
Greg Clayton60038be2015-02-14 00:51:13 +00003240 {
3241 ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
3242 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3243 }
3244 // Fall through
3245 case N_PBUD:
Jason Molendaa5609c82012-06-21 01:51:02 +00003246 type = eSymbolTypeUndefined;
3247 break;
3248
Charles Davis510938e2013-08-27 05:04:57 +00003249 case N_ABS:
Jason Molendaa5609c82012-06-21 01:51:02 +00003250 type = eSymbolTypeAbsolute;
3251 break;
3252
Charles Davis510938e2013-08-27 05:04:57 +00003253 case N_SECT:
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003254 {
3255 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00003256
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003257 if (symbol_section == NULL)
Jason Molendaa5609c82012-06-21 01:51:02 +00003258 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003259 // TODO: warn about this?
3260 add_nlist = false;
3261 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003262 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003263
3264 if (TEXT_eh_frame_sectID == nlist.n_sect)
Jason Molendaa5609c82012-06-21 01:51:02 +00003265 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003266 type = eSymbolTypeException;
3267 }
3268 else
3269 {
Charles Davis510938e2013-08-27 05:04:57 +00003270 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003271
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003272 switch (section_type)
Jason Molendaa5609c82012-06-21 01:51:02 +00003273 {
Charles Davis510938e2013-08-27 05:04:57 +00003274 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
3275 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
3276 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
3277 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
3278 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
3279 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
3280 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
3281 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
3282 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00003283 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
3284 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
3285 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
3286 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00003287 default:
3288 switch (symbol_section->GetType())
3289 {
3290 case lldb::eSectionTypeCode:
3291 type = eSymbolTypeCode;
3292 break;
3293 case eSectionTypeData:
3294 case eSectionTypeDataCString: // Inlined C string data
3295 case eSectionTypeDataCStringPointers: // Pointers to C string data
3296 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
3297 case eSectionTypeData4:
3298 case eSectionTypeData8:
3299 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00003300 type = eSymbolTypeData;
3301 break;
3302 default:
3303 break;
3304 }
3305 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003306 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003307
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003308 if (type == eSymbolTypeInvalid)
3309 {
3310 const char *symbol_sect_name = symbol_section->GetName().AsCString();
3311 if (symbol_section->IsDescendant (text_section_sp.get()))
3312 {
Charles Davis510938e2013-08-27 05:04:57 +00003313 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3314 S_ATTR_SELF_MODIFYING_CODE |
3315 S_ATTR_SOME_INSTRUCTIONS))
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003316 type = eSymbolTypeData;
3317 else
3318 type = eSymbolTypeCode;
3319 }
Greg Claytona381e102015-07-27 23:21:05 +00003320 else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3321 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
3322 symbol_section->IsDescendant(data_const_section_sp.get()))
Jason Molendaa5609c82012-06-21 01:51:02 +00003323 {
3324 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
3325 {
3326 type = eSymbolTypeRuntime;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003327
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003328 if (symbol_name &&
3329 symbol_name[0] == '_' &&
3330 symbol_name[1] == 'O' &&
Jason Molendaa5609c82012-06-21 01:51:02 +00003331 symbol_name[2] == 'B')
3332 {
3333 llvm::StringRef symbol_name_ref(symbol_name);
Jason Molendaa5609c82012-06-21 01:51:02 +00003334 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3335 {
3336 symbol_name_non_abi_mangled = symbol_name + 1;
3337 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3338 type = eSymbolTypeObjCClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003339 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003340 }
3341 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3342 {
3343 symbol_name_non_abi_mangled = symbol_name + 1;
3344 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3345 type = eSymbolTypeObjCMetaClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003346 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003347 }
3348 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3349 {
3350 symbol_name_non_abi_mangled = symbol_name + 1;
3351 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3352 type = eSymbolTypeObjCIVar;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003353 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003354 }
3355 }
3356 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003357 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
Jason Molendaa5609c82012-06-21 01:51:02 +00003358 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003359 type = eSymbolTypeException;
Jason Molendaa5609c82012-06-21 01:51:02 +00003360 }
3361 else
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003362 {
3363 type = eSymbolTypeData;
3364 }
3365 }
3366 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
3367 {
3368 type = eSymbolTypeTrampoline;
3369 }
3370 else if (symbol_section->IsDescendant(objc_section_sp.get()))
3371 {
3372 type = eSymbolTypeRuntime;
3373 if (symbol_name && symbol_name[0] == '.')
3374 {
3375 llvm::StringRef symbol_name_ref(symbol_name);
3376 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
3377 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
Jason Molendaa5609c82012-06-21 01:51:02 +00003378 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003379 symbol_name_non_abi_mangled = symbol_name;
3380 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
3381 type = eSymbolTypeObjCClass;
3382 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003383 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003384 }
3385 }
3386 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003387 }
3388 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003389 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003390 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003391 }
3392
3393 if (add_nlist)
3394 {
3395 uint64_t symbol_value = nlist.n_value;
Jason Molendaa5609c82012-06-21 01:51:02 +00003396 if (symbol_name_non_abi_mangled)
3397 {
Jason Molendad9d5cf52012-07-20 03:35:44 +00003398 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
3399 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Jason Molendaa5609c82012-06-21 01:51:02 +00003400 }
3401 else
3402 {
Greg Clayton3046e662013-07-10 01:23:25 +00003403 bool symbol_name_is_mangled = false;
3404
Jason Molendaa5609c82012-06-21 01:51:02 +00003405 if (symbol_name && symbol_name[0] == '_')
3406 {
3407 symbol_name_is_mangled = symbol_name[1] == '_';
3408 symbol_name++; // Skip the leading underscore
3409 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003410
Jason Molendaa5609c82012-06-21 01:51:02 +00003411 if (symbol_name)
3412 {
Greg Claytondacc4a92013-05-14 22:19:37 +00003413 ConstString const_symbol_name(symbol_name);
Greg Claytondacc4a92013-05-14 22:19:37 +00003414 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Clayton3046e662013-07-10 01:23:25 +00003415 if (is_gsym && is_debug)
Greg Clayton14cd13c2015-07-01 23:29:06 +00003416 {
3417 const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
3418 if (gsym_name)
3419 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3420 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003421 }
3422 }
3423 if (symbol_section)
3424 {
3425 const addr_t section_file_addr = symbol_section->GetFileAddress();
3426 if (symbol_byte_size == 0 && function_starts_count > 0)
3427 {
3428 addr_t symbol_lookup_file_addr = nlist.n_value;
3429 // Do an exact address match for non-ARM addresses, else get the closest since
3430 // the symbol might be a thumb symbol which has an address with bit zero set
3431 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
3432 if (is_arm && func_start_entry)
3433 {
3434 // Verify that the function start address is the symbol address (ARM)
3435 // or the symbol address + 1 (thumb)
3436 if (func_start_entry->addr != symbol_lookup_file_addr &&
3437 func_start_entry->addr != (symbol_lookup_file_addr + 1))
3438 {
3439 // Not the right entry, NULL it out...
3440 func_start_entry = NULL;
3441 }
3442 }
3443 if (func_start_entry)
3444 {
3445 func_start_entry->data = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003446
Jason Molendaa5609c82012-06-21 01:51:02 +00003447 addr_t symbol_file_addr = func_start_entry->addr;
3448 uint32_t symbol_flags = 0;
3449 if (is_arm)
3450 {
3451 if (symbol_file_addr & 1)
3452 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Greg Claytonb887da12015-07-16 19:50:57 +00003453 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Jason Molendaa5609c82012-06-21 01:51:02 +00003454 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003455
Jason Molendaa5609c82012-06-21 01:51:02 +00003456 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3457 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3458 if (next_func_start_entry)
3459 {
3460 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3461 // Be sure the clear the Thumb address bit when we calculate the size
3462 // from the current and next address
3463 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00003464 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Jason Molendaa5609c82012-06-21 01:51:02 +00003465 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
3466 }
3467 else
3468 {
3469 symbol_byte_size = section_end_file_addr - symbol_file_addr;
3470 }
3471 }
3472 }
3473 symbol_value -= section_file_addr;
3474 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003475
Greg Claytondacc4a92013-05-14 22:19:37 +00003476 if (is_debug == false)
3477 {
3478 if (type == eSymbolTypeCode)
3479 {
3480 // See if we can find a N_FUN entry for any code symbols.
3481 // If we do find a match, and the name matches, then we
3482 // can merge the two into just the function symbol to avoid
3483 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003484 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3485 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3486 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003487 {
Greg Claytond81088c2014-01-16 01:38:29 +00003488 bool found_it = false;
3489 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003490 {
Greg Claytond81088c2014-01-16 01:38:29 +00003491 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3492 {
3493 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3494 // We just need the flags from the linker symbol, so put these flags
3495 // into the N_FUN flags to avoid duplicate symbols in the symbol table
3496 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3497 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3498 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
3499 sym[pos->second].SetType (eSymbolTypeResolver);
3500 sym[sym_idx].Clear();
3501 found_it = true;
3502 break;
3503 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003504 }
Greg Claytond81088c2014-01-16 01:38:29 +00003505 if (found_it)
3506 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003507 }
Jim Inghamea3ac272014-01-10 22:55:37 +00003508 else
3509 {
Greg Claytond81088c2014-01-16 01:38:29 +00003510 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00003511 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00003512 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003513 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00003514 else if (type == eSymbolTypeData ||
3515 type == eSymbolTypeObjCClass ||
3516 type == eSymbolTypeObjCMetaClass ||
3517 type == eSymbolTypeObjCIVar )
Greg Claytondacc4a92013-05-14 22:19:37 +00003518 {
3519 // See if we can find a N_STSYM entry for any data symbols.
3520 // If we do find a match, and the name matches, then we
3521 // can merge the two into just the Static symbol to avoid
3522 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003523 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3524 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
3525 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003526 {
Greg Claytond81088c2014-01-16 01:38:29 +00003527 bool found_it = false;
3528 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003529 {
Greg Claytond81088c2014-01-16 01:38:29 +00003530 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3531 {
3532 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3533 // We just need the flags from the linker symbol, so put these flags
3534 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3535 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3536 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3537 sym[sym_idx].Clear();
3538 found_it = true;
3539 break;
3540 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003541 }
Greg Claytond81088c2014-01-16 01:38:29 +00003542 if (found_it)
3543 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003544 }
3545 else
3546 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00003547 const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
3548 if (gsym_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003549 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00003550 // Combine N_GSYM stab entries with the non stab symbol
3551 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
3552 if (pos != N_GSYM_name_to_sym_idx.end())
3553 {
3554 const uint32_t GSYM_sym_idx = pos->second;
3555 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
3556 // Copy the address, because often the N_GSYM address has an invalid address of zero
3557 // when the global is a common symbol
3558 sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
3559 sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
3560 // We just need the flags from the linker symbol, so put these flags
3561 // into the N_GSYM flags to avoid duplicate symbols in the symbol table
3562 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3563 sym[sym_idx].Clear();
3564 continue;
3565 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003566 }
3567 }
3568 }
3569 }
3570
Jason Molendaa5609c82012-06-21 01:51:02 +00003571 sym[sym_idx].SetID (nlist_idx);
3572 sym[sym_idx].SetType (type);
Greg Clayton60038be2015-02-14 00:51:13 +00003573 if (set_value)
3574 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00003575 sym[sym_idx].GetAddressRef().SetSection (symbol_section);
3576 sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
Greg Clayton60038be2015-02-14 00:51:13 +00003577 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003578 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003579
Jason Molendaa5609c82012-06-21 01:51:02 +00003580 if (symbol_byte_size > 0)
3581 sym[sym_idx].SetByteSize(symbol_byte_size);
3582
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003583 if (demangled_is_synthesized)
3584 sym[sym_idx].SetDemangledNameIsSynthesized(true);
Jason Molendaa5609c82012-06-21 01:51:02 +00003585 ++sym_idx;
3586 }
3587 else
3588 {
3589 sym[sym_idx].Clear();
3590 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003591
Jason Molendaa5609c82012-06-21 01:51:02 +00003592 }
3593 /////////////////////////////
3594 }
3595 break; // No more entries to consider
3596 }
3597 }
Greg Clayton60038be2015-02-14 00:51:13 +00003598
3599 for (const auto &pos :reexport_shlib_needs_fixup)
3600 {
3601 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3602 if (undef_pos != undefined_name_to_desc.end())
3603 {
3604 const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3605 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
3606 sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
3607 }
3608 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003609 }
3610 }
3611 }
3612 }
3613 }
3614
3615 // Must reset this in case it was mutated above!
3616 nlist_data_offset = 0;
3617#endif
Jim Inghamea3ac272014-01-10 22:55:37 +00003618
Greg Claytonfd814c52013-08-13 01:42:25 +00003619 if (nlist_data.GetByteSize() > 0)
Jason Molendaa5609c82012-06-21 01:51:02 +00003620 {
Jason Molendaa5609c82012-06-21 01:51:02 +00003621
Greg Claytonfd814c52013-08-13 01:42:25 +00003622 // If the sym array was not created while parsing the DSC unmapped
3623 // symbols, create it now.
3624 if (sym == NULL)
Greg Clayton4c82d422012-05-18 23:20:01 +00003625 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003626 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3627 num_syms = symtab->GetNumSymbols();
3628 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003629
Greg Claytonfd814c52013-08-13 01:42:25 +00003630 if (unmapped_local_symbols_found)
3631 {
3632 assert(m_dysymtab.ilocalsym == 0);
3633 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3634 nlist_idx = m_dysymtab.nlocalsym;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003635 }
Greg Claytondebb8812012-05-25 17:04:00 +00003636 else
3637 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003638 nlist_idx = 0;
Greg Claytondebb8812012-05-25 17:04:00 +00003639 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003640
Greg Clayton60038be2015-02-14 00:51:13 +00003641 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
3642 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
3643 UndefinedNameToDescMap undefined_name_to_desc;
3644 SymbolIndexToName reexport_shlib_needs_fixup;
Greg Claytonfd814c52013-08-13 01:42:25 +00003645 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003646 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003647 struct nlist_64 nlist;
3648 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
3649 break;
3650
3651 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
3652 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
3653 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
3654 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
3655 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
3656
3657 SymbolType type = eSymbolTypeInvalid;
3658 const char *symbol_name = NULL;
3659
3660 if (have_strtab_data)
Greg Clayton77ccca72011-12-30 00:32:24 +00003661 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003662 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003663
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003664 if (symbol_name == NULL)
3665 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003666 // No symbol should be NULL, even the symbols with no
3667 // string values should have an offset zero which points
3668 // to an empty C-string
3669 Host::SystemLog (Host::eSystemLogError,
3670 "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
3671 nlist_idx,
3672 nlist.n_strx,
3673 module_sp->GetFileSpec().GetPath().c_str());
3674 continue;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003675 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003676 if (symbol_name[0] == '\0')
3677 symbol_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003678 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003679 else
3680 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003681 const addr_t str_addr = strtab_addr + nlist.n_strx;
3682 Error str_error;
3683 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
3684 symbol_name = memory_symbol_name.c_str();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003685 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003686 const char *symbol_name_non_abi_mangled = NULL;
3687
3688 SectionSP symbol_section;
3689 lldb::addr_t symbol_byte_size = 0;
3690 bool add_nlist = true;
3691 bool is_gsym = false;
Charles Davis510938e2013-08-27 05:04:57 +00003692 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00003693 bool demangled_is_synthesized = false;
Greg Clayton60038be2015-02-14 00:51:13 +00003694 bool set_value = true;
Greg Claytonfd814c52013-08-13 01:42:25 +00003695 assert (sym_idx < num_syms);
3696
3697 sym[sym_idx].SetDebug (is_debug);
3698
3699 if (is_debug)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003700 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003701 switch (nlist.n_type)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003702 {
Charles Davis510938e2013-08-27 05:04:57 +00003703 case N_GSYM:
3704 // global symbol: name,,NO_SECT,type,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003705 // Sometimes the N_GSYM value contains the address.
Jason Molenda4e7511e2013-03-06 23:19:17 +00003706
Greg Claytonfd814c52013-08-13 01:42:25 +00003707 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
3708 // have the same address, but we want to ensure that we always find only the real symbol,
3709 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
3710 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
3711 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
3712 // same address.
Greg Clayton1e28adf2015-02-25 17:25:02 +00003713 is_gsym = true;
3714 sym[sym_idx].SetExternal(true);
Greg Clayton29e08cb2012-03-14 01:53:24 +00003715
Greg Clayton1e28adf2015-02-25 17:25:02 +00003716 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
3717 {
3718 llvm::StringRef symbol_name_ref(symbol_name);
3719 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3720 {
3721 symbol_name_non_abi_mangled = symbol_name + 1;
3722 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3723 type = eSymbolTypeObjCClass;
3724 demangled_is_synthesized = true;
3725
3726 }
3727 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3728 {
3729 symbol_name_non_abi_mangled = symbol_name + 1;
3730 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3731 type = eSymbolTypeObjCMetaClass;
3732 demangled_is_synthesized = true;
3733 }
3734 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3735 {
3736 symbol_name_non_abi_mangled = symbol_name + 1;
3737 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3738 type = eSymbolTypeObjCIVar;
3739 demangled_is_synthesized = true;
3740 }
3741 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003742 else
3743 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003744 if (nlist.n_value != 0)
3745 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3746 type = eSymbolTypeData;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003747 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003748 break;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003749
Charles Davis510938e2013-08-27 05:04:57 +00003750 case N_FNAME:
3751 // procedure name (f77 kludge): name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003752 type = eSymbolTypeCompiler;
3753 break;
3754
Charles Davis510938e2013-08-27 05:04:57 +00003755 case N_FUN:
3756 // procedure: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003757 if (symbol_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003758 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003759 type = eSymbolTypeCode;
3760 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3761
Greg Claytond81088c2014-01-16 01:38:29 +00003762 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003763 // We use the current number of symbols in the symbol table in lieu of
3764 // using nlist_idx in case we ever start trimming entries out
3765 N_FUN_indexes.push_back(sym_idx);
Greg Claytondacc4a92013-05-14 22:19:37 +00003766 }
3767 else
3768 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003769 type = eSymbolTypeCompiler;
3770
3771 if ( !N_FUN_indexes.empty() )
Greg Claytondacc4a92013-05-14 22:19:37 +00003772 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003773 // Copy the size of the function into the original STAB entry so we don't have
3774 // to hunt for it later
3775 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
3776 N_FUN_indexes.pop_back();
3777 // We don't really need the end function STAB as it contains the size which
3778 // we already placed with the original symbol, so don't add it if we want a
3779 // minimal symbol table
3780 add_nlist = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00003781 }
3782 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003783 break;
3784
Charles Davis510938e2013-08-27 05:04:57 +00003785 case N_STSYM:
3786 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00003787 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003788 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3789 type = eSymbolTypeData;
3790 break;
3791
Charles Davis510938e2013-08-27 05:04:57 +00003792 case N_LCSYM:
3793 // .lcomm symbol: name,,n_sect,type,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003794 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3795 type = eSymbolTypeCommonBlock;
3796 break;
3797
Charles Davis510938e2013-08-27 05:04:57 +00003798 case N_BNSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003799 // We use the current number of symbols in the symbol table in lieu of
3800 // using nlist_idx in case we ever start trimming entries out
3801 // Skip these if we want minimal symbol tables
3802 add_nlist = false;
3803 break;
3804
Charles Davis510938e2013-08-27 05:04:57 +00003805 case N_ENSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003806 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
3807 // so that we can always skip the entire symbol if we need to navigate
3808 // more quickly at the source level when parsing STABS
3809 // Skip these if we want minimal symbol tables
3810 add_nlist = false;
3811 break;
3812
3813
Charles Davis510938e2013-08-27 05:04:57 +00003814 case N_OPT:
3815 // emitted with gcc2_compiled and in gcc source
Greg Claytonfd814c52013-08-13 01:42:25 +00003816 type = eSymbolTypeCompiler;
3817 break;
3818
Charles Davis510938e2013-08-27 05:04:57 +00003819 case N_RSYM:
3820 // register sym: name,,NO_SECT,type,register
Greg Claytonfd814c52013-08-13 01:42:25 +00003821 type = eSymbolTypeVariable;
3822 break;
3823
Charles Davis510938e2013-08-27 05:04:57 +00003824 case N_SLINE:
3825 // src line: 0,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003826 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3827 type = eSymbolTypeLineEntry;
3828 break;
3829
Charles Davis510938e2013-08-27 05:04:57 +00003830 case N_SSYM:
3831 // structure elt: name,,NO_SECT,type,struct_offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003832 type = eSymbolTypeVariableType;
3833 break;
3834
Charles Davis510938e2013-08-27 05:04:57 +00003835 case N_SO:
3836 // source file name
Greg Claytonfd814c52013-08-13 01:42:25 +00003837 type = eSymbolTypeSourceFile;
3838 if (symbol_name == NULL)
3839 {
3840 add_nlist = false;
3841 if (N_SO_index != UINT32_MAX)
3842 {
3843 // Set the size of the N_SO to the terminating index of this N_SO
3844 // so that we can always skip the entire N_SO if we need to navigate
3845 // more quickly at the source level when parsing STABS
3846 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
3847 symbol_ptr->SetByteSize(sym_idx);
3848 symbol_ptr->SetSizeIsSibling(true);
3849 }
3850 N_NSYM_indexes.clear();
3851 N_INCL_indexes.clear();
3852 N_BRAC_indexes.clear();
3853 N_COMM_indexes.clear();
3854 N_FUN_indexes.clear();
3855 N_SO_index = UINT32_MAX;
3856 }
3857 else
3858 {
3859 // We use the current number of symbols in the symbol table in lieu of
3860 // using nlist_idx in case we ever start trimming entries out
3861 const bool N_SO_has_full_path = symbol_name[0] == '/';
3862 if (N_SO_has_full_path)
3863 {
3864 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3865 {
3866 // We have two consecutive N_SO entries where the first contains a directory
3867 // and the second contains a full path.
3868 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
3869 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3870 add_nlist = false;
3871 }
3872 else
3873 {
3874 // This is the first entry in a N_SO that contains a directory or
3875 // a full path to the source file
3876 N_SO_index = sym_idx;
3877 }
3878 }
3879 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3880 {
3881 // This is usually the second N_SO entry that contains just the filename,
3882 // so here we combine it with the first one if we are minimizing the symbol table
Greg Claytonddaf6a72015-07-08 22:32:23 +00003883 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString();
Greg Claytonfd814c52013-08-13 01:42:25 +00003884 if (so_path && so_path[0])
3885 {
3886 std::string full_so_path (so_path);
3887 const size_t double_slash_pos = full_so_path.find("//");
3888 if (double_slash_pos != std::string::npos)
3889 {
3890 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003891 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Claytonfd814c52013-08-13 01:42:25 +00003892 // and the second is the directory for the source file so you end up with
3893 // a path that looks like "/tmp/src//tmp/src/"
3894 FileSpec so_dir(so_path, false);
3895 if (!so_dir.Exists())
3896 {
3897 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3898 if (so_dir.Exists())
3899 {
3900 // Trim off the incorrect path
3901 full_so_path.erase(0, double_slash_pos + 1);
3902 }
3903 }
3904 }
3905 if (*full_so_path.rbegin() != '/')
3906 full_so_path += '/';
3907 full_so_path += symbol_name;
3908 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
3909 add_nlist = false;
3910 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3911 }
3912 }
3913 else
3914 {
3915 // This could be a relative path to a N_SO
3916 N_SO_index = sym_idx;
3917 }
3918 }
3919
3920 break;
3921
Charles Davis510938e2013-08-27 05:04:57 +00003922 case N_OSO:
3923 // object file name: name,,0,0,st_mtime
Greg Claytonfd814c52013-08-13 01:42:25 +00003924 type = eSymbolTypeObjectFile;
3925 break;
3926
Charles Davis510938e2013-08-27 05:04:57 +00003927 case N_LSYM:
3928 // local sym: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003929 type = eSymbolTypeLocal;
3930 break;
3931
3932 //----------------------------------------------------------------------
3933 // INCL scopes
3934 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003935 case N_BINCL:
3936 // include file beginning: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00003937 // We use the current number of symbols in the symbol table in lieu of
3938 // using nlist_idx in case we ever start trimming entries out
3939 N_INCL_indexes.push_back(sym_idx);
3940 type = eSymbolTypeScopeBegin;
3941 break;
3942
Charles Davis510938e2013-08-27 05:04:57 +00003943 case N_EINCL:
3944 // include file end: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003945 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3946 // so that we can always skip the entire symbol if we need to navigate
3947 // more quickly at the source level when parsing STABS
3948 if ( !N_INCL_indexes.empty() )
3949 {
3950 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3951 symbol_ptr->SetByteSize(sym_idx + 1);
3952 symbol_ptr->SetSizeIsSibling(true);
3953 N_INCL_indexes.pop_back();
3954 }
3955 type = eSymbolTypeScopeEnd;
3956 break;
3957
Charles Davis510938e2013-08-27 05:04:57 +00003958 case N_SOL:
3959 // #included file name: name,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003960 type = eSymbolTypeHeaderFile;
3961
3962 // We currently don't use the header files on darwin
3963 add_nlist = false;
3964 break;
3965
Charles Davis510938e2013-08-27 05:04:57 +00003966 case N_PARAMS:
3967 // compiler parameters: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003968 type = eSymbolTypeCompiler;
3969 break;
3970
Charles Davis510938e2013-08-27 05:04:57 +00003971 case N_VERSION:
3972 // compiler version: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003973 type = eSymbolTypeCompiler;
3974 break;
3975
Charles Davis510938e2013-08-27 05:04:57 +00003976 case N_OLEVEL:
3977 // compiler -O level: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003978 type = eSymbolTypeCompiler;
3979 break;
3980
Charles Davis510938e2013-08-27 05:04:57 +00003981 case N_PSYM:
3982 // parameter: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003983 type = eSymbolTypeVariable;
3984 break;
3985
Charles Davis510938e2013-08-27 05:04:57 +00003986 case N_ENTRY:
3987 // alternate entry: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003988 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3989 type = eSymbolTypeLineEntry;
3990 break;
3991
3992 //----------------------------------------------------------------------
3993 // Left and Right Braces
3994 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003995 case N_LBRAC:
3996 // left bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003997 // We use the current number of symbols in the symbol table in lieu of
3998 // using nlist_idx in case we ever start trimming entries out
3999 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4000 N_BRAC_indexes.push_back(sym_idx);
4001 type = eSymbolTypeScopeBegin;
4002 break;
4003
Charles Davis510938e2013-08-27 05:04:57 +00004004 case N_RBRAC:
4005 // right bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004006 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
4007 // so that we can always skip the entire symbol if we need to navigate
4008 // more quickly at the source level when parsing STABS
4009 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4010 if ( !N_BRAC_indexes.empty() )
4011 {
4012 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
4013 symbol_ptr->SetByteSize(sym_idx + 1);
4014 symbol_ptr->SetSizeIsSibling(true);
4015 N_BRAC_indexes.pop_back();
4016 }
4017 type = eSymbolTypeScopeEnd;
4018 break;
4019
Charles Davis510938e2013-08-27 05:04:57 +00004020 case N_EXCL:
4021 // deleted include file: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00004022 type = eSymbolTypeHeaderFile;
4023 break;
4024
4025 //----------------------------------------------------------------------
4026 // COMM scopes
4027 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00004028 case N_BCOMM:
4029 // begin common: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004030 // We use the current number of symbols in the symbol table in lieu of
4031 // using nlist_idx in case we ever start trimming entries out
4032 type = eSymbolTypeScopeBegin;
4033 N_COMM_indexes.push_back(sym_idx);
4034 break;
4035
Charles Davis510938e2013-08-27 05:04:57 +00004036 case N_ECOML:
4037 // end common (local name): 0,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004038 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4039 // Fall through
4040
Charles Davis510938e2013-08-27 05:04:57 +00004041 case N_ECOMM:
4042 // end common: name,,n_sect,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004043 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
4044 // so that we can always skip the entire symbol if we need to navigate
4045 // more quickly at the source level when parsing STABS
4046 if ( !N_COMM_indexes.empty() )
4047 {
4048 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
4049 symbol_ptr->SetByteSize(sym_idx + 1);
4050 symbol_ptr->SetSizeIsSibling(true);
4051 N_COMM_indexes.pop_back();
4052 }
4053 type = eSymbolTypeScopeEnd;
4054 break;
4055
Charles Davis510938e2013-08-27 05:04:57 +00004056 case N_LENG:
4057 // second stab entry with length information
Greg Claytonfd814c52013-08-13 01:42:25 +00004058 type = eSymbolTypeAdditional;
4059 break;
4060
4061 default: break;
4062 }
4063 }
4064 else
4065 {
Charles Davis510938e2013-08-27 05:04:57 +00004066 //uint8_t n_pext = N_PEXT & nlist.n_type;
4067 uint8_t n_type = N_TYPE & nlist.n_type;
4068 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00004069
4070 switch (n_type)
4071 {
Greg Clayton60038be2015-02-14 00:51:13 +00004072 case N_INDR:
4073 {
4074 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4075 if (reexport_name_cstr && reexport_name_cstr[0])
4076 {
4077 type = eSymbolTypeReExported;
4078 ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
4079 sym[sym_idx].SetReExportedSymbolName(reexport_name);
4080 set_value = false;
4081 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4082 indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
4083 }
4084 else
4085 type = eSymbolTypeUndefined;
4086 }
4087 break;
4088
Charles Davis510938e2013-08-27 05:04:57 +00004089 case N_UNDF:
Greg Clayton786ad182015-03-03 01:40:46 +00004090 if (symbol_name && symbol_name[0])
Greg Clayton60038be2015-02-14 00:51:13 +00004091 {
4092 ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
4093 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4094 }
4095 // Fall through
4096 case N_PBUD:
Greg Claytonfd814c52013-08-13 01:42:25 +00004097 type = eSymbolTypeUndefined;
4098 break;
4099
Charles Davis510938e2013-08-27 05:04:57 +00004100 case N_ABS:
Greg Claytonfd814c52013-08-13 01:42:25 +00004101 type = eSymbolTypeAbsolute;
4102 break;
4103
Charles Davis510938e2013-08-27 05:04:57 +00004104 case N_SECT:
Greg Claytonfd814c52013-08-13 01:42:25 +00004105 {
4106 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4107
4108 if (!symbol_section)
4109 {
4110 // TODO: warn about this?
4111 add_nlist = false;
4112 break;
4113 }
4114
4115 if (TEXT_eh_frame_sectID == nlist.n_sect)
4116 {
4117 type = eSymbolTypeException;
4118 }
4119 else
4120 {
Charles Davis510938e2013-08-27 05:04:57 +00004121 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Greg Claytonfd814c52013-08-13 01:42:25 +00004122
4123 switch (section_type)
4124 {
Charles Davis510938e2013-08-27 05:04:57 +00004125 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
4126 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
4127 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
4128 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
4129 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
4130 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
4131 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
4132 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
4133 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00004134 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
4135 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
4136 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
4137 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00004138 default:
4139 switch (symbol_section->GetType())
4140 {
4141 case lldb::eSectionTypeCode:
4142 type = eSymbolTypeCode;
4143 break;
4144 case eSectionTypeData:
4145 case eSectionTypeDataCString: // Inlined C string data
4146 case eSectionTypeDataCStringPointers: // Pointers to C string data
4147 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
4148 case eSectionTypeData4:
4149 case eSectionTypeData8:
4150 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00004151 type = eSymbolTypeData;
4152 break;
4153 default:
4154 break;
4155 }
4156 break;
Greg Claytonfd814c52013-08-13 01:42:25 +00004157 }
4158
4159 if (type == eSymbolTypeInvalid)
4160 {
4161 const char *symbol_sect_name = symbol_section->GetName().AsCString();
4162 if (symbol_section->IsDescendant (text_section_sp.get()))
4163 {
Charles Davis510938e2013-08-27 05:04:57 +00004164 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4165 S_ATTR_SELF_MODIFYING_CODE |
4166 S_ATTR_SOME_INSTRUCTIONS))
Greg Claytonfd814c52013-08-13 01:42:25 +00004167 type = eSymbolTypeData;
4168 else
4169 type = eSymbolTypeCode;
4170 }
4171 else
Greg Claytona381e102015-07-27 23:21:05 +00004172 if (symbol_section->IsDescendant(data_section_sp.get()) ||
4173 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
4174 symbol_section->IsDescendant(data_const_section_sp.get()))
Greg Claytonfd814c52013-08-13 01:42:25 +00004175 {
4176 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
4177 {
4178 type = eSymbolTypeRuntime;
4179
4180 if (symbol_name &&
4181 symbol_name[0] == '_' &&
4182 symbol_name[1] == 'O' &&
4183 symbol_name[2] == 'B')
4184 {
4185 llvm::StringRef symbol_name_ref(symbol_name);
Greg Claytonfd814c52013-08-13 01:42:25 +00004186 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
4187 {
4188 symbol_name_non_abi_mangled = symbol_name + 1;
4189 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
4190 type = eSymbolTypeObjCClass;
4191 demangled_is_synthesized = true;
4192 }
4193 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
4194 {
4195 symbol_name_non_abi_mangled = symbol_name + 1;
4196 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
4197 type = eSymbolTypeObjCMetaClass;
4198 demangled_is_synthesized = true;
4199 }
4200 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
4201 {
4202 symbol_name_non_abi_mangled = symbol_name + 1;
4203 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
4204 type = eSymbolTypeObjCIVar;
4205 demangled_is_synthesized = true;
4206 }
4207 }
4208 }
4209 else
4210 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
4211 {
4212 type = eSymbolTypeException;
4213 }
4214 else
4215 {
4216 type = eSymbolTypeData;
4217 }
4218 }
4219 else
4220 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
4221 {
4222 type = eSymbolTypeTrampoline;
4223 }
4224 else
4225 if (symbol_section->IsDescendant(objc_section_sp.get()))
4226 {
4227 type = eSymbolTypeRuntime;
4228 if (symbol_name && symbol_name[0] == '.')
4229 {
4230 llvm::StringRef symbol_name_ref(symbol_name);
4231 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
4232 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
4233 {
4234 symbol_name_non_abi_mangled = symbol_name;
4235 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4236 type = eSymbolTypeObjCClass;
4237 demangled_is_synthesized = true;
4238 }
4239 }
4240 }
4241 }
4242 }
4243 }
4244 break;
Greg Claytondacc4a92013-05-14 22:19:37 +00004245 }
4246 }
4247
Greg Claytonfd814c52013-08-13 01:42:25 +00004248 if (add_nlist)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004249 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004250 uint64_t symbol_value = nlist.n_value;
4251
4252 if (symbol_name_non_abi_mangled)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004253 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004254 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
4255 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
4256 }
4257 else
4258 {
4259 bool symbol_name_is_mangled = false;
4260
4261 if (symbol_name && symbol_name[0] == '_')
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004262 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004263 symbol_name_is_mangled = symbol_name[1] == '_';
4264 symbol_name++; // Skip the leading underscore
4265 }
4266
4267 if (symbol_name)
4268 {
4269 ConstString const_symbol_name(symbol_name);
4270 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Claytonfd814c52013-08-13 01:42:25 +00004271 }
4272 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004273
4274 if (is_gsym)
Greg Clayton14cd13c2015-07-01 23:29:06 +00004275 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004276 const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
Greg Clayton14cd13c2015-07-01 23:29:06 +00004277 if (gsym_name)
4278 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4279 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004280
Greg Claytonfd814c52013-08-13 01:42:25 +00004281 if (symbol_section)
4282 {
4283 const addr_t section_file_addr = symbol_section->GetFileAddress();
4284 if (symbol_byte_size == 0 && function_starts_count > 0)
4285 {
4286 addr_t symbol_lookup_file_addr = nlist.n_value;
4287 // Do an exact address match for non-ARM addresses, else get the closest since
4288 // the symbol might be a thumb symbol which has an address with bit zero set
4289 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
4290 if (is_arm && func_start_entry)
4291 {
4292 // Verify that the function start address is the symbol address (ARM)
4293 // or the symbol address + 1 (thumb)
4294 if (func_start_entry->addr != symbol_lookup_file_addr &&
4295 func_start_entry->addr != (symbol_lookup_file_addr + 1))
4296 {
4297 // Not the right entry, NULL it out...
4298 func_start_entry = NULL;
4299 }
4300 }
4301 if (func_start_entry)
4302 {
4303 func_start_entry->data = true;
4304
4305 addr_t symbol_file_addr = func_start_entry->addr;
4306 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004307 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Claytonfd814c52013-08-13 01:42:25 +00004308
4309 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4310 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4311 if (next_func_start_entry)
4312 {
4313 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4314 // Be sure the clear the Thumb address bit when we calculate the size
4315 // from the current and next address
4316 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004317 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Claytonfd814c52013-08-13 01:42:25 +00004318 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
4319 }
4320 else
4321 {
4322 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4323 }
4324 }
4325 }
4326 symbol_value -= section_file_addr;
4327 }
4328
4329 if (is_debug == false)
4330 {
4331 if (type == eSymbolTypeCode)
4332 {
4333 // See if we can find a N_FUN entry for any code symbols.
4334 // If we do find a match, and the name matches, then we
4335 // can merge the two into just the function symbol to avoid
4336 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004337 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4338 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4339 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004340 {
Greg Claytond81088c2014-01-16 01:38:29 +00004341 bool found_it = false;
4342 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004343 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004344 if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled))
Greg Claytond81088c2014-01-16 01:38:29 +00004345 {
4346 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4347 // We just need the flags from the linker symbol, so put these flags
4348 // into the N_FUN flags to avoid duplicate symbols in the symbol table
4349 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4350 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4351 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
4352 sym[pos->second].SetType (eSymbolTypeResolver);
4353 sym[sym_idx].Clear();
4354 found_it = true;
4355 break;
4356 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004357 }
Greg Claytond81088c2014-01-16 01:38:29 +00004358 if (found_it)
4359 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004360 }
Jim Inghamea3ac272014-01-10 22:55:37 +00004361 else
4362 {
4363 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00004364 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00004365 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004366 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004367 else if (type == eSymbolTypeData ||
4368 type == eSymbolTypeObjCClass ||
4369 type == eSymbolTypeObjCMetaClass ||
4370 type == eSymbolTypeObjCIVar )
Greg Claytonfd814c52013-08-13 01:42:25 +00004371 {
4372 // See if we can find a N_STSYM entry for any data symbols.
4373 // If we do find a match, and the name matches, then we
4374 // can merge the two into just the Static symbol to avoid
4375 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004376 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4377 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4378 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004379 {
Greg Claytond81088c2014-01-16 01:38:29 +00004380 bool found_it = false;
4381 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004382 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004383 if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled))
Greg Claytond81088c2014-01-16 01:38:29 +00004384 {
4385 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4386 // We just need the flags from the linker symbol, so put these flags
4387 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
4388 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4389 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4390 sym[sym_idx].Clear();
4391 found_it = true;
4392 break;
4393 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004394 }
Greg Claytond81088c2014-01-16 01:38:29 +00004395 if (found_it)
4396 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004397 }
4398 else
4399 {
4400 // Combine N_GSYM stab entries with the non stab symbol
Greg Claytonddaf6a72015-07-08 22:32:23 +00004401 const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
Greg Clayton14cd13c2015-07-01 23:29:06 +00004402 if (gsym_name)
Greg Claytonfd814c52013-08-13 01:42:25 +00004403 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00004404 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
4405 if (pos != N_GSYM_name_to_sym_idx.end())
4406 {
4407 const uint32_t GSYM_sym_idx = pos->second;
4408 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4409 // Copy the address, because often the N_GSYM address has an invalid address of zero
4410 // when the global is a common symbol
4411 sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
4412 sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
4413 // We just need the flags from the linker symbol, so put these flags
4414 // into the N_GSYM flags to avoid duplicate symbols in the symbol table
4415 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4416 sym[sym_idx].Clear();
4417 continue;
4418 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004419 }
4420 }
4421 }
4422 }
4423
4424 sym[sym_idx].SetID (nlist_idx);
4425 sym[sym_idx].SetType (type);
Greg Clayton60038be2015-02-14 00:51:13 +00004426 if (set_value)
4427 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004428 sym[sym_idx].GetAddressRef().SetSection (symbol_section);
4429 sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
Greg Clayton60038be2015-02-14 00:51:13 +00004430 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004431 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4432
4433 if (symbol_byte_size > 0)
4434 sym[sym_idx].SetByteSize(symbol_byte_size);
4435
4436 if (demangled_is_synthesized)
4437 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4438
4439 ++sym_idx;
4440 }
4441 else
4442 {
4443 sym[sym_idx].Clear();
4444 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004445 }
Greg Clayton60038be2015-02-14 00:51:13 +00004446
4447 for (const auto &pos :reexport_shlib_needs_fixup)
4448 {
4449 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4450 if (undef_pos != undefined_name_to_desc.end())
4451 {
4452 const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4453 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4454 sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
4455 }
4456 }
4457
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004458 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004459
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004460 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4461
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004462 if (function_starts_count > 0)
4463 {
4464 char synthetic_function_symbol[PATH_MAX];
4465 uint32_t num_synthetic_function_symbols = 0;
4466 for (i=0; i<function_starts_count; ++i)
4467 {
4468 if (function_starts.GetEntryRef (i).data == false)
4469 ++num_synthetic_function_symbols;
4470 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004471
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004472 if (num_synthetic_function_symbols > 0)
4473 {
4474 if (num_syms < sym_idx + num_synthetic_function_symbols)
4475 {
4476 num_syms = sym_idx + num_synthetic_function_symbols;
4477 sym = symtab->Resize (num_syms);
4478 }
4479 uint32_t synthetic_function_symbol_idx = 0;
4480 for (i=0; i<function_starts_count; ++i)
4481 {
4482 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
4483 if (func_start_entry->data == false)
4484 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004485 addr_t symbol_file_addr = func_start_entry->addr;
4486 uint32_t symbol_flags = 0;
4487 if (is_arm)
4488 {
4489 if (symbol_file_addr & 1)
4490 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Greg Claytonb887da12015-07-16 19:50:57 +00004491 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004492 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004493 Address symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004494 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004495 {
4496 SectionSP symbol_section (symbol_addr.GetSection());
4497 uint32_t symbol_byte_size = 0;
4498 if (symbol_section)
4499 {
4500 const addr_t section_file_addr = symbol_section->GetFileAddress();
4501 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4502 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4503 if (next_func_start_entry)
4504 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004505 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4506 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004507 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004508 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 +00004509 }
4510 else
4511 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004512 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004513 }
4514 snprintf (synthetic_function_symbol,
4515 sizeof(synthetic_function_symbol),
4516 "___lldb_unnamed_function%u$$%s",
4517 ++synthetic_function_symbol_idx,
4518 module_sp->GetFileSpec().GetFilename().GetCString());
4519 sym[sym_idx].SetID (synthetic_sym_id++);
Greg Clayton037520e2012-07-18 23:18:10 +00004520 sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004521 sym[sym_idx].SetType (eSymbolTypeCode);
4522 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004523 sym[sym_idx].GetAddressRef() = symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004524 if (symbol_flags)
4525 sym[sym_idx].SetFlags (symbol_flags);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004526 if (symbol_byte_size)
4527 sym[sym_idx].SetByteSize (symbol_byte_size);
4528 ++sym_idx;
4529 }
4530 }
4531 }
4532 }
4533 }
4534 }
4535
4536 // Trim our symbols down to just what we ended up with after
4537 // removing any symbols.
4538 if (sym_idx < num_syms)
4539 {
4540 num_syms = sym_idx;
4541 sym = symtab->Resize (num_syms);
4542 }
4543
4544 // Now synthesize indirect symbols
4545 if (m_dysymtab.nindirectsyms != 0)
4546 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004547 if (indirect_symbol_index_data.GetByteSize())
4548 {
4549 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
4550
4551 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
4552 {
Charles Davis510938e2013-08-27 05:04:57 +00004553 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004554 {
4555 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4556 if (symbol_stub_byte_size == 0)
4557 continue;
4558
4559 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4560
4561 if (num_symbol_stubs == 0)
4562 continue;
4563
4564 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
4565 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
4566 {
4567 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
4568 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 +00004569 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004570 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
4571 {
4572 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
Charles Davis510938e2013-08-27 05:04:57 +00004573 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004574 continue;
4575
4576 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
4577 Symbol *stub_symbol = NULL;
4578 if (index_pos != end_index_pos)
4579 {
4580 // We have a remapping from the original nlist index to
4581 // a current symbol index, so just look this up by index
4582 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
4583 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004584 else
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004585 {
4586 // We need to lookup a symbol using the original nlist
Jason Molenda4e7511e2013-03-06 23:19:17 +00004587 // symbol index since this index is coming from the
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004588 // S_SYMBOL_STUBS
4589 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
4590 }
4591
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004592 if (stub_symbol)
4593 {
4594 Address so_addr(symbol_stub_addr, section_list);
4595
4596 if (stub_symbol->GetType() == eSymbolTypeUndefined)
4597 {
4598 // Change the external symbol into a trampoline that makes sense
4599 // These symbols were N_UNDF N_EXT, and are useless to us, so we
4600 // can re-use them so we don't have to make up a synthetic symbol
4601 // for no good reason.
Greg Clayton9191db42013-10-21 18:40:51 +00004602 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4603 stub_symbol->SetType (eSymbolTypeTrampoline);
4604 else
4605 stub_symbol->SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004606 stub_symbol->SetExternal (false);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004607 stub_symbol->GetAddressRef() = so_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004608 stub_symbol->SetByteSize (symbol_stub_byte_size);
4609 }
4610 else
4611 {
4612 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda0a287e02012-04-24 02:09:58 +00004613 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004614 if (sym_idx >= num_syms)
Jason Molenda0a287e02012-04-24 02:09:58 +00004615 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004616 sym = symtab->Resize (++num_syms);
Jason Molenda0a287e02012-04-24 02:09:58 +00004617 stub_symbol = NULL; // this pointer no longer valid
4618 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004619 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda0a287e02012-04-24 02:09:58 +00004620 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton9191db42013-10-21 18:40:51 +00004621 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4622 sym[sym_idx].SetType (eSymbolTypeTrampoline);
4623 else
4624 sym[sym_idx].SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004625 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004626 sym[sym_idx].GetAddressRef() = so_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004627 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
4628 ++sym_idx;
4629 }
4630 }
Greg Clayton3f839a32012-09-05 01:38:55 +00004631 else
4632 {
4633 if (log)
4634 log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
4635 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004636 }
4637 }
4638 }
4639 }
4640 }
4641 }
Greg Clayton9191db42013-10-21 18:40:51 +00004642
4643
4644 if (!trie_entries.empty())
4645 {
4646 for (const auto &e : trie_entries)
4647 {
4648 if (e.entry.import_name)
4649 {
Greg Clayton60038be2015-02-14 00:51:13 +00004650 // Only add indirect symbols from the Trie entries if we
4651 // didn't have a N_INDR nlist entry for this already
4652 if (indirect_symbol_names.find(e.entry.name) == indirect_symbol_names.end())
Greg Clayton9191db42013-10-21 18:40:51 +00004653 {
Greg Clayton60038be2015-02-14 00:51:13 +00004654 // Make a synthetic symbol to describe re-exported symbol.
4655 if (sym_idx >= num_syms)
4656 sym = symtab->Resize (++num_syms);
4657 sym[sym_idx].SetID (synthetic_sym_id++);
4658 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4659 sym[sym_idx].SetType (eSymbolTypeReExported);
4660 sym[sym_idx].SetIsSynthetic (true);
4661 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4662 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
4663 {
4664 sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
4665 }
4666 ++sym_idx;
Greg Clayton9191db42013-10-21 18:40:51 +00004667 }
Greg Clayton9191db42013-10-21 18:40:51 +00004668 }
4669 }
4670 }
4671
4672
Greg Clayton3046e662013-07-10 01:23:25 +00004673
4674// StreamFile s(stdout, false);
4675// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
4676// symtab->Dump(&s, NULL, eSortOrderNone);
4677 // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
4678 symtab->CalculateSymbolSizes();
4679
4680// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
4681// symtab->Dump(&s, NULL, eSortOrderNone);
4682
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004683 return symtab->GetNumSymbols();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004684 }
4685 return 0;
4686}
4687
4688
4689void
4690ObjectFileMachO::Dump (Stream *s)
4691{
Greg Claytona1743492012-03-13 23:14:29 +00004692 ModuleSP module_sp(GetModule());
4693 if (module_sp)
4694 {
4695 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004696 s->Printf("%p: ", static_cast<void*>(this));
Greg Claytona1743492012-03-13 23:14:29 +00004697 s->Indent();
Charles Davis510938e2013-08-27 05:04:57 +00004698 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
Greg Claytona1743492012-03-13 23:14:29 +00004699 s->PutCString("ObjectFileMachO64");
4700 else
4701 s->PutCString("ObjectFileMachO32");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004702
Greg Clayton7ab7f892014-05-29 21:33:45 +00004703 ArchSpec header_arch;
4704 GetArchitecture(header_arch);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004705
Greg Claytona1743492012-03-13 23:14:29 +00004706 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004707
Greg Clayton3046e662013-07-10 01:23:25 +00004708 SectionList *sections = GetSectionList();
4709 if (sections)
4710 sections->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004711
Greg Claytona1743492012-03-13 23:14:29 +00004712 if (m_symtab_ap.get())
4713 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
4714 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004715}
4716
Greg Claytonf4d6de62013-04-24 22:29:28 +00004717bool
4718ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header,
4719 const lldb_private::DataExtractor &data,
4720 lldb::offset_t lc_offset,
4721 lldb_private::UUID& uuid)
4722{
4723 uint32_t i;
4724 struct uuid_command load_cmd;
4725
4726 lldb::offset_t offset = lc_offset;
4727 for (i=0; i<header.ncmds; ++i)
4728 {
4729 const lldb::offset_t cmd_offset = offset;
4730 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4731 break;
4732
Charles Davis510938e2013-08-27 05:04:57 +00004733 if (load_cmd.cmd == LC_UUID)
Greg Claytonf4d6de62013-04-24 22:29:28 +00004734 {
4735 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4736
4737 if (uuid_bytes)
4738 {
4739 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4740 // We pretend these object files have no UUID to prevent crashing.
4741
4742 const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
4743 0x3b, 0xa8,
4744 0x4b, 0x16,
4745 0xb6, 0xa4,
4746 0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
4747
4748 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4749 return false;
4750
4751 uuid.SetBytes (uuid_bytes);
4752 return true;
4753 }
4754 return false;
4755 }
4756 offset = cmd_offset + load_cmd.cmdsize;
4757 }
4758 return false;
4759}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004760
Greg Clayton7ab7f892014-05-29 21:33:45 +00004761
4762bool
4763ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header,
4764 const lldb_private::DataExtractor &data,
4765 lldb::offset_t lc_offset,
4766 ArchSpec &arch)
4767{
4768 arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype);
4769
4770 if (arch.IsValid())
4771 {
4772 llvm::Triple &triple = arch.GetTriple();
4773 if (header.filetype == MH_PRELOAD)
4774 {
4775 // Set OS to "unknown" - this is a standalone binary with no dyld et al
4776 triple.setOS(llvm::Triple::UnknownOS);
4777 return true;
4778 }
4779 else
4780 {
4781 struct load_command load_cmd;
4782
4783 lldb::offset_t offset = lc_offset;
4784 for (uint32_t i=0; i<header.ncmds; ++i)
4785 {
4786 const lldb::offset_t cmd_offset = offset;
4787 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4788 break;
4789
4790 switch (load_cmd.cmd)
4791 {
4792 case LC_VERSION_MIN_IPHONEOS:
4793 triple.setOS (llvm::Triple::IOS);
4794 return true;
4795
4796 case LC_VERSION_MIN_MACOSX:
4797 triple.setOS (llvm::Triple::MacOSX);
4798 return true;
4799
4800 default:
4801 break;
4802 }
4803
4804 offset = cmd_offset + load_cmd.cmdsize;
4805 }
4806
Greg Claytona3a6c122014-07-29 18:04:57 +00004807 // Only set the OS to iOS for ARM, we don't want to set it for x86 and x86_64.
4808 // We do this because we now have MacOSX or iOS as the OS value for x86 and
4809 // x86_64 for normal desktop (MacOSX) and simulator (iOS) binaries. And if
4810 // we compare a "x86_64-apple-ios" to a "x86_64-apple-" triple, it will say
4811 // it is compatible (because the OS is unspecified in the second one and will
4812 // match anything in the first
Greg Clayton7ab7f892014-05-29 21:33:45 +00004813 if (header.cputype == CPU_TYPE_ARM || header.cputype == CPU_TYPE_ARM64)
4814 triple.setOS (llvm::Triple::IOS);
Greg Clayton7ab7f892014-05-29 21:33:45 +00004815 }
4816 }
4817 return arch.IsValid();
4818}
4819
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004820bool
Greg Clayton60830262011-02-04 18:53:10 +00004821ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004822{
Greg Claytona1743492012-03-13 23:14:29 +00004823 ModuleSP module_sp(GetModule());
4824 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004825 {
Greg Claytona1743492012-03-13 23:14:29 +00004826 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Claytonc7bece562013-01-25 18:06:21 +00004827 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +00004828 return GetUUID (m_header, m_data, offset, *uuid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004829 }
4830 return false;
4831}
4832
4833
4834uint32_t
4835ObjectFileMachO::GetDependentModules (FileSpecList& files)
4836{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004837 uint32_t count = 0;
Greg Claytona1743492012-03-13 23:14:29 +00004838 ModuleSP module_sp(GetModule());
4839 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004840 {
Greg Claytona1743492012-03-13 23:14:29 +00004841 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4842 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004843 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Clayton5a271952015-06-02 22:43:29 +00004844 std::vector<std::string> rpath_paths;
4845 std::vector<std::string> rpath_relative_paths;
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004846 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 +00004847 uint32_t i;
4848 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004849 {
Greg Claytona1743492012-03-13 23:14:29 +00004850 const uint32_t cmd_offset = offset;
4851 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4852 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004853
Greg Claytona1743492012-03-13 23:14:29 +00004854 switch (load_cmd.cmd)
4855 {
Greg Clayton5a271952015-06-02 22:43:29 +00004856 case LC_RPATH:
Charles Davis510938e2013-08-27 05:04:57 +00004857 case LC_LOAD_DYLIB:
4858 case LC_LOAD_WEAK_DYLIB:
4859 case LC_REEXPORT_DYLIB:
4860 case LC_LOAD_DYLINKER:
4861 case LC_LOADFVMLIB:
4862 case LC_LOAD_UPWARD_DYLIB:
Greg Claytona1743492012-03-13 23:14:29 +00004863 {
4864 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
4865 const char *path = m_data.PeekCStr(name_offset);
Greg Clayton5a271952015-06-02 22:43:29 +00004866 if (path)
Greg Claytona1743492012-03-13 23:14:29 +00004867 {
Greg Clayton5a271952015-06-02 22:43:29 +00004868 if (load_cmd.cmd == LC_RPATH)
4869 rpath_paths.push_back(path);
4870 else
4871 {
4872 if (path[0] == '@')
4873 {
4874 if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
4875 rpath_relative_paths.push_back(path + strlen("@rpath"));
4876 }
4877 else
4878 {
4879 FileSpec file_spec(path, resolve_path);
4880 if (files.AppendIfUnique(file_spec))
4881 count++;
4882 }
4883 }
Greg Claytona1743492012-03-13 23:14:29 +00004884 }
4885 }
4886 break;
4887
4888 default:
4889 break;
4890 }
4891 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004892 }
Greg Clayton5a271952015-06-02 22:43:29 +00004893
4894 if (!rpath_paths.empty())
4895 {
4896 // Fixup all LC_RPATH values to be absolute paths
4897 FileSpec this_file_spec(m_file);
4898 this_file_spec.ResolvePath();
4899 std::string loader_path("@loader_path");
4900 std::string executable_path("@executable_path");
4901 for (auto &rpath : rpath_paths)
4902 {
4903 if (rpath.find(loader_path) == 0)
4904 {
4905 rpath.erase(0, loader_path.size());
4906 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
4907 }
4908 else if (rpath.find(executable_path) == 0)
4909 {
4910 rpath.erase(0, executable_path.size());
4911 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
4912 }
4913 }
4914
4915 for (const auto &rpath_relative_path : rpath_relative_paths)
4916 {
4917 for (const auto &rpath : rpath_paths)
4918 {
4919 std::string path = rpath;
4920 path += rpath_relative_path;
4921 // It is OK to resolve this path because we must find a file on
4922 // disk for us to accept it anyway if it is rpath relative.
4923 FileSpec file_spec(path, true);
4924 // Remove any redundant parts of the path (like "../foo") since
4925 // LC_RPATH values often contain "..".
4926 file_spec.NormalizePath ();
4927 if (file_spec.Exists() && files.AppendIfUnique(file_spec))
4928 {
4929 count++;
4930 break;
4931 }
4932 }
4933 }
4934 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004935 }
4936 return count;
4937}
4938
Jim Ingham672e6f52011-03-07 23:44:08 +00004939lldb_private::Address
Jason Molenda4e7511e2013-03-06 23:19:17 +00004940ObjectFileMachO::GetEntryPointAddress ()
Jim Ingham672e6f52011-03-07 23:44:08 +00004941{
4942 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
4943 // is initialized to an invalid address, so we can just return that.
4944 // 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 +00004945
Jim Ingham672e6f52011-03-07 23:44:08 +00004946 if (!IsExecutable() || m_entry_point_address.IsValid())
4947 return m_entry_point_address;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004948
4949 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
Jim Ingham672e6f52011-03-07 23:44:08 +00004950 // /usr/include/mach-o.h, but it is basically:
4951 //
4952 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
4953 // uint32_t count - this is the count of longs in the thread state data
4954 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
4955 // <repeat this trio>
Jason Molenda4e7511e2013-03-06 23:19:17 +00004956 //
Jim Ingham672e6f52011-03-07 23:44:08 +00004957 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
4958 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
4959 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
4960 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
4961 //
4962 // For now we hard-code the offsets and flavors we need:
4963 //
4964 //
4965
Greg Claytona1743492012-03-13 23:14:29 +00004966 ModuleSP module_sp(GetModule());
4967 if (module_sp)
Jim Ingham672e6f52011-03-07 23:44:08 +00004968 {
Greg Claytona1743492012-03-13 23:14:29 +00004969 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4970 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004971 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00004972 uint32_t i;
4973 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
4974 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004975
Greg Claytona1743492012-03-13 23:14:29 +00004976 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham672e6f52011-03-07 23:44:08 +00004977 {
Greg Claytonc7bece562013-01-25 18:06:21 +00004978 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00004979 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4980 break;
4981
4982 switch (load_cmd.cmd)
Jim Ingham672e6f52011-03-07 23:44:08 +00004983 {
Charles Davis510938e2013-08-27 05:04:57 +00004984 case LC_UNIXTHREAD:
4985 case LC_THREAD:
Jim Ingham672e6f52011-03-07 23:44:08 +00004986 {
Greg Claytona1743492012-03-13 23:14:29 +00004987 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham672e6f52011-03-07 23:44:08 +00004988 {
Greg Claytona1743492012-03-13 23:14:29 +00004989 uint32_t flavor = m_data.GetU32(&offset);
4990 uint32_t count = m_data.GetU32(&offset);
4991 if (count == 0)
4992 {
4993 // We've gotten off somehow, log and exit;
4994 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00004995 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004996
Greg Claytona1743492012-03-13 23:14:29 +00004997 switch (m_header.cputype)
4998 {
Charles Davis510938e2013-08-27 05:04:57 +00004999 case llvm::MachO::CPU_TYPE_ARM:
Greg Claytona1743492012-03-13 23:14:29 +00005000 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
5001 {
5002 offset += 60; // This is the offset of pc in the GPR thread state data structure.
5003 start_address = m_data.GetU32(&offset);
5004 done = true;
5005 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005006 break;
Jason Molendaa3329782014-03-29 18:54:20 +00005007 case llvm::MachO::CPU_TYPE_ARM64:
5008 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
5009 {
5010 offset += 256; // This is the offset of pc in the GPR thread state data structure.
5011 start_address = m_data.GetU64(&offset);
5012 done = true;
5013 }
5014 break;
Charles Davis510938e2013-08-27 05:04:57 +00005015 case llvm::MachO::CPU_TYPE_I386:
Greg Claytona1743492012-03-13 23:14:29 +00005016 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
5017 {
5018 offset += 40; // This is the offset of eip in the GPR thread state data structure.
5019 start_address = m_data.GetU32(&offset);
5020 done = true;
5021 }
5022 break;
Charles Davis510938e2013-08-27 05:04:57 +00005023 case llvm::MachO::CPU_TYPE_X86_64:
Greg Claytona1743492012-03-13 23:14:29 +00005024 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
5025 {
5026 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
5027 start_address = m_data.GetU64(&offset);
5028 done = true;
5029 }
5030 break;
5031 default:
5032 return m_entry_point_address;
5033 }
5034 // Haven't found the GPR flavor yet, skip over the data for this flavor:
5035 if (done)
5036 break;
5037 offset += count * 4;
5038 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005039 }
Greg Claytona1743492012-03-13 23:14:29 +00005040 break;
Charles Davis510938e2013-08-27 05:04:57 +00005041 case LC_MAIN:
Sean Callanan226b70c2012-03-08 02:39:03 +00005042 {
Greg Claytona1743492012-03-13 23:14:29 +00005043 ConstString text_segment_name ("__TEXT");
5044 uint64_t entryoffset = m_data.GetU64(&offset);
5045 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
5046 if (text_segment_sp)
5047 {
5048 done = true;
5049 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5050 }
Sean Callanan226b70c2012-03-08 02:39:03 +00005051 }
Greg Claytona1743492012-03-13 23:14:29 +00005052
5053 default:
5054 break;
Sean Callanan226b70c2012-03-08 02:39:03 +00005055 }
Greg Claytona1743492012-03-13 23:14:29 +00005056 if (done)
5057 break;
Jim Ingham672e6f52011-03-07 23:44:08 +00005058
Greg Claytona1743492012-03-13 23:14:29 +00005059 // Go to the next load command:
5060 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham672e6f52011-03-07 23:44:08 +00005061 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005062
Greg Claytona1743492012-03-13 23:14:29 +00005063 if (start_address != LLDB_INVALID_ADDRESS)
Greg Claytone72dfb32012-02-24 01:59:29 +00005064 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00005065 // We got the start address from the load commands, so now resolve that address in the sections
Greg Claytona1743492012-03-13 23:14:29 +00005066 // of this ObjectFile:
5067 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Claytone72dfb32012-02-24 01:59:29 +00005068 {
Greg Claytona1743492012-03-13 23:14:29 +00005069 m_entry_point_address.Clear();
5070 }
5071 }
5072 else
5073 {
5074 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
5075 // "start" symbol in the main executable.
Jason Molenda4e7511e2013-03-06 23:19:17 +00005076
Greg Claytona1743492012-03-13 23:14:29 +00005077 ModuleSP module_sp (GetModule());
Jason Molenda4e7511e2013-03-06 23:19:17 +00005078
Greg Claytona1743492012-03-13 23:14:29 +00005079 if (module_sp)
5080 {
5081 SymbolContextList contexts;
5082 SymbolContext context;
5083 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
5084 {
5085 if (contexts.GetContextAtIndex(0, context))
5086 m_entry_point_address = context.symbol->GetAddress();
5087 }
Greg Claytone72dfb32012-02-24 01:59:29 +00005088 }
5089 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005090 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005091
Jim Ingham672e6f52011-03-07 23:44:08 +00005092 return m_entry_point_address;
5093
5094}
5095
Greg Claytonc9660542012-02-05 02:38:54 +00005096lldb_private::Address
5097ObjectFileMachO::GetHeaderAddress ()
5098{
5099 lldb_private::Address header_addr;
5100 SectionList *section_list = GetSectionList();
5101 if (section_list)
5102 {
5103 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
5104 if (text_segment_sp)
5105 {
Greg Claytone72dfb32012-02-24 01:59:29 +00005106 header_addr.SetSection (text_segment_sp);
Greg Claytonc9660542012-02-05 02:38:54 +00005107 header_addr.SetOffset (0);
5108 }
5109 }
5110 return header_addr;
5111}
5112
Greg Claytonc3776bf2012-02-09 06:16:32 +00005113uint32_t
5114ObjectFileMachO::GetNumThreadContexts ()
5115{
Greg Claytona1743492012-03-13 23:14:29 +00005116 ModuleSP module_sp(GetModule());
5117 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005118 {
Greg Claytona1743492012-03-13 23:14:29 +00005119 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5120 if (!m_thread_context_offsets_valid)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005121 {
Greg Claytona1743492012-03-13 23:14:29 +00005122 m_thread_context_offsets_valid = true;
Greg Claytonc7bece562013-01-25 18:06:21 +00005123 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005124 FileRangeArray::Entry file_range;
5125 thread_command thread_cmd;
5126 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005127 {
Greg Claytona1743492012-03-13 23:14:29 +00005128 const uint32_t cmd_offset = offset;
5129 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
5130 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005131
Charles Davis510938e2013-08-27 05:04:57 +00005132 if (thread_cmd.cmd == LC_THREAD)
Greg Claytona1743492012-03-13 23:14:29 +00005133 {
5134 file_range.SetRangeBase (offset);
5135 file_range.SetByteSize (thread_cmd.cmdsize - 8);
5136 m_thread_context_offsets.Append (file_range);
5137 }
5138 offset = cmd_offset + thread_cmd.cmdsize;
Greg Claytonc3776bf2012-02-09 06:16:32 +00005139 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00005140 }
5141 }
5142 return m_thread_context_offsets.GetSize();
5143}
5144
5145lldb::RegisterContextSP
5146ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
5147{
Greg Claytonc3776bf2012-02-09 06:16:32 +00005148 lldb::RegisterContextSP reg_ctx_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +00005149
Greg Claytona1743492012-03-13 23:14:29 +00005150 ModuleSP module_sp(GetModule());
5151 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005152 {
Greg Claytona1743492012-03-13 23:14:29 +00005153 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5154 if (!m_thread_context_offsets_valid)
5155 GetNumThreadContexts ();
5156
5157 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
Jim Ingham28eb5712012-10-12 17:34:26 +00005158 if (thread_context_file_range)
Greg Claytona1743492012-03-13 23:14:29 +00005159 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00005160
5161 DataExtractor data (m_data,
5162 thread_context_file_range->GetRangeBase(),
Jim Ingham28eb5712012-10-12 17:34:26 +00005163 thread_context_file_range->GetByteSize());
5164
5165 switch (m_header.cputype)
5166 {
Jason Molendaa3329782014-03-29 18:54:20 +00005167 case llvm::MachO::CPU_TYPE_ARM64:
5168 reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
5169 break;
5170
Charles Davis510938e2013-08-27 05:04:57 +00005171 case llvm::MachO::CPU_TYPE_ARM:
Jim Ingham28eb5712012-10-12 17:34:26 +00005172 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
5173 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005174
Charles Davis510938e2013-08-27 05:04:57 +00005175 case llvm::MachO::CPU_TYPE_I386:
Jim Ingham28eb5712012-10-12 17:34:26 +00005176 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
5177 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005178
Charles Davis510938e2013-08-27 05:04:57 +00005179 case llvm::MachO::CPU_TYPE_X86_64:
Jim Ingham28eb5712012-10-12 17:34:26 +00005180 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
5181 break;
5182 }
Greg Claytona1743492012-03-13 23:14:29 +00005183 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00005184 }
5185 return reg_ctx_sp;
5186}
5187
Greg Claytonc9660542012-02-05 02:38:54 +00005188
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005189ObjectFile::Type
5190ObjectFileMachO::CalculateType()
5191{
5192 switch (m_header.filetype)
5193 {
Charles Davis510938e2013-08-27 05:04:57 +00005194 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005195 if (GetAddressByteSize () == 4)
5196 {
5197 // 32 bit kexts are just object files, but they do have a valid
5198 // UUID load command.
5199 UUID uuid;
5200 if (GetUUID(&uuid))
5201 {
5202 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00005203 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005204 // "OSKextGetCurrentIdentifier" as this is required of kexts
5205 if (m_strata == eStrataInvalid)
5206 m_strata = eStrataKernel;
5207 return eTypeSharedLibrary;
5208 }
5209 }
5210 return eTypeObjectFile;
5211
Charles Davis510938e2013-08-27 05:04:57 +00005212 case MH_EXECUTE: return eTypeExecutable; // 0x2u
5213 case MH_FVMLIB: return eTypeSharedLibrary; // 0x3u
5214 case MH_CORE: return eTypeCoreFile; // 0x4u
5215 case MH_PRELOAD: return eTypeSharedLibrary; // 0x5u
5216 case MH_DYLIB: return eTypeSharedLibrary; // 0x6u
5217 case MH_DYLINKER: return eTypeDynamicLinker; // 0x7u
5218 case MH_BUNDLE: return eTypeSharedLibrary; // 0x8u
5219 case MH_DYLIB_STUB: return eTypeStubLibrary; // 0x9u
5220 case MH_DSYM: return eTypeDebugInfo; // 0xAu
5221 case MH_KEXT_BUNDLE: return eTypeSharedLibrary; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005222 default:
5223 break;
5224 }
5225 return eTypeUnknown;
5226}
5227
5228ObjectFile::Strata
5229ObjectFileMachO::CalculateStrata()
5230{
5231 switch (m_header.filetype)
5232 {
Charles Davis510938e2013-08-27 05:04:57 +00005233 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005234 {
5235 // 32 bit kexts are just object files, but they do have a valid
5236 // UUID load command.
5237 UUID uuid;
5238 if (GetUUID(&uuid))
5239 {
5240 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00005241 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005242 // "OSKextGetCurrentIdentifier" as this is required of kexts
5243 if (m_type == eTypeInvalid)
5244 m_type = eTypeSharedLibrary;
5245
5246 return eStrataKernel;
5247 }
5248 }
5249 return eStrataUnknown;
5250
Charles Davis510938e2013-08-27 05:04:57 +00005251 case MH_EXECUTE: // 0x2u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005252 // Check for the MH_DYLDLINK bit in the flags
Charles Davis510938e2013-08-27 05:04:57 +00005253 if (m_header.flags & MH_DYLDLINK)
Sean Callanan49bce8e2012-02-10 20:22:35 +00005254 {
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005255 return eStrataUser;
Sean Callanan49bce8e2012-02-10 20:22:35 +00005256 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005257 else
Sean Callanan49bce8e2012-02-10 20:22:35 +00005258 {
5259 SectionList *section_list = GetSectionList();
5260 if (section_list)
5261 {
5262 static ConstString g_kld_section_name ("__KLD");
5263 if (section_list->FindSectionByName(g_kld_section_name))
5264 return eStrataKernel;
5265 }
5266 }
5267 return eStrataRawImage;
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005268
Charles Davis510938e2013-08-27 05:04:57 +00005269 case MH_FVMLIB: return eStrataUser; // 0x3u
5270 case MH_CORE: return eStrataUnknown; // 0x4u
5271 case MH_PRELOAD: return eStrataRawImage; // 0x5u
5272 case MH_DYLIB: return eStrataUser; // 0x6u
5273 case MH_DYLINKER: return eStrataUser; // 0x7u
5274 case MH_BUNDLE: return eStrataUser; // 0x8u
5275 case MH_DYLIB_STUB: return eStrataUser; // 0x9u
5276 case MH_DSYM: return eStrataUnknown; // 0xAu
5277 case MH_KEXT_BUNDLE: return eStrataKernel; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005278 default:
5279 break;
5280 }
5281 return eStrataUnknown;
5282}
5283
5284
Greg Claytonc2ff9312012-02-22 19:41:02 +00005285uint32_t
5286ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
5287{
Greg Claytona1743492012-03-13 23:14:29 +00005288 ModuleSP module_sp(GetModule());
5289 if (module_sp)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005290 {
Greg Claytona1743492012-03-13 23:14:29 +00005291 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5292 struct dylib_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00005293 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005294 uint32_t version_cmd = 0;
5295 uint64_t version = 0;
5296 uint32_t i;
5297 for (i=0; i<m_header.ncmds; ++i)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005298 {
Greg Claytonc7bece562013-01-25 18:06:21 +00005299 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00005300 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
5301 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005302
Charles Davis510938e2013-08-27 05:04:57 +00005303 if (load_cmd.cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005304 {
Greg Claytona1743492012-03-13 23:14:29 +00005305 if (version_cmd == 0)
5306 {
5307 version_cmd = load_cmd.cmd;
5308 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
5309 break;
5310 version = load_cmd.dylib.current_version;
5311 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005312 break; // Break for now unless there is another more complete version
Greg Claytona1743492012-03-13 23:14:29 +00005313 // number load command in the future.
Greg Claytonc2ff9312012-02-22 19:41:02 +00005314 }
Greg Claytona1743492012-03-13 23:14:29 +00005315 offset = cmd_offset + load_cmd.cmdsize;
Greg Claytonc2ff9312012-02-22 19:41:02 +00005316 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005317
Charles Davis510938e2013-08-27 05:04:57 +00005318 if (version_cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005319 {
Greg Claytona1743492012-03-13 23:14:29 +00005320 if (versions != NULL && num_versions > 0)
5321 {
5322 if (num_versions > 0)
5323 versions[0] = (version & 0xFFFF0000ull) >> 16;
5324 if (num_versions > 1)
5325 versions[1] = (version & 0x0000FF00ull) >> 8;
5326 if (num_versions > 2)
5327 versions[2] = (version & 0x000000FFull);
5328 // Fill in an remaining version numbers with invalid values
5329 for (i=3; i<num_versions; ++i)
5330 versions[i] = UINT32_MAX;
5331 }
5332 // The LC_ID_DYLIB load command has a version with 3 version numbers
5333 // in it, so always return 3
5334 return 3;
Greg Claytonc2ff9312012-02-22 19:41:02 +00005335 }
Greg Claytonc2ff9312012-02-22 19:41:02 +00005336 }
5337 return false;
5338}
5339
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005340bool
Greg Clayton514487e2011-02-15 21:59:32 +00005341ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005342{
Greg Claytona1743492012-03-13 23:14:29 +00005343 ModuleSP module_sp(GetModule());
5344 if (module_sp)
Greg Clayton593577a2011-09-21 03:57:31 +00005345 {
Greg Claytona1743492012-03-13 23:14:29 +00005346 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Clayton7ab7f892014-05-29 21:33:45 +00005347 return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch);
Greg Clayton593577a2011-09-21 03:57:31 +00005348 }
Greg Claytona1743492012-03-13 23:14:29 +00005349 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005350}
5351
5352
Jason Molenda0e0954c2013-04-16 06:24:42 +00005353UUID
5354ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
5355{
5356 UUID uuid;
5357 if (process)
5358 {
5359 addr_t all_image_infos = process->GetImageInfoAddress();
5360
5361 // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
5362 // or it may be the address of the dyld_all_image_infos structure (want). The first four
5363 // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
5364 // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
5365
5366 Error err;
5367 uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00005368 if (version_or_magic != static_cast<uint32_t>(-1)
Charles Davis510938e2013-08-27 05:04:57 +00005369 && version_or_magic != MH_MAGIC
5370 && version_or_magic != MH_CIGAM
5371 && version_or_magic != MH_MAGIC_64
5372 && version_or_magic != MH_CIGAM_64
Jason Molenda0e0954c2013-04-16 06:24:42 +00005373 && version_or_magic >= 13)
5374 {
5375 addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
5376 int wordsize = process->GetAddressByteSize();
5377 if (wordsize == 8)
5378 {
5379 sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
5380 }
5381 if (wordsize == 4)
5382 {
5383 sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
5384 }
5385 if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
5386 {
5387 uuid_t shared_cache_uuid;
5388 if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
5389 {
5390 uuid.SetBytes (shared_cache_uuid);
5391 }
5392 }
5393 }
5394 }
5395 return uuid;
5396}
5397
5398UUID
5399ObjectFileMachO::GetLLDBSharedCacheUUID ()
5400{
5401 UUID uuid;
Todd Fiala013434e2014-07-09 01:29:05 +00005402#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +00005403 uint8_t *(*dyld_get_all_image_infos)(void);
5404 dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
5405 if (dyld_get_all_image_infos)
5406 {
5407 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5408 if (dyld_all_image_infos_address)
5409 {
Jason Molendac9cb7d22013-04-16 21:42:58 +00005410 uint32_t *version = (uint32_t*) dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5411 if (*version >= 13)
Jason Molenda0e0954c2013-04-16 06:24:42 +00005412 {
Jason Molendaa3329782014-03-29 18:54:20 +00005413 uuid_t *sharedCacheUUID_address = 0;
5414 int wordsize = sizeof (uint8_t *);
5415 if (wordsize == 8)
5416 {
5417 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
5418 }
5419 else
5420 {
5421 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84); // sharedCacheUUID <mach-o/dyld_images.h>
5422 }
Jason Molenda0e0954c2013-04-16 06:24:42 +00005423 uuid.SetBytes (sharedCacheUUID_address);
5424 }
5425 }
5426 }
5427#endif
5428 return uuid;
5429}
5430
Greg Clayton9b234982013-10-24 22:54:08 +00005431uint32_t
5432ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
5433{
5434 if (m_min_os_versions.empty())
5435 {
5436 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5437 bool success = false;
5438 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5439 {
5440 const lldb::offset_t load_cmd_offset = offset;
5441
5442 version_min_command lc;
5443 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5444 break;
5445 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5446 {
5447 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5448 {
5449 const uint32_t xxxx = lc.version >> 16;
5450 const uint32_t yy = (lc.version >> 8) & 0xffu;
5451 const uint32_t zz = lc.version & 0xffu;
5452 if (xxxx)
5453 {
5454 m_min_os_versions.push_back(xxxx);
Greg Clayton8031d282015-02-04 00:40:25 +00005455 m_min_os_versions.push_back(yy);
5456 m_min_os_versions.push_back(zz);
Greg Clayton9b234982013-10-24 22:54:08 +00005457 }
5458 success = true;
5459 }
5460 }
5461 offset = load_cmd_offset + lc.cmdsize;
5462 }
5463
5464 if (success == false)
5465 {
5466 // Push an invalid value so we don't keep trying to
5467 m_min_os_versions.push_back(UINT32_MAX);
5468 }
5469 }
5470
5471 if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
5472 {
5473 if (versions != NULL && num_versions > 0)
5474 {
5475 for (size_t i=0; i<num_versions; ++i)
5476 {
5477 if (i < m_min_os_versions.size())
5478 versions[i] = m_min_os_versions[i];
5479 else
5480 versions[i] = 0;
5481 }
5482 }
5483 return m_min_os_versions.size();
5484 }
5485 // Call the superclasses version that will empty out the data
5486 return ObjectFile::GetMinimumOSVersion (versions, num_versions);
5487}
5488
5489uint32_t
5490ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions)
5491{
5492 if (m_sdk_versions.empty())
5493 {
5494 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5495 bool success = false;
5496 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5497 {
5498 const lldb::offset_t load_cmd_offset = offset;
5499
5500 version_min_command lc;
5501 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5502 break;
5503 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5504 {
5505 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5506 {
Todd Fialaebecb382014-09-04 19:31:52 +00005507 const uint32_t xxxx = lc.sdk >> 16;
5508 const uint32_t yy = (lc.sdk >> 8) & 0xffu;
5509 const uint32_t zz = lc.sdk & 0xffu;
Greg Clayton9b234982013-10-24 22:54:08 +00005510 if (xxxx)
5511 {
5512 m_sdk_versions.push_back(xxxx);
Greg Clayton8031d282015-02-04 00:40:25 +00005513 m_sdk_versions.push_back(yy);
5514 m_sdk_versions.push_back(zz);
Greg Clayton9b234982013-10-24 22:54:08 +00005515 }
5516 success = true;
5517 }
5518 }
5519 offset = load_cmd_offset + lc.cmdsize;
5520 }
5521
5522 if (success == false)
5523 {
5524 // Push an invalid value so we don't keep trying to
5525 m_sdk_versions.push_back(UINT32_MAX);
5526 }
5527 }
5528
5529 if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
5530 {
5531 if (versions != NULL && num_versions > 0)
5532 {
5533 for (size_t i=0; i<num_versions; ++i)
5534 {
5535 if (i < m_sdk_versions.size())
5536 versions[i] = m_sdk_versions[i];
5537 else
5538 versions[i] = 0;
5539 }
5540 }
5541 return m_sdk_versions.size();
5542 }
5543 // Call the superclasses version that will empty out the data
5544 return ObjectFile::GetSDKVersion (versions, num_versions);
5545}
5546
Jason Molenda0e0954c2013-04-16 06:24:42 +00005547
Greg Clayton08928f32015-02-05 02:01:34 +00005548bool
5549ObjectFileMachO::GetIsDynamicLinkEditor()
5550{
5551 return m_header.filetype == llvm::MachO::MH_DYLINKER;
5552}
5553
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005554//------------------------------------------------------------------
5555// PluginInterface protocol
5556//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00005557lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005558ObjectFileMachO::GetPluginName()
5559{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005560 return GetPluginNameStatic();
5561}
5562
5563uint32_t
5564ObjectFileMachO::GetPluginVersion()
5565{
5566 return 1;
5567}
5568
Greg Clayton7524e092014-02-06 20:10:16 +00005569
Greg Clayton07347372015-06-08 21:53:11 +00005570Section *
5571ObjectFileMachO::GetMachHeaderSection()
5572{
5573 // Find the first address of the mach header which is the first non-zero
5574 // file sized section whose file offset is zero. This is the base file address
5575 // of the mach-o file which can be subtracted from the vmaddr of the other
5576 // segments found in memory and added to the load address
5577 ModuleSP module_sp = GetModule();
5578 if (module_sp)
5579 {
5580 SectionList *section_list = GetSectionList ();
5581 if (section_list)
5582 {
5583 lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
5584 const size_t num_sections = section_list->GetSize();
5585
5586 for (size_t sect_idx = 0;
5587 sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
5588 ++sect_idx)
5589 {
5590 Section *section = section_list->GetSectionAtIndex (sect_idx).get();
5591 if (section &&
5592 section->GetFileSize() > 0 &&
5593 section->GetFileOffset() == 0 &&
5594 section->IsThreadSpecific() == false &&
5595 module_sp.get() == section->GetModule().get())
5596 {
5597 return section;
5598 }
5599 }
5600 }
5601 }
5602 return nullptr;
5603}
5604
5605lldb::addr_t
5606ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const Section *mach_header_section, const Section *section)
5607{
5608 ModuleSP module_sp = GetModule();
5609 if (module_sp && mach_header_section && section && mach_header_load_address != LLDB_INVALID_ADDRESS)
5610 {
5611 lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
5612 if (mach_header_file_addr != LLDB_INVALID_ADDRESS)
5613 {
5614 if (section &&
5615 section->GetFileSize() > 0 &&
5616 section->IsThreadSpecific() == false &&
5617 module_sp.get() == section->GetModule().get())
5618 {
5619 // Ignore __LINKEDIT and __DWARF segments
5620 if (section->GetName() == GetSegmentNameLINKEDIT())
5621 {
5622 // Only map __LINKEDIT if we have an in memory image and this isn't
5623 // a kernel binary like a kext or mach_kernel.
5624 const bool is_memory_image = (bool)m_process_wp.lock();
5625 const Strata strata = GetStrata();
5626 if (is_memory_image == false || strata == eStrataKernel)
5627 return LLDB_INVALID_ADDRESS;
5628 }
5629 return section->GetFileAddress() - mach_header_file_addr + mach_header_load_address;
5630 }
5631 }
5632 }
5633 return LLDB_INVALID_ADDRESS;
5634}
5635
Greg Clayton7524e092014-02-06 20:10:16 +00005636bool
Greg Clayton751caf62014-02-07 22:54:47 +00005637ObjectFileMachO::SetLoadAddress (Target &target,
5638 lldb::addr_t value,
5639 bool value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005640{
Greg Clayton7524e092014-02-06 20:10:16 +00005641 ModuleSP module_sp = GetModule();
5642 if (module_sp)
5643 {
5644 size_t num_loaded_sections = 0;
5645 SectionList *section_list = GetSectionList ();
5646 if (section_list)
5647 {
Greg Clayton7524e092014-02-06 20:10:16 +00005648 const size_t num_sections = section_list->GetSize();
5649
Greg Clayton751caf62014-02-07 22:54:47 +00005650 if (value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005651 {
Greg Clayton751caf62014-02-07 22:54:47 +00005652 // "value" is an offset to apply to each top level segment
Greg Clayton7524e092014-02-06 20:10:16 +00005653 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5654 {
5655 // Iterate through the object file sections to find all
5656 // of the sections that size on disk (to avoid __PAGEZERO)
5657 // and load them
5658 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton751caf62014-02-07 22:54:47 +00005659 if (section_sp &&
5660 section_sp->GetFileSize() > 0 &&
5661 section_sp->IsThreadSpecific() == false &&
5662 module_sp.get() == section_sp->GetModule().get())
Greg Clayton7524e092014-02-06 20:10:16 +00005663 {
Greg Clayton751caf62014-02-07 22:54:47 +00005664 // Ignore __LINKEDIT and __DWARF segments
Greg Clayton07347372015-06-08 21:53:11 +00005665 if (section_sp->GetName() == GetSegmentNameLINKEDIT())
Greg Clayton751caf62014-02-07 22:54:47 +00005666 {
5667 // Only map __LINKEDIT if we have an in memory image and this isn't
5668 // a kernel binary like a kext or mach_kernel.
Greg Clayton07347372015-06-08 21:53:11 +00005669 const bool is_memory_image = (bool)m_process_wp.lock();
5670 const Strata strata = GetStrata();
Greg Clayton751caf62014-02-07 22:54:47 +00005671 if (is_memory_image == false || strata == eStrataKernel)
5672 continue;
5673 }
5674 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
Greg Clayton7524e092014-02-06 20:10:16 +00005675 ++num_loaded_sections;
5676 }
5677 }
5678 }
Greg Clayton751caf62014-02-07 22:54:47 +00005679 else
5680 {
5681 // "value" is the new base address of the mach_header, adjust each
5682 // section accordingly
5683
Greg Clayton07347372015-06-08 21:53:11 +00005684 Section *mach_header_section = GetMachHeaderSection();
5685 if (mach_header_section)
Greg Clayton751caf62014-02-07 22:54:47 +00005686 {
5687 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5688 {
Greg Clayton751caf62014-02-07 22:54:47 +00005689 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton07347372015-06-08 21:53:11 +00005690
5691 lldb::addr_t section_load_addr = CalculateSectionLoadAddressForMemoryImage(value, mach_header_section, section_sp.get());
5692 if (section_load_addr != LLDB_INVALID_ADDRESS)
Greg Clayton751caf62014-02-07 22:54:47 +00005693 {
Greg Clayton07347372015-06-08 21:53:11 +00005694 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_load_addr))
Greg Clayton751caf62014-02-07 22:54:47 +00005695 ++num_loaded_sections;
5696 }
5697 }
5698 }
5699 }
Greg Clayton7524e092014-02-06 20:10:16 +00005700 }
Greg Clayton7524e092014-02-06 20:10:16 +00005701 return num_loaded_sections > 0;
5702 }
Jason Molenda5cf1e232014-10-16 07:41:32 +00005703 return false;
Greg Clayton7524e092014-02-06 20:10:16 +00005704}
5705
Greg Claytona2715cf2014-06-13 00:54:12 +00005706bool
5707ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp,
5708 const FileSpec &outfile,
5709 Error &error)
5710{
5711 if (process_sp)
5712 {
5713 Target &target = process_sp->GetTarget();
5714 const ArchSpec target_arch = target.GetArchitecture();
5715 const llvm::Triple &target_triple = target_arch.GetTriple();
5716 if (target_triple.getVendor() == llvm::Triple::Apple &&
5717 (target_triple.getOS() == llvm::Triple::MacOSX ||
5718 target_triple.getOS() == llvm::Triple::IOS))
5719 {
5720 bool make_core = false;
5721 switch (target_arch.GetMachine())
5722 {
Jason Molenda16dc86d2015-06-25 23:58:25 +00005723 case llvm::Triple::aarch64:
Jason Molenda4b0c1182014-11-12 02:39:14 +00005724 case llvm::Triple::arm:
Jason Molenda6d9fe8c2015-08-21 00:13:37 +00005725 case llvm::Triple::thumb:
Greg Claytona2715cf2014-06-13 00:54:12 +00005726 case llvm::Triple::x86:
5727 case llvm::Triple::x86_64:
5728 make_core = true;
5729 break;
5730 default:
5731 error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str());
5732 break;
5733 }
5734
5735 if (make_core)
5736 {
5737 std::vector<segment_command_64> segment_load_commands;
Saleem Abdulrasool3924d752014-06-13 03:30:39 +00005738// uint32_t range_info_idx = 0;
Greg Claytona2715cf2014-06-13 00:54:12 +00005739 MemoryRegionInfo range_info;
5740 Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
Jason Molendad20359d2014-11-11 10:59:15 +00005741 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
5742 const ByteOrder byte_order = target_arch.GetByteOrder();
Greg Claytona2715cf2014-06-13 00:54:12 +00005743 if (range_error.Success())
5744 {
5745 while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS)
5746 {
5747 const addr_t addr = range_info.GetRange().GetRangeBase();
5748 const addr_t size = range_info.GetRange().GetByteSize();
5749
5750 if (size == 0)
5751 break;
5752
5753 // Calculate correct protections
5754 uint32_t prot = 0;
5755 if (range_info.GetReadable() == MemoryRegionInfo::eYes)
5756 prot |= VM_PROT_READ;
5757 if (range_info.GetWritable() == MemoryRegionInfo::eYes)
5758 prot |= VM_PROT_WRITE;
5759 if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
5760 prot |= VM_PROT_EXECUTE;
5761
5762// printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n",
5763// range_info_idx,
5764// addr,
5765// size,
5766// (prot & VM_PROT_READ ) ? 'r' : '-',
5767// (prot & VM_PROT_WRITE ) ? 'w' : '-',
5768// (prot & VM_PROT_EXECUTE) ? 'x' : '-');
5769
5770 if (prot != 0)
5771 {
Jason Molendad20359d2014-11-11 10:59:15 +00005772 uint32_t cmd_type = LC_SEGMENT_64;
5773 uint32_t segment_size = sizeof (segment_command_64);
5774 if (addr_byte_size == 4)
5775 {
5776 cmd_type = LC_SEGMENT;
5777 segment_size = sizeof (segment_command);
5778 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005779 segment_command_64 segment = {
Jason Molendad20359d2014-11-11 10:59:15 +00005780 cmd_type, // uint32_t cmd;
5781 segment_size, // uint32_t cmdsize;
Greg Claytona2715cf2014-06-13 00:54:12 +00005782 {0}, // char segname[16];
Jason Molendad20359d2014-11-11 10:59:15 +00005783 addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
5784 size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
5785 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
5786 size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
Greg Claytona2715cf2014-06-13 00:54:12 +00005787 prot, // uint32_t maxprot;
5788 prot, // uint32_t initprot;
5789 0, // uint32_t nsects;
5790 0 }; // uint32_t flags;
5791 segment_load_commands.push_back(segment);
5792 }
5793 else
5794 {
5795 // No protections and a size of 1 used to be returned from old
5796 // debugservers when we asked about a region that was past the
5797 // last memory region and it indicates the end...
5798 if (size == 1)
5799 break;
5800 }
5801
5802 range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info);
5803 if (range_error.Fail())
5804 break;
5805 }
5806
Greg Claytona2715cf2014-06-13 00:54:12 +00005807 StreamString buffer (Stream::eBinary,
5808 addr_byte_size,
5809 byte_order);
5810
5811 mach_header_64 mach_header;
Jason Molendad20359d2014-11-11 10:59:15 +00005812 if (addr_byte_size == 8)
5813 {
5814 mach_header.magic = MH_MAGIC_64;
5815 }
5816 else
5817 {
5818 mach_header.magic = MH_MAGIC;
5819 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005820 mach_header.cputype = target_arch.GetMachOCPUType();
5821 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
5822 mach_header.filetype = MH_CORE;
5823 mach_header.ncmds = segment_load_commands.size();
5824 mach_header.flags = 0;
5825 mach_header.reserved = 0;
5826 ThreadList &thread_list = process_sp->GetThreadList();
5827 const uint32_t num_threads = thread_list.GetSize();
5828
5829 // Make an array of LC_THREAD data items. Each one contains
5830 // the contents of the LC_THREAD load command. The data doesn't
5831 // contain the load command + load command size, we will
5832 // add the load command and load command size as we emit the data.
5833 std::vector<StreamString> LC_THREAD_datas(num_threads);
5834 for (auto &LC_THREAD_data : LC_THREAD_datas)
5835 {
5836 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
5837 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
5838 LC_THREAD_data.SetByteOrder(byte_order);
5839 }
5840 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
5841 {
5842 ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx));
5843 if (thread_sp)
5844 {
5845 switch (mach_header.cputype)
5846 {
Jason Molenda22952582014-11-12 01:11:36 +00005847 case llvm::MachO::CPU_TYPE_ARM64:
5848 RegisterContextDarwin_arm64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005849 break;
Jason Molenda22952582014-11-12 01:11:36 +00005850
5851 case llvm::MachO::CPU_TYPE_ARM:
5852 RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5853 break;
5854
Greg Claytona2715cf2014-06-13 00:54:12 +00005855 case llvm::MachO::CPU_TYPE_I386:
Jason Molendad20359d2014-11-11 10:59:15 +00005856 RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005857 break;
5858
5859 case llvm::MachO::CPU_TYPE_X86_64:
5860 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5861 break;
5862 }
5863
5864 }
5865 }
5866
5867 // The size of the load command is the size of the segments...
Jason Molendad20359d2014-11-11 10:59:15 +00005868 if (addr_byte_size == 8)
5869 {
5870 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64);
5871 }
5872 else
5873 {
5874 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command);
5875 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005876
5877 // and the size of all LC_THREAD load command
5878 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5879 {
Greg Claytone37df2e2014-09-16 20:50:29 +00005880 ++mach_header.ncmds;
Greg Claytona2715cf2014-06-13 00:54:12 +00005881 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
5882 }
5883
5884 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",
5885 mach_header.magic,
5886 mach_header.cputype,
5887 mach_header.cpusubtype,
5888 mach_header.filetype,
5889 mach_header.ncmds,
5890 mach_header.sizeofcmds,
5891 mach_header.flags,
5892 mach_header.reserved);
5893
5894 // Write the mach header
5895 buffer.PutHex32(mach_header.magic);
5896 buffer.PutHex32(mach_header.cputype);
5897 buffer.PutHex32(mach_header.cpusubtype);
5898 buffer.PutHex32(mach_header.filetype);
5899 buffer.PutHex32(mach_header.ncmds);
5900 buffer.PutHex32(mach_header.sizeofcmds);
5901 buffer.PutHex32(mach_header.flags);
Jason Molendad20359d2014-11-11 10:59:15 +00005902 if (addr_byte_size == 8)
5903 {
5904 buffer.PutHex32(mach_header.reserved);
5905 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005906
5907 // Skip the mach header and all load commands and align to the next
5908 // 0x1000 byte boundary
5909 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
5910 if (file_offset & 0x00000fff)
5911 {
5912 file_offset += 0x00001000ull;
5913 file_offset &= (~0x00001000ull + 1);
5914 }
5915
5916 for (auto &segment : segment_load_commands)
5917 {
5918 segment.fileoff = file_offset;
5919 file_offset += segment.filesize;
5920 }
5921
5922 // Write out all of the LC_THREAD load commands
5923 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5924 {
5925 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
5926 buffer.PutHex32(LC_THREAD);
5927 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
5928 buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size);
5929 }
5930
5931 // Write out all of the segment load commands
5932 for (const auto &segment : segment_load_commands)
5933 {
5934 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",
5935 segment.cmd,
5936 segment.cmdsize,
5937 segment.vmaddr,
5938 segment.vmaddr + segment.vmsize,
5939 segment.fileoff,
5940 segment.filesize,
5941 segment.maxprot,
5942 segment.initprot,
5943 segment.nsects,
5944 segment.flags);
5945
5946 buffer.PutHex32(segment.cmd);
5947 buffer.PutHex32(segment.cmdsize);
5948 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
Jason Molendad20359d2014-11-11 10:59:15 +00005949 if (addr_byte_size == 8)
5950 {
5951 buffer.PutHex64(segment.vmaddr);
5952 buffer.PutHex64(segment.vmsize);
5953 buffer.PutHex64(segment.fileoff);
5954 buffer.PutHex64(segment.filesize);
5955 }
5956 else
5957 {
5958 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
5959 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
5960 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
5961 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
5962 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005963 buffer.PutHex32(segment.maxprot);
5964 buffer.PutHex32(segment.initprot);
5965 buffer.PutHex32(segment.nsects);
5966 buffer.PutHex32(segment.flags);
5967 }
5968
5969 File core_file;
5970 std::string core_file_path(outfile.GetPath());
5971 error = core_file.Open(core_file_path.c_str(),
5972 File::eOpenOptionWrite |
5973 File::eOpenOptionTruncate |
5974 File::eOpenOptionCanCreate);
5975 if (error.Success())
5976 {
5977 // Read 1 page at a time
5978 uint8_t bytes[0x1000];
5979 // Write the mach header and load commands out to the core file
5980 size_t bytes_written = buffer.GetString().size();
5981 error = core_file.Write(buffer.GetString().data(), bytes_written);
5982 if (error.Success())
5983 {
5984 // Now write the file data for all memory segments in the process
5985 for (const auto &segment : segment_load_commands)
5986 {
David Majnemerb98a5e02014-07-24 00:24:12 +00005987 if (core_file.SeekFromStart(segment.fileoff) == -1)
Greg Claytona2715cf2014-06-13 00:54:12 +00005988 {
5989 error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str());
5990 break;
5991 }
5992
Jason Molendad20359d2014-11-11 10:59:15 +00005993 printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr);
Greg Claytona2715cf2014-06-13 00:54:12 +00005994 addr_t bytes_left = segment.vmsize;
5995 addr_t addr = segment.vmaddr;
5996 Error memory_read_error;
5997 while (bytes_left > 0 && error.Success())
5998 {
5999 const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
6000 const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error);
6001 if (bytes_read == bytes_to_read)
6002 {
6003 size_t bytes_written = bytes_read;
6004 error = core_file.Write(bytes, bytes_written);
6005 bytes_left -= bytes_read;
6006 addr += bytes_read;
6007 }
6008 else
6009 {
6010 // Some pages within regions are not readable, those
6011 // should be zero filled
6012 memset (bytes, 0, bytes_to_read);
6013 size_t bytes_written = bytes_to_read;
6014 error = core_file.Write(bytes, bytes_written);
6015 bytes_left -= bytes_to_read;
6016 addr += bytes_to_read;
6017 }
6018 }
6019 }
6020 }
6021 }
6022 }
6023 else
6024 {
6025 error.SetErrorString("process doesn't support getting memory region info");
6026 }
6027 }
6028 return true; // This is the right plug to handle saving core files for this process
6029 }
6030 }
6031 return false;
6032}
6033