blob: 660c31e6683caba4e27e0b3b656f1705b7ec5491 [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"
Sean Callananb6d70eb2011-10-12 02:08:07 +000029#include "lldb/Symbol/ClangNamespaceDecl.h"
Jason Molenda5635f772013-03-21 03:36:01 +000030#include "lldb/Symbol/DWARFCallFrameInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Symbol/ObjectFile.h"
Zachary Turner93749ab2015-03-03 21:51:25 +000032#include "lldb/Target/MemoryRegionInfo.h"
Greg Clayton26b47e22012-04-18 05:19:20 +000033#include "lldb/Target/Platform.h"
Greg Claytonc9660542012-02-05 02:38:54 +000034#include "lldb/Target/Process.h"
Greg Clayton7524e092014-02-06 20:10:16 +000035#include "lldb/Target/SectionLoadList.h"
Greg Clayton26b47e22012-04-18 05:19:20 +000036#include "lldb/Target/Target.h"
Greg Claytona2715cf2014-06-13 00:54:12 +000037#include "lldb/Target/Thread.h"
38#include "lldb/Target/ThreadList.h"
Greg Claytonc859e2d2012-02-13 23:10:39 +000039#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
Jason Molendaa3329782014-03-29 18:54:20 +000040#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
Greg Claytonc859e2d2012-02-13 23:10:39 +000041#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
Greg Claytonc3776bf2012-02-09 06:16:32 +000042#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043
Jim Ingham46d005d2014-04-02 22:53:21 +000044#include "lldb/Utility/SafeMachO.h"
45
46#include "ObjectFileMachO.h"
47
Todd Fiala013434e2014-07-09 01:29:05 +000048#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +000049// GetLLDBSharedCacheUUID() needs to call dlsym()
50#include <dlfcn.h>
51#endif
52
Daniel Maleaffeb4b62013-04-17 19:24:22 +000053#ifndef __APPLE__
54#include "Utility/UuidCompatibility.h"
55#endif
56
Greg Claytonb887da12015-07-16 19:50:57 +000057#define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058using namespace lldb;
59using namespace lldb_private;
Greg Claytone1a916a2010-07-21 22:12:05 +000060using namespace llvm::MachO;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061
Jason Molenda4e7511e2013-03-06 23:19:17 +000062class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
Greg Claytonc3776bf2012-02-09 06:16:32 +000063{
64public:
65 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
66 RegisterContextDarwin_x86_64 (thread, 0)
67 {
68 SetRegisterDataFrom_LC_THREAD (data);
69 }
70
71 virtual void
72 InvalidateAllRegisters ()
73 {
74 // Do nothing... registers are always valid...
75 }
76
77 void
78 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
79 {
Greg Claytonc7bece562013-01-25 18:06:21 +000080 lldb::offset_t offset = 0;
Greg Claytonc3776bf2012-02-09 06:16:32 +000081 SetError (GPRRegSet, Read, -1);
82 SetError (FPURegSet, Read, -1);
83 SetError (EXCRegSet, Read, -1);
Greg Claytonc859e2d2012-02-13 23:10:39 +000084 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +000085
Greg Claytonc859e2d2012-02-13 23:10:39 +000086 while (!done)
Greg Claytonc3776bf2012-02-09 06:16:32 +000087 {
Greg Claytonc859e2d2012-02-13 23:10:39 +000088 int flavor = data.GetU32 (&offset);
89 if (flavor == 0)
90 done = true;
91 else
Greg Claytonc3776bf2012-02-09 06:16:32 +000092 {
Greg Claytonc859e2d2012-02-13 23:10:39 +000093 uint32_t i;
94 uint32_t count = data.GetU32 (&offset);
95 switch (flavor)
96 {
97 case GPRRegSet:
98 for (i=0; i<count; ++i)
99 (&gpr.rax)[i] = data.GetU64(&offset);
100 SetError (GPRRegSet, Read, 0);
101 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000102
Greg Claytonc859e2d2012-02-13 23:10:39 +0000103 break;
104 case FPURegSet:
105 // TODO: fill in FPU regs....
106 //SetError (FPURegSet, Read, -1);
107 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000108
Greg Claytonc859e2d2012-02-13 23:10:39 +0000109 break;
110 case EXCRegSet:
111 exc.trapno = data.GetU32(&offset);
112 exc.err = data.GetU32(&offset);
113 exc.faultvaddr = data.GetU64(&offset);
114 SetError (EXCRegSet, Read, 0);
115 done = true;
116 break;
117 case 7:
118 case 8:
119 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000120 // fancy flavors that encapsulate of the above
121 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000122 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000123
Greg Claytonc859e2d2012-02-13 23:10:39 +0000124 default:
125 done = true;
126 break;
127 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000128 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000129 }
130 }
Greg Claytona2715cf2014-06-13 00:54:12 +0000131
Jason Molendad20359d2014-11-11 10:59:15 +0000132
Greg Claytona2715cf2014-06-13 00:54:12 +0000133 static size_t
134 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
135 {
136 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
137 if (reg_info == NULL)
138 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
139 if (reg_info)
140 {
141 lldb_private::RegisterValue reg_value;
142 if (reg_ctx->ReadRegister(reg_info, reg_value))
143 {
144 if (reg_info->byte_size >= reg_byte_size)
145 data.Write(reg_value.GetBytes(), reg_byte_size);
146 else
147 {
148 data.Write(reg_value.GetBytes(), reg_info->byte_size);
149 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
150 data.PutChar(0);
151 }
152 return reg_byte_size;
153 }
154 }
155 // Just write zeros if all else fails
156 for (size_t i=0; i<reg_byte_size; ++ i)
157 data.PutChar(0);
158 return reg_byte_size;
159 }
Jason Molendad20359d2014-11-11 10:59:15 +0000160
Greg Claytona2715cf2014-06-13 00:54:12 +0000161 static bool
162 Create_LC_THREAD (Thread *thread, Stream &data)
163 {
164 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
165 if (reg_ctx_sp)
166 {
167 RegisterContext *reg_ctx = reg_ctx_sp.get();
168
169 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000170 data.PutHex32 (GPRWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000171 WriteRegister (reg_ctx, "rax", NULL, 8, data);
172 WriteRegister (reg_ctx, "rbx", NULL, 8, data);
173 WriteRegister (reg_ctx, "rcx", NULL, 8, data);
174 WriteRegister (reg_ctx, "rdx", NULL, 8, data);
175 WriteRegister (reg_ctx, "rdi", NULL, 8, data);
176 WriteRegister (reg_ctx, "rsi", NULL, 8, data);
177 WriteRegister (reg_ctx, "rbp", NULL, 8, data);
178 WriteRegister (reg_ctx, "rsp", NULL, 8, data);
179 WriteRegister (reg_ctx, "r8", NULL, 8, data);
180 WriteRegister (reg_ctx, "r9", NULL, 8, data);
181 WriteRegister (reg_ctx, "r10", NULL, 8, data);
182 WriteRegister (reg_ctx, "r11", NULL, 8, data);
183 WriteRegister (reg_ctx, "r12", NULL, 8, data);
184 WriteRegister (reg_ctx, "r13", NULL, 8, data);
185 WriteRegister (reg_ctx, "r14", NULL, 8, data);
186 WriteRegister (reg_ctx, "r15", NULL, 8, data);
187 WriteRegister (reg_ctx, "rip", NULL, 8, data);
188 WriteRegister (reg_ctx, "rflags", NULL, 8, data);
189 WriteRegister (reg_ctx, "cs", NULL, 8, data);
190 WriteRegister (reg_ctx, "fs", NULL, 8, data);
191 WriteRegister (reg_ctx, "gs", NULL, 8, data);
192
193// // Write out the FPU registers
194// const size_t fpu_byte_size = sizeof(FPU);
195// size_t bytes_written = 0;
196// data.PutHex32 (FPURegSet);
197// data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
198// bytes_written += data.PutHex32(0); // uint32_t pad[0]
199// bytes_written += data.PutHex32(0); // uint32_t pad[1]
200// bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, data); // uint16_t fcw; // "fctrl"
201// bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, data); // uint16_t fsw; // "fstat"
202// bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, data); // uint8_t ftw; // "ftag"
203// bytes_written += data.PutHex8 (0); // uint8_t pad1;
204// bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, data); // uint16_t fop; // "fop"
205// bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, data); // uint32_t ip; // "fioff"
206// bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, data); // uint16_t cs; // "fiseg"
207// bytes_written += data.PutHex16 (0); // uint16_t pad2;
208// bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, data); // uint32_t dp; // "fooff"
209// bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, data); // uint16_t ds; // "foseg"
210// bytes_written += data.PutHex16 (0); // uint16_t pad3;
211// bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, data); // uint32_t mxcsr;
212// bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, 4, data);// uint32_t mxcsrmask;
213// bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, sizeof(MMSReg), data);
214// bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, sizeof(MMSReg), data);
215// bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, sizeof(MMSReg), data);
216// bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, sizeof(MMSReg), data);
217// bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, sizeof(MMSReg), data);
218// bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, sizeof(MMSReg), data);
219// bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, sizeof(MMSReg), data);
220// bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, sizeof(MMSReg), data);
221// bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, sizeof(XMMReg), data);
222// bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, sizeof(XMMReg), data);
223// bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, sizeof(XMMReg), data);
224// bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, sizeof(XMMReg), data);
225// bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, sizeof(XMMReg), data);
226// bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, sizeof(XMMReg), data);
227// bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, sizeof(XMMReg), data);
228// bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, sizeof(XMMReg), data);
229// bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, sizeof(XMMReg), data);
230// bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, sizeof(XMMReg), data);
231// bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, sizeof(XMMReg), data);
232// bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, sizeof(XMMReg), data);
233// bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, sizeof(XMMReg), data);
234// bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, sizeof(XMMReg), data);
235// bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, sizeof(XMMReg), data);
236// bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, sizeof(XMMReg), data);
237//
238// // Fill rest with zeros
239// for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ i)
240// data.PutChar(0);
241
242 // Write out the EXC registers
243 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000244 data.PutHex32 (EXCWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000245 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
246 WriteRegister (reg_ctx, "err", NULL, 4, data);
247 WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data);
248 return true;
249 }
250 return false;
251 }
252
Greg Claytonc859e2d2012-02-13 23:10:39 +0000253protected:
254 virtual int
255 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
256 {
257 return 0;
258 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000259
Greg Claytonc859e2d2012-02-13 23:10:39 +0000260 virtual int
261 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
262 {
263 return 0;
264 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000265
Greg Claytonc859e2d2012-02-13 23:10:39 +0000266 virtual int
267 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
268 {
269 return 0;
270 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000271
Greg Claytonc859e2d2012-02-13 23:10:39 +0000272 virtual int
273 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
274 {
275 return 0;
276 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000277
Greg Claytonc859e2d2012-02-13 23:10:39 +0000278 virtual int
279 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
280 {
281 return 0;
282 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000283
Greg Claytonc859e2d2012-02-13 23:10:39 +0000284 virtual int
285 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
286 {
287 return 0;
288 }
289};
Greg Claytonc3776bf2012-02-09 06:16:32 +0000290
Greg Claytonc859e2d2012-02-13 23:10:39 +0000291
Jason Molenda4e7511e2013-03-06 23:19:17 +0000292class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
Greg Claytonc859e2d2012-02-13 23:10:39 +0000293{
294public:
295 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
296 RegisterContextDarwin_i386 (thread, 0)
297 {
298 SetRegisterDataFrom_LC_THREAD (data);
299 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000300
Greg Claytonc859e2d2012-02-13 23:10:39 +0000301 virtual void
302 InvalidateAllRegisters ()
303 {
304 // Do nothing... registers are always valid...
305 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000306
Greg Claytonc859e2d2012-02-13 23:10:39 +0000307 void
308 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
309 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000310 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000311 SetError (GPRRegSet, Read, -1);
312 SetError (FPURegSet, Read, -1);
313 SetError (EXCRegSet, Read, -1);
314 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000315
Greg Claytonc859e2d2012-02-13 23:10:39 +0000316 while (!done)
317 {
318 int flavor = data.GetU32 (&offset);
319 if (flavor == 0)
320 done = true;
321 else
Greg Claytonc3776bf2012-02-09 06:16:32 +0000322 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000323 uint32_t i;
324 uint32_t count = data.GetU32 (&offset);
325 switch (flavor)
326 {
327 case GPRRegSet:
328 for (i=0; i<count; ++i)
329 (&gpr.eax)[i] = data.GetU32(&offset);
330 SetError (GPRRegSet, Read, 0);
331 done = true;
332
333 break;
334 case FPURegSet:
335 // TODO: fill in FPU regs....
336 //SetError (FPURegSet, Read, -1);
337 done = true;
338
339 break;
340 case EXCRegSet:
341 exc.trapno = data.GetU32(&offset);
342 exc.err = data.GetU32(&offset);
343 exc.faultvaddr = data.GetU32(&offset);
344 SetError (EXCRegSet, Read, 0);
345 done = true;
346 break;
347 case 7:
348 case 8:
349 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000350 // fancy flavors that encapsulate of the above
351 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000352 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000353
Greg Claytonc859e2d2012-02-13 23:10:39 +0000354 default:
355 done = true;
356 break;
357 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000358 }
359 }
360 }
Jason Molendad20359d2014-11-11 10:59:15 +0000361
362 static size_t
363 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
364 {
365 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
366 if (reg_info == NULL)
367 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
368 if (reg_info)
369 {
370 lldb_private::RegisterValue reg_value;
371 if (reg_ctx->ReadRegister(reg_info, reg_value))
372 {
373 if (reg_info->byte_size >= reg_byte_size)
374 data.Write(reg_value.GetBytes(), reg_byte_size);
375 else
376 {
377 data.Write(reg_value.GetBytes(), reg_info->byte_size);
378 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
379 data.PutChar(0);
380 }
381 return reg_byte_size;
382 }
383 }
384 // Just write zeros if all else fails
385 for (size_t i=0; i<reg_byte_size; ++ i)
386 data.PutChar(0);
387 return reg_byte_size;
388 }
389
390 static bool
391 Create_LC_THREAD (Thread *thread, Stream &data)
392 {
393 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
394 if (reg_ctx_sp)
395 {
396 RegisterContext *reg_ctx = reg_ctx_sp.get();
397
398 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000399 data.PutHex32 (GPRWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000400 WriteRegister (reg_ctx, "eax", NULL, 4, data);
401 WriteRegister (reg_ctx, "ebx", NULL, 4, data);
402 WriteRegister (reg_ctx, "ecx", NULL, 4, data);
403 WriteRegister (reg_ctx, "edx", NULL, 4, data);
404 WriteRegister (reg_ctx, "edi", NULL, 4, data);
405 WriteRegister (reg_ctx, "esi", NULL, 4, data);
406 WriteRegister (reg_ctx, "ebp", NULL, 4, data);
407 WriteRegister (reg_ctx, "esp", NULL, 4, data);
408 WriteRegister (reg_ctx, "ss", NULL, 4, data);
409 WriteRegister (reg_ctx, "eflags", NULL, 4, data);
410 WriteRegister (reg_ctx, "eip", NULL, 4, data);
411 WriteRegister (reg_ctx, "cs", NULL, 4, data);
412 WriteRegister (reg_ctx, "ds", NULL, 4, data);
413 WriteRegister (reg_ctx, "es", NULL, 4, data);
414 WriteRegister (reg_ctx, "fs", NULL, 4, data);
415 WriteRegister (reg_ctx, "gs", NULL, 4, data);
416
417 // Write out the EXC registers
418 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000419 data.PutHex32 (EXCWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000420 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
421 WriteRegister (reg_ctx, "err", NULL, 4, data);
Jason Molenda22952582014-11-12 01:11:36 +0000422 WriteRegister (reg_ctx, "faultvaddr", NULL, 4, data);
Jason Molendad20359d2014-11-11 10:59:15 +0000423 return true;
424 }
425 return false;
426 }
427
Greg Claytonc3776bf2012-02-09 06:16:32 +0000428protected:
429 virtual int
430 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
431 {
432 return 0;
433 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000434
Greg Claytonc3776bf2012-02-09 06:16:32 +0000435 virtual int
436 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
437 {
438 return 0;
439 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000440
Greg Claytonc3776bf2012-02-09 06:16:32 +0000441 virtual int
442 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
443 {
444 return 0;
445 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000446
Greg Claytonc3776bf2012-02-09 06:16:32 +0000447 virtual int
448 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
449 {
450 return 0;
451 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000452
Greg Claytonc3776bf2012-02-09 06:16:32 +0000453 virtual int
454 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
455 {
456 return 0;
457 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000458
Greg Claytonc3776bf2012-02-09 06:16:32 +0000459 virtual int
460 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
461 {
462 return 0;
463 }
464};
465
Jason Molenda4e7511e2013-03-06 23:19:17 +0000466class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000467{
468public:
469 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
Greg Claytonc2807462012-10-30 23:57:32 +0000470 RegisterContextDarwin_arm (thread, 0)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000471 {
472 SetRegisterDataFrom_LC_THREAD (data);
473 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000474
Greg Claytonc859e2d2012-02-13 23:10:39 +0000475 virtual void
476 InvalidateAllRegisters ()
477 {
478 // Do nothing... registers are always valid...
479 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000480
Greg Claytonc859e2d2012-02-13 23:10:39 +0000481 void
482 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
483 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000484 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000485 SetError (GPRRegSet, Read, -1);
486 SetError (FPURegSet, Read, -1);
487 SetError (EXCRegSet, Read, -1);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000488 bool done = false;
489
490 while (!done)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000491 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000492 int flavor = data.GetU32 (&offset);
493 uint32_t count = data.GetU32 (&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000494 lldb::offset_t next_thread_state = offset + (count * 4);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000495 switch (flavor)
496 {
497 case GPRRegSet:
498 for (uint32_t i=0; i<count; ++i)
Jason Molendaddf91772013-05-14 04:50:47 +0000499 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000500 gpr.r[i] = data.GetU32(&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000501 }
502
503 // Note that gpr.cpsr is also copied by the above loop; this loop technically extends
504 // one element past the end of the gpr.r[] array.
505
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000506 SetError (GPRRegSet, Read, 0);
Jason Molendaddf91772013-05-14 04:50:47 +0000507 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000508 break;
509
510 case FPURegSet:
511 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000512 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0];
513 const int fpu_reg_buf_size = sizeof (fpu.floats);
514 if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000515 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000516 offset += fpu_reg_buf_size;
517 fpu.fpscr = data.GetU32(&offset);
518 SetError (FPURegSet, Read, 0);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000519 }
Jason Molenda663d2e12013-05-14 03:52:22 +0000520 else
521 {
522 done = true;
523 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000524 }
Jason Molendaddf91772013-05-14 04:50:47 +0000525 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000526 break;
527
528 case EXCRegSet:
Jason Molendaddf91772013-05-14 04:50:47 +0000529 if (count == 3)
530 {
531 exc.exception = data.GetU32(&offset);
532 exc.fsr = data.GetU32(&offset);
533 exc.far = data.GetU32(&offset);
534 SetError (EXCRegSet, Read, 0);
535 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000536 done = true;
Jason Molendaddf91772013-05-14 04:50:47 +0000537 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000538 break;
539
540 // Unknown register set flavor, stop trying to parse.
541 default:
542 done = true;
543 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000544 }
545 }
Jason Molenda22952582014-11-12 01:11:36 +0000546
547 static size_t
548 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
549 {
550 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
551 if (reg_info == NULL)
552 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
553 if (reg_info)
554 {
555 lldb_private::RegisterValue reg_value;
556 if (reg_ctx->ReadRegister(reg_info, reg_value))
557 {
558 if (reg_info->byte_size >= reg_byte_size)
559 data.Write(reg_value.GetBytes(), reg_byte_size);
560 else
561 {
562 data.Write(reg_value.GetBytes(), reg_info->byte_size);
563 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
564 data.PutChar(0);
565 }
566 return reg_byte_size;
567 }
568 }
569 // Just write zeros if all else fails
570 for (size_t i=0; i<reg_byte_size; ++ i)
571 data.PutChar(0);
572 return reg_byte_size;
573 }
574
575 static bool
576 Create_LC_THREAD (Thread *thread, Stream &data)
577 {
578 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
579 if (reg_ctx_sp)
580 {
581 RegisterContext *reg_ctx = reg_ctx_sp.get();
582
583 data.PutHex32 (GPRRegSet); // Flavor
584 data.PutHex32 (GPRWordCount);
585 WriteRegister (reg_ctx, "r0", NULL, 4, data);
586 WriteRegister (reg_ctx, "r1", NULL, 4, data);
587 WriteRegister (reg_ctx, "r2", NULL, 4, data);
588 WriteRegister (reg_ctx, "r3", NULL, 4, data);
589 WriteRegister (reg_ctx, "r4", NULL, 4, data);
590 WriteRegister (reg_ctx, "r5", NULL, 4, data);
591 WriteRegister (reg_ctx, "r6", NULL, 4, data);
592 WriteRegister (reg_ctx, "r7", NULL, 4, data);
593 WriteRegister (reg_ctx, "r8", NULL, 4, data);
594 WriteRegister (reg_ctx, "r9", NULL, 4, data);
595 WriteRegister (reg_ctx, "r10", NULL, 4, data);
596 WriteRegister (reg_ctx, "r11", NULL, 4, data);
597 WriteRegister (reg_ctx, "r12", NULL, 4, data);
598 WriteRegister (reg_ctx, "sp", NULL, 4, data);
599 WriteRegister (reg_ctx, "lr", NULL, 4, data);
600 WriteRegister (reg_ctx, "pc", NULL, 4, data);
601 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
602
603 // Write out the EXC registers
604// data.PutHex32 (EXCRegSet);
605// data.PutHex32 (EXCWordCount);
606// WriteRegister (reg_ctx, "exception", NULL, 4, data);
607// WriteRegister (reg_ctx, "fsr", NULL, 4, data);
608// WriteRegister (reg_ctx, "far", NULL, 4, data);
609 return true;
610 }
611 return false;
612 }
613
Greg Claytonc859e2d2012-02-13 23:10:39 +0000614protected:
615 virtual int
616 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
617 {
Jason Molendaddf91772013-05-14 04:50:47 +0000618 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000619 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000620
Greg Claytonc859e2d2012-02-13 23:10:39 +0000621 virtual int
622 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
623 {
Jason Molendaddf91772013-05-14 04:50:47 +0000624 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000625 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000626
Greg Claytonc859e2d2012-02-13 23:10:39 +0000627 virtual int
628 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
629 {
Jason Molendaddf91772013-05-14 04:50:47 +0000630 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000631 }
Greg Claytonc2807462012-10-30 23:57:32 +0000632
633 virtual int
634 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
635 {
636 return -1;
637 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000638
Greg Claytonc859e2d2012-02-13 23:10:39 +0000639 virtual int
640 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
641 {
642 return 0;
643 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000644
Greg Claytonc859e2d2012-02-13 23:10:39 +0000645 virtual int
646 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
647 {
648 return 0;
649 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000650
Greg Claytonc859e2d2012-02-13 23:10:39 +0000651 virtual int
652 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
653 {
654 return 0;
655 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000656
Greg Claytonc2807462012-10-30 23:57:32 +0000657 virtual int
658 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
659 {
660 return -1;
661 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000662};
663
Jason Molendaa3329782014-03-29 18:54:20 +0000664class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
665{
666public:
667 RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
668 RegisterContextDarwin_arm64 (thread, 0)
669 {
670 SetRegisterDataFrom_LC_THREAD (data);
671 }
672
673 virtual void
674 InvalidateAllRegisters ()
675 {
676 // Do nothing... registers are always valid...
677 }
678
679 void
680 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
681 {
682 lldb::offset_t offset = 0;
683 SetError (GPRRegSet, Read, -1);
684 SetError (FPURegSet, Read, -1);
685 SetError (EXCRegSet, Read, -1);
686 bool done = false;
687 while (!done)
688 {
689 int flavor = data.GetU32 (&offset);
690 uint32_t count = data.GetU32 (&offset);
691 lldb::offset_t next_thread_state = offset + (count * 4);
692 switch (flavor)
693 {
694 case GPRRegSet:
695 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
696 if (count >= (33 * 2) + 1)
697 {
698 for (uint32_t i=0; i<33; ++i)
699 gpr.x[i] = data.GetU64(&offset);
700 gpr.cpsr = data.GetU32(&offset);
701 SetError (GPRRegSet, Read, 0);
702 }
703 offset = next_thread_state;
704 break;
705 case FPURegSet:
706 {
707 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
708 const int fpu_reg_buf_size = sizeof (fpu);
709 if (fpu_reg_buf_size == count
710 && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
711 {
712 SetError (FPURegSet, Read, 0);
713 }
714 else
715 {
716 done = true;
717 }
718 }
719 offset = next_thread_state;
720 break;
721 case EXCRegSet:
722 if (count == 4)
723 {
724 exc.far = data.GetU64(&offset);
725 exc.esr = data.GetU32(&offset);
726 exc.exception = data.GetU32(&offset);
727 SetError (EXCRegSet, Read, 0);
728 }
729 offset = next_thread_state;
730 break;
731 default:
732 done = true;
733 break;
734 }
735 }
736 }
Jason Molenda22952582014-11-12 01:11:36 +0000737
738 static size_t
739 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
740 {
741 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
742 if (reg_info == NULL)
743 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
744 if (reg_info)
745 {
746 lldb_private::RegisterValue reg_value;
747 if (reg_ctx->ReadRegister(reg_info, reg_value))
748 {
749 if (reg_info->byte_size >= reg_byte_size)
750 data.Write(reg_value.GetBytes(), reg_byte_size);
751 else
752 {
753 data.Write(reg_value.GetBytes(), reg_info->byte_size);
754 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
755 data.PutChar(0);
756 }
757 return reg_byte_size;
758 }
759 }
760 // Just write zeros if all else fails
761 for (size_t i=0; i<reg_byte_size; ++ i)
762 data.PutChar(0);
763 return reg_byte_size;
764 }
765
766 static bool
767 Create_LC_THREAD (Thread *thread, Stream &data)
768 {
769 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
770 if (reg_ctx_sp)
771 {
772 RegisterContext *reg_ctx = reg_ctx_sp.get();
773
774 data.PutHex32 (GPRRegSet); // Flavor
775 data.PutHex32 (GPRWordCount);
776 WriteRegister (reg_ctx, "x0", NULL, 8, data);
777 WriteRegister (reg_ctx, "x1", NULL, 8, data);
778 WriteRegister (reg_ctx, "x2", NULL, 8, data);
779 WriteRegister (reg_ctx, "x3", NULL, 8, data);
780 WriteRegister (reg_ctx, "x4", NULL, 8, data);
781 WriteRegister (reg_ctx, "x5", NULL, 8, data);
782 WriteRegister (reg_ctx, "x6", NULL, 8, data);
783 WriteRegister (reg_ctx, "x7", NULL, 8, data);
784 WriteRegister (reg_ctx, "x8", NULL, 8, data);
785 WriteRegister (reg_ctx, "x9", NULL, 8, data);
786 WriteRegister (reg_ctx, "x10", NULL, 8, data);
787 WriteRegister (reg_ctx, "x11", NULL, 8, data);
788 WriteRegister (reg_ctx, "x12", NULL, 8, data);
789 WriteRegister (reg_ctx, "x13", NULL, 8, data);
790 WriteRegister (reg_ctx, "x14", NULL, 8, data);
791 WriteRegister (reg_ctx, "x15", NULL, 8, data);
792 WriteRegister (reg_ctx, "x16", NULL, 8, data);
793 WriteRegister (reg_ctx, "x17", NULL, 8, data);
794 WriteRegister (reg_ctx, "x18", NULL, 8, data);
795 WriteRegister (reg_ctx, "x19", NULL, 8, data);
796 WriteRegister (reg_ctx, "x20", NULL, 8, data);
797 WriteRegister (reg_ctx, "x21", NULL, 8, data);
798 WriteRegister (reg_ctx, "x22", NULL, 8, data);
799 WriteRegister (reg_ctx, "x23", NULL, 8, data);
800 WriteRegister (reg_ctx, "x24", NULL, 8, data);
801 WriteRegister (reg_ctx, "x25", NULL, 8, data);
802 WriteRegister (reg_ctx, "x26", NULL, 8, data);
803 WriteRegister (reg_ctx, "x27", NULL, 8, data);
804 WriteRegister (reg_ctx, "x28", NULL, 8, data);
805 WriteRegister (reg_ctx, "fp", NULL, 8, data);
806 WriteRegister (reg_ctx, "lr", NULL, 8, data);
807 WriteRegister (reg_ctx, "sp", NULL, 8, data);
808 WriteRegister (reg_ctx, "pc", NULL, 8, data);
809 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
810
811 // Write out the EXC registers
812// data.PutHex32 (EXCRegSet);
813// data.PutHex32 (EXCWordCount);
814// WriteRegister (reg_ctx, "far", NULL, 8, data);
815// WriteRegister (reg_ctx, "esr", NULL, 4, data);
816// WriteRegister (reg_ctx, "exception", NULL, 4, data);
817 return true;
818 }
819 return false;
820 }
821
Jason Molendaa3329782014-03-29 18:54:20 +0000822protected:
823 virtual int
824 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
825 {
826 return -1;
827 }
828
829 virtual int
830 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
831 {
832 return -1;
833 }
834
835 virtual int
836 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
837 {
838 return -1;
839 }
840
841 virtual int
842 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
843 {
844 return -1;
845 }
846
847 virtual int
848 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
849 {
850 return 0;
851 }
852
853 virtual int
854 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
855 {
856 return 0;
857 }
858
859 virtual int
860 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
861 {
862 return 0;
863 }
864
865 virtual int
866 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
867 {
868 return -1;
869 }
870};
871
Greg Clayton9aae0a12013-05-15 19:52:08 +0000872static uint32_t
873MachHeaderSizeFromMagic(uint32_t magic)
874{
875 switch (magic)
876 {
Charles Davis510938e2013-08-27 05:04:57 +0000877 case MH_MAGIC:
878 case MH_CIGAM:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000879 return sizeof(struct mach_header);
880
Charles Davis510938e2013-08-27 05:04:57 +0000881 case MH_MAGIC_64:
882 case MH_CIGAM_64:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000883 return sizeof(struct mach_header_64);
884 break;
885
886 default:
887 break;
888 }
889 return 0;
890}
891
Greg Claytonded470d2011-03-19 01:12:21 +0000892#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000893
894void
895ObjectFileMachO::Initialize()
896{
897 PluginManager::RegisterPlugin (GetPluginNameStatic(),
898 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000899 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000900 CreateMemoryInstance,
Greg Claytona2715cf2014-06-13 00:54:12 +0000901 GetModuleSpecifications,
902 SaveCore);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000903}
904
905void
906ObjectFileMachO::Terminate()
907{
908 PluginManager::UnregisterPlugin (CreateInstance);
909}
910
911
Greg Clayton57abc5d2013-05-10 21:47:16 +0000912lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913ObjectFileMachO::GetPluginNameStatic()
914{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000915 static ConstString g_name("mach-o");
916 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000917}
918
919const char *
920ObjectFileMachO::GetPluginDescriptionStatic()
921{
922 return "Mach-o object file reader (32 and 64 bit)";
923}
924
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925ObjectFile *
Greg Clayton5ce9c562013-02-06 17:22:03 +0000926ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
927 DataBufferSP& data_sp,
928 lldb::offset_t data_offset,
929 const FileSpec* file,
930 lldb::offset_t file_offset,
931 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000933 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934 {
Greg Clayton736888c2015-02-23 23:47:09 +0000935 data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
Greg Clayton5ce9c562013-02-06 17:22:03 +0000936 data_offset = 0;
937 }
938
939 if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
940 {
941 // Update the data to contain the entire file if it doesn't already
942 if (data_sp->GetByteSize() < length)
943 {
Greg Clayton736888c2015-02-23 23:47:09 +0000944 data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
Greg Clayton5ce9c562013-02-06 17:22:03 +0000945 data_offset = 0;
946 }
Greg Clayton7b0992d2013-04-18 22:45:39 +0000947 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 +0000948 if (objfile_ap.get() && objfile_ap->ParseHeader())
949 return objfile_ap.release();
950 }
951 return NULL;
952}
953
Greg Claytonc9660542012-02-05 02:38:54 +0000954ObjectFile *
Jason Molenda4e7511e2013-03-06 23:19:17 +0000955ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
956 DataBufferSP& data_sp,
957 const ProcessSP &process_sp,
Greg Claytonc9660542012-02-05 02:38:54 +0000958 lldb::addr_t header_addr)
959{
960 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
961 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000962 std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonc9660542012-02-05 02:38:54 +0000963 if (objfile_ap.get() && objfile_ap->ParseHeader())
964 return objfile_ap.release();
965 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000966 return NULL;
Greg Claytonc9660542012-02-05 02:38:54 +0000967}
968
Greg Claytonf4d6de62013-04-24 22:29:28 +0000969size_t
970ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
971 lldb::DataBufferSP& data_sp,
972 lldb::offset_t data_offset,
973 lldb::offset_t file_offset,
974 lldb::offset_t length,
975 lldb_private::ModuleSpecList &specs)
976{
977 const size_t initial_count = specs.GetSize();
978
979 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
980 {
981 DataExtractor data;
982 data.SetData(data_sp);
983 llvm::MachO::mach_header header;
984 if (ParseHeader (data, &data_offset, header))
985 {
Jason Molenda48cd3332014-04-22 04:52:30 +0000986 size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
987 if (header_and_load_cmds >= data_sp->GetByteSize())
Greg Claytonf4d6de62013-04-24 22:29:28 +0000988 {
Jason Molenda48cd3332014-04-22 04:52:30 +0000989 data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);
Greg Clayton2540a8a2013-07-12 22:07:46 +0000990 data.SetData(data_sp);
991 data_offset = MachHeaderSizeFromMagic(header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000992 }
993 if (data_sp)
994 {
995 ModuleSpec spec;
996 spec.GetFileSpec() = file;
Greg Clayton7ab7f892014-05-29 21:33:45 +0000997 spec.SetObjectOffset(file_offset);
Oleksiy Vyalov63acdfd2015-03-10 01:15:28 +0000998 spec.SetObjectSize(length);
999
Greg Clayton7ab7f892014-05-29 21:33:45 +00001000 if (GetArchitecture (header, data, data_offset, spec.GetArchitecture()))
Jason Molendab000e4d2013-08-27 02:22:06 +00001001 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001002 if (spec.GetArchitecture().IsValid())
1003 {
1004 GetUUID (header, data, data_offset, spec.GetUUID());
1005 specs.Append(spec);
1006 }
Greg Claytonf4d6de62013-04-24 22:29:28 +00001007 }
1008 }
1009 }
1010 }
1011 return specs.GetSize() - initial_count;
1012}
1013
1014
Greg Claytonc9660542012-02-05 02:38:54 +00001015
1016const ConstString &
1017ObjectFileMachO::GetSegmentNameTEXT()
1018{
1019 static ConstString g_segment_name_TEXT ("__TEXT");
1020 return g_segment_name_TEXT;
1021}
1022
1023const ConstString &
1024ObjectFileMachO::GetSegmentNameDATA()
1025{
1026 static ConstString g_segment_name_DATA ("__DATA");
1027 return g_segment_name_DATA;
1028}
1029
1030const ConstString &
Greg Claytona381e102015-07-27 23:21:05 +00001031ObjectFileMachO::GetSegmentNameDATA_DIRTY()
1032{
1033 static ConstString g_segment_name ("__DATA_DIRTY");
1034 return g_segment_name;
1035}
1036
1037const ConstString &
1038ObjectFileMachO::GetSegmentNameDATA_CONST()
1039{
1040 static ConstString g_segment_name ("__DATA_CONST");
1041 return g_segment_name;
1042}
1043
1044const ConstString &
Greg Claytonc9660542012-02-05 02:38:54 +00001045ObjectFileMachO::GetSegmentNameOBJC()
1046{
1047 static ConstString g_segment_name_OBJC ("__OBJC");
1048 return g_segment_name_OBJC;
1049}
1050
1051const ConstString &
1052ObjectFileMachO::GetSegmentNameLINKEDIT()
1053{
1054 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
1055 return g_section_name_LINKEDIT;
1056}
1057
1058const ConstString &
1059ObjectFileMachO::GetSectionNameEHFrame()
1060{
1061 static ConstString g_section_name_eh_frame ("__eh_frame");
1062 return g_section_name_eh_frame;
1063}
1064
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065bool
Jason Molenda4e7511e2013-03-06 23:19:17 +00001066ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
1067 lldb::addr_t data_offset,
Greg Clayton44435ed2012-01-12 05:25:17 +00001068 lldb::addr_t data_length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001069{
Greg Clayton44435ed2012-01-12 05:25:17 +00001070 DataExtractor data;
1071 data.SetData (data_sp, data_offset, data_length);
Greg Claytonc7bece562013-01-25 18:06:21 +00001072 lldb::offset_t offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001073 uint32_t magic = data.GetU32(&offset);
1074 return MachHeaderSizeFromMagic(magic) != 0;
1075}
1076
1077
Greg Clayton5ce9c562013-02-06 17:22:03 +00001078ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
1079 DataBufferSP& data_sp,
1080 lldb::offset_t data_offset,
1081 const FileSpec* file,
1082 lldb::offset_t file_offset,
1083 lldb::offset_t length) :
1084 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001085 m_mach_segments(),
1086 m_mach_sections(),
1087 m_entry_point_address(),
1088 m_thread_context_offsets(),
1089 m_thread_context_offsets_valid(false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090{
Greg Clayton72b77eb2011-02-04 21:13:05 +00001091 ::memset (&m_header, 0, sizeof(m_header));
1092 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093}
1094
Greg Claytone72dfb32012-02-24 01:59:29 +00001095ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonc9660542012-02-05 02:38:54 +00001096 lldb::DataBufferSP& header_data_sp,
1097 const lldb::ProcessSP &process_sp,
1098 lldb::addr_t header_addr) :
Greg Claytone72dfb32012-02-24 01:59:29 +00001099 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001100 m_mach_segments(),
1101 m_mach_sections(),
1102 m_entry_point_address(),
1103 m_thread_context_offsets(),
1104 m_thread_context_offsets_valid(false)
Greg Claytonc9660542012-02-05 02:38:54 +00001105{
1106 ::memset (&m_header, 0, sizeof(m_header));
1107 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1108}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001109
1110ObjectFileMachO::~ObjectFileMachO()
1111{
1112}
1113
Greg Claytonf4d6de62013-04-24 22:29:28 +00001114bool
1115ObjectFileMachO::ParseHeader (DataExtractor &data,
1116 lldb::offset_t *data_offset_ptr,
1117 llvm::MachO::mach_header &header)
1118{
1119 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1120 // Leave magic in the original byte order
1121 header.magic = data.GetU32(data_offset_ptr);
1122 bool can_parse = false;
1123 bool is_64_bit = false;
1124 switch (header.magic)
1125 {
Charles Davis510938e2013-08-27 05:04:57 +00001126 case MH_MAGIC:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001127 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1128 data.SetAddressByteSize(4);
1129 can_parse = true;
1130 break;
1131
Charles Davis510938e2013-08-27 05:04:57 +00001132 case MH_MAGIC_64:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001133 data.SetByteOrder (lldb::endian::InlHostByteOrder());
1134 data.SetAddressByteSize(8);
1135 can_parse = true;
1136 is_64_bit = true;
1137 break;
1138
Charles Davis510938e2013-08-27 05:04:57 +00001139 case MH_CIGAM:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001140 data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1141 data.SetAddressByteSize(4);
1142 can_parse = true;
1143 break;
1144
Charles Davis510938e2013-08-27 05:04:57 +00001145 case MH_CIGAM_64:
Greg Claytonf4d6de62013-04-24 22:29:28 +00001146 data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1147 data.SetAddressByteSize(8);
1148 is_64_bit = true;
1149 can_parse = true;
1150 break;
1151
1152 default:
1153 break;
1154 }
1155
1156 if (can_parse)
1157 {
1158 data.GetU32(data_offset_ptr, &header.cputype, 6);
1159 if (is_64_bit)
1160 *data_offset_ptr += 4;
1161 return true;
1162 }
1163 else
1164 {
1165 memset(&header, 0, sizeof(header));
1166 }
1167 return false;
1168}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001169
1170bool
1171ObjectFileMachO::ParseHeader ()
1172{
Greg Claytona1743492012-03-13 23:14:29 +00001173 ModuleSP module_sp(GetModule());
1174 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001175 {
Greg Claytona1743492012-03-13 23:14:29 +00001176 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1177 bool can_parse = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00001178 lldb::offset_t offset = 0;
Greg Clayton7fb56d02011-02-01 01:31:41 +00001179 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001180 // Leave magic in the original byte order
1181 m_header.magic = m_data.GetU32(&offset);
1182 switch (m_header.magic)
Greg Claytonc9660542012-02-05 02:38:54 +00001183 {
Charles Davis510938e2013-08-27 05:04:57 +00001184 case MH_MAGIC:
Greg Claytona1743492012-03-13 23:14:29 +00001185 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
1186 m_data.SetAddressByteSize(4);
1187 can_parse = true;
1188 break;
1189
Charles Davis510938e2013-08-27 05:04:57 +00001190 case MH_MAGIC_64:
Greg Claytona1743492012-03-13 23:14:29 +00001191 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
1192 m_data.SetAddressByteSize(8);
1193 can_parse = true;
1194 break;
1195
Charles Davis510938e2013-08-27 05:04:57 +00001196 case MH_CIGAM:
Greg Claytona1743492012-03-13 23:14:29 +00001197 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1198 m_data.SetAddressByteSize(4);
1199 can_parse = true;
1200 break;
1201
Charles Davis510938e2013-08-27 05:04:57 +00001202 case MH_CIGAM_64:
Greg Claytona1743492012-03-13 23:14:29 +00001203 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
1204 m_data.SetAddressByteSize(8);
1205 can_parse = true;
1206 break;
1207
1208 default:
1209 break;
Greg Claytonc9660542012-02-05 02:38:54 +00001210 }
Greg Claytona1743492012-03-13 23:14:29 +00001211
1212 if (can_parse)
1213 {
1214 m_data.GetU32(&offset, &m_header.cputype, 6);
1215
Greg Clayton7ab7f892014-05-29 21:33:45 +00001216
1217 ArchSpec mach_arch;
1218
1219 if (GetArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001220 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001221 // Check if the module has a required architecture
1222 const ArchSpec &module_arch = module_sp->GetArchitecture();
1223 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
1224 return false;
1225
1226 if (SetModulesArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001227 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001228 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
1229 if (m_data.GetByteSize() < header_and_lc_size)
Greg Claytona1743492012-03-13 23:14:29 +00001230 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001231 DataBufferSP data_sp;
1232 ProcessSP process_sp (m_process_wp.lock());
1233 if (process_sp)
1234 {
1235 data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
1236 }
1237 else
1238 {
1239 // Read in all only the load command data from the file on disk
1240 data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
1241 if (data_sp->GetByteSize() != header_and_lc_size)
1242 return false;
1243 }
1244 if (data_sp)
1245 m_data.SetData (data_sp);
Greg Claytona1743492012-03-13 23:14:29 +00001246 }
Greg Claytona1743492012-03-13 23:14:29 +00001247 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00001248 return true;
Greg Claytona1743492012-03-13 23:14:29 +00001249 }
Greg Claytona1743492012-03-13 23:14:29 +00001250 }
1251 else
1252 {
1253 memset(&m_header, 0, sizeof(struct mach_header));
1254 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255 }
1256 return false;
1257}
1258
1259
1260ByteOrder
1261ObjectFileMachO::GetByteOrder () const
1262{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001263 return m_data.GetByteOrder ();
1264}
1265
Jim Ingham5aee1622010-08-09 23:31:02 +00001266bool
1267ObjectFileMachO::IsExecutable() const
1268{
Charles Davis510938e2013-08-27 05:04:57 +00001269 return m_header.filetype == MH_EXECUTE;
Jim Ingham5aee1622010-08-09 23:31:02 +00001270}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271
Greg Claytonc7bece562013-01-25 18:06:21 +00001272uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001273ObjectFileMachO::GetAddressByteSize () const
1274{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275 return m_data.GetAddressByteSize ();
1276}
1277
Greg Claytone0d378b2011-03-24 21:19:54 +00001278AddressClass
Greg Claytonded470d2011-03-19 01:12:21 +00001279ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
1280{
1281 Symtab *symtab = GetSymtab();
1282 if (symtab)
1283 {
1284 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
1285 if (symbol)
1286 {
Greg Claytone7612132012-03-07 21:03:09 +00001287 if (symbol->ValueIsAddress())
Greg Claytonded470d2011-03-19 01:12:21 +00001288 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00001289 SectionSP section_sp (symbol->GetAddressRef().GetSection());
Greg Claytone72dfb32012-02-24 01:59:29 +00001290 if (section_sp)
Greg Claytonded470d2011-03-19 01:12:21 +00001291 {
Charles Davis510938e2013-08-27 05:04:57 +00001292 const lldb::SectionType section_type = section_sp->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001293 switch (section_type)
1294 {
Jason Molendae589e7e2014-12-08 03:09:00 +00001295 case eSectionTypeInvalid:
1296 return eAddressClassUnknown;
1297
Greg Claytonded470d2011-03-19 01:12:21 +00001298 case eSectionTypeCode:
Charles Davis510938e2013-08-27 05:04:57 +00001299 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001300 {
1301 // For ARM we have a bit in the n_desc field of the symbol
1302 // that tells us ARM/Thumb which is bit 0x0008.
1303 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1304 return eAddressClassCodeAlternateISA;
1305 }
1306 return eAddressClassCode;
1307
Jason Molendae589e7e2014-12-08 03:09:00 +00001308 case eSectionTypeContainer:
1309 return eAddressClassUnknown;
1310
Greg Clayton5009f9d2011-10-27 17:55:14 +00001311 case eSectionTypeData:
1312 case eSectionTypeDataCString:
1313 case eSectionTypeDataCStringPointers:
1314 case eSectionTypeDataSymbolAddress:
1315 case eSectionTypeData4:
1316 case eSectionTypeData8:
1317 case eSectionTypeData16:
1318 case eSectionTypeDataPointers:
1319 case eSectionTypeZeroFill:
1320 case eSectionTypeDataObjCMessageRefs:
1321 case eSectionTypeDataObjCCFStrings:
1322 return eAddressClassData;
Jason Molendae589e7e2014-12-08 03:09:00 +00001323
Greg Clayton5009f9d2011-10-27 17:55:14 +00001324 case eSectionTypeDebug:
1325 case eSectionTypeDWARFDebugAbbrev:
1326 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:
1336 case eSectionTypeDWARFAppleNames:
1337 case eSectionTypeDWARFAppleTypes:
1338 case eSectionTypeDWARFAppleNamespaces:
1339 case eSectionTypeDWARFAppleObjC:
1340 return eAddressClassDebug;
Jason Molendae589e7e2014-12-08 03:09:00 +00001341
1342 case eSectionTypeEHFrame:
1343 case eSectionTypeCompactUnwind:
1344 return eAddressClassRuntime;
1345
Michael Sartaina7499c92013-07-01 19:45:50 +00001346 case eSectionTypeELFSymbolTable:
1347 case eSectionTypeELFDynamicSymbols:
1348 case eSectionTypeELFRelocationEntries:
1349 case eSectionTypeELFDynamicLinkInfo:
Jason Molendae589e7e2014-12-08 03:09:00 +00001350 case eSectionTypeOther:
1351 return eAddressClassUnknown;
Greg Claytonded470d2011-03-19 01:12:21 +00001352 }
1353 }
1354 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001355
Greg Claytone0d378b2011-03-24 21:19:54 +00001356 const SymbolType symbol_type = symbol->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001357 switch (symbol_type)
1358 {
1359 case eSymbolTypeAny: return eAddressClassUnknown;
1360 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Jason Molenda4e7511e2013-03-06 23:19:17 +00001361
Greg Claytonded470d2011-03-19 01:12:21 +00001362 case eSymbolTypeCode:
1363 case eSymbolTypeTrampoline:
Greg Clayton059f7242013-02-27 21:16:04 +00001364 case eSymbolTypeResolver:
Charles Davis510938e2013-08-27 05:04:57 +00001365 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001366 {
1367 // For ARM we have a bit in the n_desc field of the symbol
1368 // that tells us ARM/Thumb which is bit 0x0008.
1369 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1370 return eAddressClassCodeAlternateISA;
1371 }
1372 return eAddressClassCode;
1373
1374 case eSymbolTypeData: return eAddressClassData;
1375 case eSymbolTypeRuntime: return eAddressClassRuntime;
1376 case eSymbolTypeException: return eAddressClassRuntime;
1377 case eSymbolTypeSourceFile: return eAddressClassDebug;
1378 case eSymbolTypeHeaderFile: return eAddressClassDebug;
1379 case eSymbolTypeObjectFile: return eAddressClassDebug;
1380 case eSymbolTypeCommonBlock: return eAddressClassDebug;
1381 case eSymbolTypeBlock: return eAddressClassDebug;
1382 case eSymbolTypeLocal: return eAddressClassData;
1383 case eSymbolTypeParam: return eAddressClassData;
1384 case eSymbolTypeVariable: return eAddressClassData;
1385 case eSymbolTypeVariableType: return eAddressClassDebug;
1386 case eSymbolTypeLineEntry: return eAddressClassDebug;
1387 case eSymbolTypeLineHeader: return eAddressClassDebug;
1388 case eSymbolTypeScopeBegin: return eAddressClassDebug;
1389 case eSymbolTypeScopeEnd: return eAddressClassDebug;
1390 case eSymbolTypeAdditional: return eAddressClassUnknown;
1391 case eSymbolTypeCompiler: return eAddressClassDebug;
1392 case eSymbolTypeInstrumentation:return eAddressClassDebug;
1393 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton456809c2011-12-03 02:30:59 +00001394 case eSymbolTypeObjCClass: return eAddressClassRuntime;
1395 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
1396 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Clayton9191db42013-10-21 18:40:51 +00001397 case eSymbolTypeReExported: return eAddressClassRuntime;
Greg Claytonded470d2011-03-19 01:12:21 +00001398 }
1399 }
1400 }
1401 return eAddressClassUnknown;
1402}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001403
1404Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001405ObjectFileMachO::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001406{
Greg Claytona1743492012-03-13 23:14:29 +00001407 ModuleSP module_sp(GetModule());
1408 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001409 {
Greg Claytona1743492012-03-13 23:14:29 +00001410 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1411 if (m_symtab_ap.get() == NULL)
1412 {
1413 m_symtab_ap.reset(new Symtab(this));
1414 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
Greg Clayton3046e662013-07-10 01:23:25 +00001415 ParseSymtab ();
Greg Claytona1743492012-03-13 23:14:29 +00001416 m_symtab_ap->Finalize ();
1417 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001418 }
1419 return m_symtab_ap.get();
1420}
1421
Greg Clayton3046e662013-07-10 01:23:25 +00001422bool
1423ObjectFileMachO::IsStripped ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001424{
Greg Clayton3046e662013-07-10 01:23:25 +00001425 if (m_dysymtab.cmd == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001426 {
Greg Clayton3046e662013-07-10 01:23:25 +00001427 ModuleSP module_sp(GetModule());
1428 if (module_sp)
Greg Claytona1743492012-03-13 23:14:29 +00001429 {
Greg Clayton3046e662013-07-10 01:23:25 +00001430 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1431 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton4d78c402012-05-25 18:09:55 +00001432 {
Greg Clayton3046e662013-07-10 01:23:25 +00001433 const lldb::offset_t load_cmd_offset = offset;
1434
1435 load_command lc;
1436 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
1437 break;
Charles Davis510938e2013-08-27 05:04:57 +00001438 if (lc.cmd == LC_DYSYMTAB)
Greg Clayton4d78c402012-05-25 18:09:55 +00001439 {
Greg Clayton3046e662013-07-10 01:23:25 +00001440 m_dysymtab.cmd = lc.cmd;
1441 m_dysymtab.cmdsize = lc.cmdsize;
1442 if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
1443 {
1444 // Clear m_dysymtab if we were unable to read all items from the load command
1445 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1446 }
Greg Clayton4d78c402012-05-25 18:09:55 +00001447 }
Greg Clayton3046e662013-07-10 01:23:25 +00001448 offset = load_cmd_offset + lc.cmdsize;
Greg Clayton4d78c402012-05-25 18:09:55 +00001449 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001450 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001451 }
Greg Clayton3046e662013-07-10 01:23:25 +00001452 if (m_dysymtab.cmd)
Greg Clayton93e28612013-10-11 22:03:48 +00001453 return m_dysymtab.nlocalsym <= 1;
Greg Clayton3046e662013-07-10 01:23:25 +00001454 return false;
1455}
Greg Clayton1eac0c72012-04-24 03:06:13 +00001456
Greg Clayton3046e662013-07-10 01:23:25 +00001457void
1458ObjectFileMachO::CreateSections (SectionList &unified_section_list)
1459{
1460 if (!m_sections_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001461 {
Greg Clayton3046e662013-07-10 01:23:25 +00001462 m_sections_ap.reset(new SectionList());
1463
Charles Davis510938e2013-08-27 05:04:57 +00001464 const bool is_dsym = (m_header.filetype == MH_DSYM);
Greg Clayton3046e662013-07-10 01:23:25 +00001465 lldb::user_id_t segID = 0;
1466 lldb::user_id_t sectID = 0;
1467 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1468 uint32_t i;
1469 const bool is_core = GetType() == eTypeCoreFile;
1470 //bool dump_sections = false;
1471 ModuleSP module_sp (GetModule());
1472 // First look up any LC_ENCRYPTION_INFO load commands
1473 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
1474 EncryptedFileRanges encrypted_file_ranges;
1475 encryption_info_command encryption_cmd;
1476 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001477 {
Greg Clayton3046e662013-07-10 01:23:25 +00001478 const lldb::offset_t load_cmd_offset = offset;
1479 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
1480 break;
1481
Jason Molendadfb02a92015-04-02 05:19:33 +00001482 // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
1483 // the 3 fields we care about, so treat them the same.
1484 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO || encryption_cmd.cmd == LC_ENCRYPTION_INFO_64)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001485 {
Greg Clayton3046e662013-07-10 01:23:25 +00001486 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001487 {
Greg Clayton3046e662013-07-10 01:23:25 +00001488 if (encryption_cmd.cryptid != 0)
Greg Claytond37d6922013-04-16 16:51:19 +00001489 {
Greg Clayton3046e662013-07-10 01:23:25 +00001490 EncryptedFileRanges::Entry entry;
1491 entry.SetRangeBase(encryption_cmd.cryptoff);
1492 entry.SetByteSize(encryption_cmd.cryptsize);
1493 encrypted_file_ranges.Append(entry);
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001494 }
1495 }
Greg Clayton3046e662013-07-10 01:23:25 +00001496 }
1497 offset = load_cmd_offset + encryption_cmd.cmdsize;
1498 }
1499
Jason Molenda05a09c62014-08-22 02:46:46 +00001500 bool section_file_addresses_changed = false;
1501
Greg Clayton3046e662013-07-10 01:23:25 +00001502 offset = MachHeaderSizeFromMagic(m_header.magic);
1503
1504 struct segment_command_64 load_cmd;
1505 for (i=0; i<m_header.ncmds; ++i)
1506 {
1507 const lldb::offset_t load_cmd_offset = offset;
1508 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1509 break;
1510
Charles Davis510938e2013-08-27 05:04:57 +00001511 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
Greg Clayton3046e662013-07-10 01:23:25 +00001512 {
1513 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001514 {
Greg Clayton3046e662013-07-10 01:23:25 +00001515 bool add_section = true;
1516 bool add_to_unified = true;
1517 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 +00001518
Greg Clayton3046e662013-07-10 01:23:25 +00001519 SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
1520 if (is_dsym && unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001521 {
Greg Clayton3046e662013-07-10 01:23:25 +00001522 if (const_segname == GetSegmentNameLINKEDIT())
1523 {
1524 // We need to keep the __LINKEDIT segment private to this object file only
1525 add_to_unified = false;
1526 }
1527 else
1528 {
1529 // This is the dSYM file and this section has already been created by
1530 // the object file, no need to create it.
1531 add_section = false;
1532 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001533 }
Greg Clayton3046e662013-07-10 01:23:25 +00001534 load_cmd.vmaddr = m_data.GetAddress(&offset);
1535 load_cmd.vmsize = m_data.GetAddress(&offset);
1536 load_cmd.fileoff = m_data.GetAddress(&offset);
1537 load_cmd.filesize = m_data.GetAddress(&offset);
1538 if (m_length != 0 && load_cmd.filesize != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001539 {
Greg Clayton3046e662013-07-10 01:23:25 +00001540 if (load_cmd.fileoff > m_length)
1541 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001542 // 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 +00001543 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001544 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001545 // is null out the SectionList vector and if a process has been set up, dump a message
1546 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001547 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001548 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 +00001549 i,
1550 lc_segment_name,
1551 load_cmd.fileoff,
1552 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001553
1554 load_cmd.fileoff = 0;
1555 load_cmd.filesize = 0;
1556 }
1557
1558 if (load_cmd.fileoff + load_cmd.filesize > m_length)
1559 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001560 // 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 +00001561 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001562 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001563 // is null out the SectionList vector and if a process has been set up, dump a message
1564 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001565 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001566 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 +00001567 i,
1568 lc_segment_name,
1569 load_cmd.fileoff + load_cmd.filesize,
1570 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001571
1572 // Tuncase the length
1573 load_cmd.filesize = m_length - load_cmd.fileoff;
1574 }
1575 }
1576 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
1577 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001578
Charles Davis510938e2013-08-27 05:04:57 +00001579 const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001580
Greg Clayton3046e662013-07-10 01:23:25 +00001581 // Keep a list of mach segments around in case we need to
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001582 // get at data that isn't stored in the abstracted Sections.
Greg Clayton3046e662013-07-10 01:23:25 +00001583 m_mach_segments.push_back (load_cmd);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001584
Greg Clayton3046e662013-07-10 01:23:25 +00001585 // Use a segment ID of the segment index shifted left by 8 so they
1586 // never conflict with any of the sections.
1587 SectionSP segment_sp;
1588 if (add_section && (const_segname || is_core))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001589 {
Greg Clayton3046e662013-07-10 01:23:25 +00001590 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
1591 this, // Object file to which this sections belongs
1592 ++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
1593 const_segname, // Name of this section
1594 eSectionTypeContainer, // This section is a container of other sections.
1595 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
1596 load_cmd.vmsize, // VM size in bytes of this section
1597 load_cmd.fileoff, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001598 load_cmd.filesize, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001599 0, // Segments have no alignment information
Greg Clayton3046e662013-07-10 01:23:25 +00001600 load_cmd.flags)); // Flags for this section
Greg Clayton8d38ac42010-06-28 23:51:11 +00001601
Greg Clayton3046e662013-07-10 01:23:25 +00001602 segment_sp->SetIsEncrypted (segment_is_encrypted);
1603 m_sections_ap->AddSection(segment_sp);
1604 if (add_to_unified)
1605 unified_section_list.AddSection(segment_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001606 }
Greg Clayton3046e662013-07-10 01:23:25 +00001607 else if (unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001608 {
Jason Molenda20eb31b2013-08-16 03:20:42 +00001609 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr)
1610 {
1611 // Check to see if the module was read from memory?
1612 if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid())
1613 {
1614 // We have a module that is in memory and needs to have its
1615 // file address adjusted. We need to do this because when we
1616 // load a file from memory, its addresses will be slid already,
1617 // yet the addresses in the new symbol file will still be unslid.
1618 // Since everything is stored as section offset, this shouldn't
1619 // cause any problems.
Jason Molenda5894a732013-08-17 03:39:52 +00001620
1621 // Make sure we've parsed the symbol table from the
1622 // ObjectFile before we go around changing its Sections.
1623 module_sp->GetObjectFile()->GetSymtab();
1624 // eh_frame would present the same problems but we parse that on
1625 // a per-function basis as-needed so it's more difficult to
1626 // remove its use of the Sections. Realistically, the environments
1627 // where this code path will be taken will not have eh_frame sections.
1628
Jason Molenda20eb31b2013-08-16 03:20:42 +00001629 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
Jason Molenda05a09c62014-08-22 02:46:46 +00001630
1631 // Notify the module that the section addresses have been changed once
1632 // we're done so any file-address caches can be updated.
1633 section_file_addresses_changed = true;
Jason Molenda20eb31b2013-08-16 03:20:42 +00001634 }
1635 }
Greg Clayton3046e662013-07-10 01:23:25 +00001636 m_sections_ap->AddSection(unified_section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001637 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001638
Greg Clayton3046e662013-07-10 01:23:25 +00001639 struct section_64 sect64;
1640 ::memset (&sect64, 0, sizeof(sect64));
1641 // Push a section into our mach sections for the section at
Charles Davis510938e2013-08-27 05:04:57 +00001642 // index zero (NO_SECT) if we don't have any mach sections yet...
Greg Clayton3046e662013-07-10 01:23:25 +00001643 if (m_mach_sections.empty())
1644 m_mach_sections.push_back(sect64);
1645 uint32_t segment_sect_idx;
1646 const lldb::user_id_t first_segment_sectID = sectID + 1;
1647
1648
Charles Davis510938e2013-08-27 05:04:57 +00001649 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
Greg Clayton3046e662013-07-10 01:23:25 +00001650 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651 {
Greg Clayton3046e662013-07-10 01:23:25 +00001652 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
Greg Clayton89411422010-10-08 00:21:05 +00001653 break;
Greg Clayton3046e662013-07-10 01:23:25 +00001654 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
1655 break;
1656 sect64.addr = m_data.GetAddress(&offset);
1657 sect64.size = m_data.GetAddress(&offset);
1658
1659 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
1660 break;
1661
1662 // Keep a list of mach sections around in case we need to
1663 // get at data that isn't stored in the abstracted Sections.
1664 m_mach_sections.push_back (sect64);
1665
1666 if (add_section)
1667 {
1668 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
1669 if (!const_segname)
1670 {
1671 // We have a segment with no name so we need to conjure up
1672 // segments that correspond to the section's segname if there
1673 // isn't already such a section. If there is such a section,
1674 // we resize the section so that it spans all sections.
1675 // We also mark these sections as fake so address matches don't
1676 // hit if they land in the gaps between the child sections.
1677 const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
1678 segment_sp = unified_section_list.FindSectionByName (const_segname);
1679 if (segment_sp.get())
1680 {
1681 Section *segment = segment_sp.get();
1682 // Grow the section size as needed.
1683 const lldb::addr_t sect64_min_addr = sect64.addr;
1684 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1685 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
1686 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
1687 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
1688 if (sect64_min_addr >= curr_seg_min_addr)
1689 {
1690 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
1691 // Only grow the section size if needed
1692 if (new_seg_byte_size > curr_seg_byte_size)
1693 segment->SetByteSize (new_seg_byte_size);
1694 }
1695 else
1696 {
1697 // We need to change the base address of the segment and
1698 // adjust the child section offsets for all existing children.
1699 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
1700 segment->Slide(slide_amount, false);
1701 segment->GetChildren().Slide(-slide_amount, false);
1702 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
1703 }
1704
1705 // Grow the section size as needed.
1706 if (sect64.offset)
1707 {
1708 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
1709 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
1710
1711 const lldb::addr_t section_min_file_offset = sect64.offset;
1712 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
1713 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
1714 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
1715 segment->SetFileOffset (new_file_offset);
1716 segment->SetFileSize (new_file_size);
1717 }
1718 }
1719 else
1720 {
1721 // Create a fake section for the section's named segment
1722 segment_sp.reset(new Section (segment_sp, // Parent section
1723 module_sp, // Module to which this section belongs
1724 this, // Object file to which this section belongs
1725 ++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
1726 const_segname, // Name of this section
1727 eSectionTypeContainer, // This section is a container of other sections.
1728 sect64.addr, // File VM address == addresses as they are found in the object file
1729 sect64.size, // VM size in bytes of this section
1730 sect64.offset, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001731 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001732 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001733 load_cmd.flags)); // Flags for this section
1734 segment_sp->SetIsFake(true);
1735
1736 m_sections_ap->AddSection(segment_sp);
1737 if (add_to_unified)
1738 unified_section_list.AddSection(segment_sp);
1739 segment_sp->SetIsEncrypted (segment_is_encrypted);
1740 }
1741 }
1742 assert (segment_sp.get());
1743
Charles Davis510938e2013-08-27 05:04:57 +00001744 lldb::SectionType sect_type = eSectionTypeOther;
Greg Clayton3046e662013-07-10 01:23:25 +00001745
Greg Clayton38f9cc42014-06-16 22:53:16 +00001746 if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1747 sect_type = eSectionTypeCode;
1748 else
Greg Clayton3046e662013-07-10 01:23:25 +00001749 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001750 uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
1751 static ConstString g_sect_name_objc_data ("__objc_data");
1752 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
1753 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
1754 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
1755 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
1756 static ConstString g_sect_name_objc_const ("__objc_const");
1757 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
1758 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton3046e662013-07-10 01:23:25 +00001759
Greg Clayton38f9cc42014-06-16 22:53:16 +00001760 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
1761 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
1762 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
1763 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
1764 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
1765 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
1766 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
1767 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
1768 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
1769 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
1770 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
1771 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
1772 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
1773 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
1774 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
1775 static ConstString g_sect_name_eh_frame ("__eh_frame");
Jason Molendae589e7e2014-12-08 03:09:00 +00001776 static ConstString g_sect_name_compact_unwind ("__unwind_info");
Greg Clayton38f9cc42014-06-16 22:53:16 +00001777 static ConstString g_sect_name_text ("__text");
1778 static ConstString g_sect_name_data ("__data");
1779
1780
1781 if (section_name == g_sect_name_dwarf_debug_abbrev)
1782 sect_type = eSectionTypeDWARFDebugAbbrev;
1783 else if (section_name == g_sect_name_dwarf_debug_aranges)
1784 sect_type = eSectionTypeDWARFDebugAranges;
1785 else if (section_name == g_sect_name_dwarf_debug_frame)
1786 sect_type = eSectionTypeDWARFDebugFrame;
1787 else if (section_name == g_sect_name_dwarf_debug_info)
1788 sect_type = eSectionTypeDWARFDebugInfo;
1789 else if (section_name == g_sect_name_dwarf_debug_line)
1790 sect_type = eSectionTypeDWARFDebugLine;
1791 else if (section_name == g_sect_name_dwarf_debug_loc)
1792 sect_type = eSectionTypeDWARFDebugLoc;
1793 else if (section_name == g_sect_name_dwarf_debug_macinfo)
1794 sect_type = eSectionTypeDWARFDebugMacInfo;
1795 else if (section_name == g_sect_name_dwarf_debug_pubnames)
1796 sect_type = eSectionTypeDWARFDebugPubNames;
1797 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
1798 sect_type = eSectionTypeDWARFDebugPubTypes;
1799 else if (section_name == g_sect_name_dwarf_debug_ranges)
1800 sect_type = eSectionTypeDWARFDebugRanges;
1801 else if (section_name == g_sect_name_dwarf_debug_str)
1802 sect_type = eSectionTypeDWARFDebugStr;
1803 else if (section_name == g_sect_name_dwarf_apple_names)
1804 sect_type = eSectionTypeDWARFAppleNames;
1805 else if (section_name == g_sect_name_dwarf_apple_types)
1806 sect_type = eSectionTypeDWARFAppleTypes;
1807 else if (section_name == g_sect_name_dwarf_apple_namespaces)
1808 sect_type = eSectionTypeDWARFAppleNamespaces;
1809 else if (section_name == g_sect_name_dwarf_apple_objc)
1810 sect_type = eSectionTypeDWARFAppleObjC;
1811 else if (section_name == g_sect_name_objc_selrefs)
1812 sect_type = eSectionTypeDataCStringPointers;
1813 else if (section_name == g_sect_name_objc_msgrefs)
1814 sect_type = eSectionTypeDataObjCMessageRefs;
1815 else if (section_name == g_sect_name_eh_frame)
1816 sect_type = eSectionTypeEHFrame;
Jason Molendae589e7e2014-12-08 03:09:00 +00001817 else if (section_name == g_sect_name_compact_unwind)
1818 sect_type = eSectionTypeCompactUnwind;
Greg Clayton38f9cc42014-06-16 22:53:16 +00001819 else if (section_name == g_sect_name_cfstring)
1820 sect_type = eSectionTypeDataObjCCFStrings;
1821 else if (section_name == g_sect_name_objc_data ||
1822 section_name == g_sect_name_objc_classrefs ||
1823 section_name == g_sect_name_objc_superrefs ||
1824 section_name == g_sect_name_objc_const ||
1825 section_name == g_sect_name_objc_classlist)
Greg Clayton3046e662013-07-10 01:23:25 +00001826 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001827 sect_type = eSectionTypeDataPointers;
1828 }
1829
1830 if (sect_type == eSectionTypeOther)
1831 {
1832 switch (mach_sect_type)
1833 {
1834 // TODO: categorize sections by other flags for regular sections
1835 case S_REGULAR:
1836 if (section_name == g_sect_name_text)
1837 sect_type = eSectionTypeCode;
1838 else if (section_name == g_sect_name_data)
1839 sect_type = eSectionTypeData;
1840 else
1841 sect_type = eSectionTypeOther;
1842 break;
1843 case S_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1844 case S_CSTRING_LITERALS: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1845 case S_4BYTE_LITERALS: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1846 case S_8BYTE_LITERALS: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1847 case S_LITERAL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1848 case S_NON_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1849 case S_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1850 case S_SYMBOL_STUBS: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1851 case S_MOD_INIT_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1852 case S_MOD_TERM_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1853 case S_COALESCED: sect_type = eSectionTypeOther; break;
1854 case S_GB_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1855 case S_INTERPOSING: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1856 case S_16BYTE_LITERALS: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1857 case S_DTRACE_DOF: sect_type = eSectionTypeDebug; break;
1858 case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break;
1859 default: break;
1860 }
Greg Clayton3046e662013-07-10 01:23:25 +00001861 }
1862 }
1863
1864 SectionSP section_sp(new Section (segment_sp,
1865 module_sp,
1866 this,
1867 ++sectID,
1868 section_name,
1869 sect_type,
1870 sect64.addr - segment_sp->GetFileAddress(),
1871 sect64.size,
1872 sect64.offset,
1873 sect64.offset == 0 ? 0 : sect64.size,
Greg Clayton48672af2014-06-24 22:22:43 +00001874 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001875 sect64.flags));
1876 // Set the section to be encrypted to match the segment
1877
1878 bool section_is_encrypted = false;
1879 if (!segment_is_encrypted && load_cmd.filesize != 0)
1880 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
1881
1882 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
1883 segment_sp->GetChildren().AddSection(section_sp);
1884
1885 if (segment_sp->IsFake())
1886 {
1887 segment_sp.reset();
1888 const_segname.Clear();
1889 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001890 }
1891 }
Greg Clayton3046e662013-07-10 01:23:25 +00001892 if (segment_sp && is_dsym)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001893 {
Greg Clayton3046e662013-07-10 01:23:25 +00001894 if (first_segment_sectID <= sectID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001895 {
Greg Clayton3046e662013-07-10 01:23:25 +00001896 lldb::user_id_t sect_uid;
1897 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001898 {
Greg Clayton3046e662013-07-10 01:23:25 +00001899 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1900 SectionSP next_section_sp;
1901 if (sect_uid + 1 <= sectID)
1902 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1903
1904 if (curr_section_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001905 {
Greg Clayton3046e662013-07-10 01:23:25 +00001906 if (curr_section_sp->GetByteSize() == 0)
1907 {
1908 if (next_section_sp.get() != NULL)
1909 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1910 else
1911 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1912 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001913 }
1914 }
1915 }
1916 }
1917 }
1918 }
1919 }
Charles Davis510938e2013-08-27 05:04:57 +00001920 else if (load_cmd.cmd == LC_DYSYMTAB)
Greg Clayton3046e662013-07-10 01:23:25 +00001921 {
1922 m_dysymtab.cmd = load_cmd.cmd;
1923 m_dysymtab.cmdsize = load_cmd.cmdsize;
1924 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1925 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001926
Greg Clayton3046e662013-07-10 01:23:25 +00001927 offset = load_cmd_offset + load_cmd.cmdsize;
1928 }
Jason Molenda05a09c62014-08-22 02:46:46 +00001929
1930
1931 if (section_file_addresses_changed && module_sp.get())
1932 {
1933 module_sp->SectionFileAddressesChanged();
1934 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001935 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001936}
1937
1938class MachSymtabSectionInfo
1939{
1940public:
1941
1942 MachSymtabSectionInfo (SectionList *section_list) :
1943 m_section_list (section_list),
1944 m_section_infos()
1945 {
1946 // Get the number of sections down to a depth of 1 to include
1947 // all segments and their sections, but no other sections that
1948 // may be added for debug map or
1949 m_section_infos.resize(section_list->GetNumSections(1));
1950 }
1951
1952
Greg Claytone72dfb32012-02-24 01:59:29 +00001953 SectionSP
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001954 GetSection (uint8_t n_sect, addr_t file_addr)
1955 {
1956 if (n_sect == 0)
Greg Claytone72dfb32012-02-24 01:59:29 +00001957 return SectionSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001958 if (n_sect < m_section_infos.size())
1959 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001960 if (!m_section_infos[n_sect].section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001961 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001962 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1963 m_section_infos[n_sect].section_sp = section_sp;
Sean Callanan9a028512012-08-09 00:50:26 +00001964 if (section_sp)
Greg Claytondda0d122011-07-10 17:32:33 +00001965 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001966 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1967 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Claytondda0d122011-07-10 17:32:33 +00001968 }
1969 else
1970 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00001971 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Claytondda0d122011-07-10 17:32:33 +00001972 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001973 }
1974 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton8f258512011-08-26 20:01:35 +00001975 {
1976 // Symbol is in section.
Greg Claytone72dfb32012-02-24 01:59:29 +00001977 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001978 }
1979 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1980 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1981 {
1982 // Symbol is in section with zero size, but has the same start
1983 // address as the section. This can happen with linker symbols
1984 // (symbols that start with the letter 'l' or 'L'.
Greg Claytone72dfb32012-02-24 01:59:29 +00001985 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001986 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001987 }
Greg Claytone72dfb32012-02-24 01:59:29 +00001988 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001989 }
1990
1991protected:
1992 struct SectionInfo
1993 {
1994 SectionInfo () :
1995 vm_range(),
Greg Claytone72dfb32012-02-24 01:59:29 +00001996 section_sp ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001997 {
1998 }
1999
2000 VMRange vm_range;
Greg Claytone72dfb32012-02-24 01:59:29 +00002001 SectionSP section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002002 };
2003 SectionList *m_section_list;
2004 std::vector<SectionInfo> m_section_infos;
2005};
2006
Greg Clayton9191db42013-10-21 18:40:51 +00002007struct TrieEntry
2008{
2009 TrieEntry () :
2010 name(),
2011 address(LLDB_INVALID_ADDRESS),
2012 flags (0),
2013 other(0),
2014 import_name()
2015 {
2016 }
2017
2018 void
2019 Clear ()
2020 {
2021 name.Clear();
2022 address = LLDB_INVALID_ADDRESS;
2023 flags = 0;
2024 other = 0;
2025 import_name.Clear();
2026 }
2027
2028 void
2029 Dump () const
2030 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002031 printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2032 static_cast<unsigned long long>(address),
2033 static_cast<unsigned long long>(flags),
2034 static_cast<unsigned long long>(other), name.GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +00002035 if (import_name)
2036 printf (" -> \"%s\"\n", import_name.GetCString());
2037 else
2038 printf ("\n");
2039 }
2040 ConstString name;
2041 uint64_t address;
2042 uint64_t flags;
2043 uint64_t other;
2044 ConstString import_name;
2045};
2046
2047struct TrieEntryWithOffset
2048{
2049 lldb::offset_t nodeOffset;
2050 TrieEntry entry;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002051
Greg Clayton9191db42013-10-21 18:40:51 +00002052 TrieEntryWithOffset (lldb::offset_t offset) :
2053 nodeOffset (offset),
2054 entry()
2055 {
2056 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002057
Greg Clayton9191db42013-10-21 18:40:51 +00002058 void
2059 Dump (uint32_t idx) const
2060 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002061 printf ("[%3u] 0x%16.16llx: ", idx,
2062 static_cast<unsigned long long>(nodeOffset));
Greg Clayton9191db42013-10-21 18:40:51 +00002063 entry.Dump();
2064 }
2065
2066 bool
2067 operator<(const TrieEntryWithOffset& other) const
2068 {
2069 return ( nodeOffset < other.nodeOffset );
2070 }
2071};
2072
2073static void
2074ParseTrieEntries (DataExtractor &data,
2075 lldb::offset_t offset,
Greg Claytonb887da12015-07-16 19:50:57 +00002076 const bool is_arm,
Greg Clayton9191db42013-10-21 18:40:51 +00002077 std::vector<llvm::StringRef> &nameSlices,
2078 std::set<lldb::addr_t> &resolver_addresses,
2079 std::vector<TrieEntryWithOffset>& output)
2080{
2081 if (!data.ValidOffset(offset))
2082 return;
2083
2084 const uint64_t terminalSize = data.GetULEB128(&offset);
2085 lldb::offset_t children_offset = offset + terminalSize;
2086 if ( terminalSize != 0 ) {
2087 TrieEntryWithOffset e (offset);
2088 e.entry.flags = data.GetULEB128(&offset);
2089 const char *import_name = NULL;
2090 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
2091 e.entry.address = 0;
2092 e.entry.other = data.GetULEB128(&offset); // dylib ordinal
2093 import_name = data.GetCStr(&offset);
2094 }
2095 else {
2096 e.entry.address = data.GetULEB128(&offset);
2097 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
2098 {
Greg Clayton9191db42013-10-21 18:40:51 +00002099 e.entry.other = data.GetULEB128(&offset);
Greg Claytonb887da12015-07-16 19:50:57 +00002100 uint64_t resolver_addr = e.entry.other;
2101 if (is_arm)
2102 resolver_addr &= THUMB_ADDRESS_BIT_MASK;
2103 resolver_addresses.insert(resolver_addr);
Greg Clayton9191db42013-10-21 18:40:51 +00002104 }
2105 else
2106 e.entry.other = 0;
2107 }
2108 // Only add symbols that are reexport symbols with a valid import name
2109 if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
2110 {
2111 std::string name;
2112 if (!nameSlices.empty())
2113 {
2114 for (auto name_slice: nameSlices)
2115 name.append(name_slice.data(), name_slice.size());
2116 }
2117 if (name.size() > 1)
2118 {
2119 // Skip the leading '_'
2120 e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
2121 }
2122 if (import_name)
2123 {
2124 // Skip the leading '_'
2125 e.entry.import_name.SetCString(import_name+1);
2126 }
2127 output.push_back(e);
2128 }
2129 }
2130
2131 const uint8_t childrenCount = data.GetU8(&children_offset);
2132 for (uint8_t i=0; i < childrenCount; ++i) {
2133 nameSlices.push_back(data.GetCStr(&children_offset));
2134 lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
2135 if (childNodeOffset)
2136 {
2137 ParseTrieEntries(data,
2138 childNodeOffset,
Greg Claytonb887da12015-07-16 19:50:57 +00002139 is_arm,
Greg Clayton9191db42013-10-21 18:40:51 +00002140 nameSlices,
2141 resolver_addresses,
2142 output);
2143 }
2144 nameSlices.pop_back();
2145 }
2146}
2147
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002148size_t
Greg Clayton3046e662013-07-10 01:23:25 +00002149ObjectFileMachO::ParseSymtab ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002150{
2151 Timer scoped_timer(__PRETTY_FUNCTION__,
2152 "ObjectFileMachO::ParseSymtab () module = %s",
2153 m_file.GetFilename().AsCString(""));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002154 ModuleSP module_sp (GetModule());
2155 if (!module_sp)
2156 return 0;
2157
2158 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
2159 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
Greg Clayton9191db42013-10-21 18:40:51 +00002160 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 +00002161 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
2162 FunctionStarts function_starts;
Greg Claytonc7bece562013-01-25 18:06:21 +00002163 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002164 uint32_t i;
Greg Clayton9191db42013-10-21 18:40:51 +00002165 FileSpecList dylib_files;
Greg Clayton5160ce52013-03-27 23:08:40 +00002166 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
Greg Clayton1e28adf2015-02-25 17:25:02 +00002167 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2168 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2169 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
Greg Clayton77ccca72011-12-30 00:32:24 +00002170
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002171 for (i=0; i<m_header.ncmds; ++i)
2172 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002173 const lldb::offset_t cmd_offset = offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002174 // Read in the load command and load command size
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002175 struct load_command lc;
2176 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002177 break;
2178 // Watch for the symbol table load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002179 switch (lc.cmd)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002180 {
Charles Davis510938e2013-08-27 05:04:57 +00002181 case LC_SYMTAB:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002182 symtab_load_command.cmd = lc.cmd;
2183 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002184 // Read in the rest of the symtab load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002185 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
2186 return 0;
2187 if (symtab_load_command.symoff == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002188 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002189 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002190 module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002191 return 0;
2192 }
2193
2194 if (symtab_load_command.stroff == 0)
2195 {
2196 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002197 module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002198 return 0;
2199 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002200
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002201 if (symtab_load_command.nsyms == 0)
2202 {
2203 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002204 module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002205 return 0;
2206 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002207
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002208 if (symtab_load_command.strsize == 0)
2209 {
2210 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002211 module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002212 return 0;
2213 }
2214 break;
2215
Greg Clayton9191db42013-10-21 18:40:51 +00002216 case LC_DYLD_INFO:
2217 case LC_DYLD_INFO_ONLY:
2218 if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
2219 {
2220 dyld_info.cmd = lc.cmd;
2221 dyld_info.cmdsize = lc.cmdsize;
2222 }
2223 else
2224 {
2225 memset (&dyld_info, 0, sizeof(dyld_info));
2226 }
2227 break;
2228
2229 case LC_LOAD_DYLIB:
2230 case LC_LOAD_WEAK_DYLIB:
2231 case LC_REEXPORT_DYLIB:
2232 case LC_LOADFVMLIB:
2233 case LC_LOAD_UPWARD_DYLIB:
2234 {
2235 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2236 const char *path = m_data.PeekCStr(name_offset);
2237 if (path)
2238 {
2239 FileSpec file_spec(path, false);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002240 // Strip the path if there is @rpath, @executable, etc so we just use the basename
Greg Clayton9191db42013-10-21 18:40:51 +00002241 if (path[0] == '@')
2242 file_spec.GetDirectory().Clear();
Jim Inghamfbe0b9a2014-05-21 03:58:03 +00002243
2244 if (lc.cmd == LC_REEXPORT_DYLIB)
2245 {
2246 m_reexported_dylibs.AppendIfUnique(file_spec);
2247 }
Greg Clayton9191db42013-10-21 18:40:51 +00002248
2249 dylib_files.Append(file_spec);
2250 }
2251 }
2252 break;
2253
Charles Davis510938e2013-08-27 05:04:57 +00002254 case LC_FUNCTION_STARTS:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002255 function_starts_load_command.cmd = lc.cmd;
2256 function_starts_load_command.cmdsize = lc.cmdsize;
2257 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 +00002258 memset (&function_starts_load_command, 0, sizeof(function_starts_load_command));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002259 break;
2260
2261 default:
2262 break;
2263 }
2264 offset = cmd_offset + lc.cmdsize;
2265 }
2266
2267 if (symtab_load_command.cmd)
2268 {
2269 Symtab *symtab = m_symtab_ap.get();
2270 SectionList *section_list = GetSectionList();
2271 if (section_list == NULL)
2272 return 0;
2273
Greg Claytonc7bece562013-01-25 18:06:21 +00002274 const uint32_t addr_byte_size = m_data.GetAddressByteSize();
2275 const ByteOrder byte_order = m_data.GetByteOrder();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002276 bool bit_width_32 = addr_byte_size == 4;
2277 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
2278
Greg Claytonc7bece562013-01-25 18:06:21 +00002279 DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
2280 DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
2281 DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
Jason Molendad34e6522013-02-05 22:31:24 +00002282 DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002283 DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);
Jason Molenda4e7511e2013-03-06 23:19:17 +00002284
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002285 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
2286 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Clayton4c82d422012-05-18 23:20:01 +00002287 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
Greg Claytonfd814c52013-08-13 01:42:25 +00002288
2289 ProcessSP process_sp (m_process_wp.lock());
2290 Process *process = process_sp.get();
2291
Greg Clayton86eac942013-08-13 21:32:34 +00002292 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
2293
Greg Clayton48672af2014-06-24 22:22:43 +00002294 if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002295 {
Greg Clayton4c82d422012-05-18 23:20:01 +00002296 Target &target = process->GetTarget();
Greg Claytonfd814c52013-08-13 01:42:25 +00002297
Greg Clayton86eac942013-08-13 21:32:34 +00002298 memory_module_load_level = target.GetMemoryModuleLoadLevel();
Greg Claytonfd814c52013-08-13 01:42:25 +00002299
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002300 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2301 // Reading mach file from memory in a process or core file...
2302
2303 if (linkedit_section_sp)
2304 {
Greg Clayton07347372015-06-08 21:53:11 +00002305 addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
2306 if (linkedit_load_addr == LLDB_INVALID_ADDRESS)
2307 {
2308 // We might be trying to access the symbol table before the __LINKEDIT's load
2309 // address has been set in the target. We can't fail to read the symbol table,
2310 // so calculate the right address manually
2311 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2312 }
2313
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002314 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2315 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Clayton4c82d422012-05-18 23:20:01 +00002316 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton26b47e22012-04-18 05:19:20 +00002317
2318 bool data_was_read = false;
2319
Todd Fiala013434e2014-07-09 01:29:05 +00002320#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa3329782014-03-29 18:54:20 +00002321 if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
Greg Clayton77ccca72011-12-30 00:32:24 +00002322 {
Greg Clayton26b47e22012-04-18 05:19:20 +00002323 // This mach-o memory file is in the dyld shared cache. If this
2324 // program is not remote and this is iOS, then this process will
2325 // share the same shared cache as the process we are debugging and
2326 // we can read the entire __LINKEDIT from the address space in this
2327 // process. This is a needed optimization that is used for local iOS
2328 // debugging only since all shared libraries in the shared cache do
2329 // not have corresponding files that exist in the file system of the
2330 // device. They have been combined into a single file. This means we
2331 // always have to load these files from memory. All of the symbol and
2332 // string tables from all of the __LINKEDIT sections from the shared
2333 // libraries in the shared cache have been merged into a single large
2334 // symbol and string table. Reading all of this symbol and string table
2335 // data across can slow down debug launch times, so we optimize this by
2336 // reading the memory for the __LINKEDIT section from this process.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002337
2338 UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
2339 UUID process_shared_cache(GetProcessSharedCacheUUID(process));
2340 bool use_lldb_cache = true;
2341 if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache)
2342 {
2343 use_lldb_cache = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002344 ModuleSP module_sp (GetModule());
2345 if (module_sp)
2346 module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow.");
2347
Jason Molenda0e0954c2013-04-16 06:24:42 +00002348 }
2349
Greg Clayton26b47e22012-04-18 05:19:20 +00002350 PlatformSP platform_sp (target.GetPlatform());
Jason Molenda0e0954c2013-04-16 06:24:42 +00002351 if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
Greg Clayton26b47e22012-04-18 05:19:20 +00002352 {
2353 data_was_read = true;
2354 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Clayton4c82d422012-05-18 23:20:01 +00002355 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton26b47e22012-04-18 05:19:20 +00002356 if (function_starts_load_command.cmd)
2357 {
2358 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2359 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
2360 }
2361 }
2362 }
2363#endif
2364
2365 if (!data_was_read)
2366 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002367 if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
Jason Molendad34e6522013-02-05 22:31:24 +00002368 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002369 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
2370 if (nlist_data_sp)
2371 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2372 // Load strings individually from memory when loading from memory since shared cache
2373 // string tables contain strings for all symbols from all shared cached libraries
2374 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
2375 //if (strtab_data_sp)
2376 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
2377 if (m_dysymtab.nindirectsyms != 0)
2378 {
2379 const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
2380 DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
2381 if (indirect_syms_data_sp)
2382 indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2383 }
Jason Molendad34e6522013-02-05 22:31:24 +00002384 }
Greg Claytonfd814c52013-08-13 01:42:25 +00002385
2386 if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
Greg Clayton26b47e22012-04-18 05:19:20 +00002387 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002388 if (function_starts_load_command.cmd)
2389 {
2390 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2391 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
2392 if (func_start_data_sp)
2393 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
2394 }
Greg Clayton26b47e22012-04-18 05:19:20 +00002395 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002396 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002397 }
2398 }
2399 else
2400 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002401 nlist_data.SetData (m_data,
2402 symtab_load_command.symoff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002403 nlist_data_byte_size);
2404 strtab_data.SetData (m_data,
Jason Molenda4e7511e2013-03-06 23:19:17 +00002405 symtab_load_command.stroff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002406 strtab_data_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002407
2408 if (dyld_info.export_size > 0)
2409 {
2410 dyld_trie_data.SetData (m_data,
2411 dyld_info.export_off,
2412 dyld_info.export_size);
2413 }
2414
Jason Molendad34e6522013-02-05 22:31:24 +00002415 if (m_dysymtab.nindirectsyms != 0)
2416 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002417 indirect_symbol_index_data.SetData (m_data,
2418 m_dysymtab.indirectsymoff,
Jason Molendad34e6522013-02-05 22:31:24 +00002419 m_dysymtab.nindirectsyms * 4);
2420 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002421 if (function_starts_load_command.cmd)
2422 {
2423 function_starts_data.SetData (m_data,
2424 function_starts_load_command.dataoff,
2425 function_starts_load_command.datasize);
2426 }
2427 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002428
Greg Clayton86eac942013-08-13 21:32:34 +00002429 if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete)
2430 {
2431 if (log)
2432 module_sp->LogMessage(log, "failed to read nlist data");
2433 return 0;
2434 }
2435
2436
Greg Claytondebb8812012-05-25 17:04:00 +00002437 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2438 if (!have_strtab_data)
Greg Clayton4c82d422012-05-18 23:20:01 +00002439 {
Greg Claytondebb8812012-05-25 17:04:00 +00002440 if (process)
2441 {
2442 if (strtab_addr == LLDB_INVALID_ADDRESS)
2443 {
2444 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002445 module_sp->LogMessage(log, "failed to locate the strtab in memory");
Greg Claytondebb8812012-05-25 17:04:00 +00002446 return 0;
2447 }
2448 }
2449 else
Greg Clayton4c82d422012-05-18 23:20:01 +00002450 {
2451 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002452 module_sp->LogMessage(log, "failed to read strtab data");
Greg Clayton4c82d422012-05-18 23:20:01 +00002453 return 0;
2454 }
2455 }
Greg Clayton4c82d422012-05-18 23:20:01 +00002456
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002457 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
2458 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
Greg Claytona381e102015-07-27 23:21:05 +00002459 const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
2460 const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002461 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
2462 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
2463 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
2464 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
Greg Claytona381e102015-07-27 23:21:05 +00002465 SectionSP data_dirty_section_sp(section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2466 SectionSP data_const_section_sp(section_list->FindSectionByName(g_segment_name_DATA_CONST));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002467 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
2468 SectionSP eh_frame_section_sp;
2469 if (text_section_sp.get())
2470 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
2471 else
2472 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
2473
Charles Davis510938e2013-08-27 05:04:57 +00002474 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
Jason Molenda5635f772013-03-21 03:36:01 +00002475
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002476 // lldb works best if it knows the start address of all functions in a module.
Jason Molenda5635f772013-03-21 03:36:01 +00002477 // Linker symbols or debug info are normally the best source of information for start addr / size but
2478 // they may be stripped in a released binary.
Jason Molendad63d3c72013-04-16 00:18:44 +00002479 // Two additional sources of information exist in Mach-O binaries:
Jason Molenda5635f772013-03-21 03:36:01 +00002480 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
2481 // binary, relative to the text section.
2482 // eh_frame - the eh_frame FDEs have the start addr & size of each function
2483 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
2484 // Binaries built to run on older releases may need to use eh_frame information.
2485
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002486 if (text_section_sp && function_starts_data.GetByteSize())
2487 {
2488 FunctionStarts::Entry function_start_entry;
2489 function_start_entry.data = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00002490 lldb::offset_t function_start_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002491 function_start_entry.addr = text_section_sp->GetFileAddress();
2492 uint64_t delta;
2493 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
2494 {
2495 // Now append the current entry
2496 function_start_entry.addr += delta;
2497 function_starts.Append(function_start_entry);
2498 }
Jason Molendad63d3c72013-04-16 00:18:44 +00002499 }
Jason Molenda5635f772013-03-21 03:36:01 +00002500 else
2501 {
Jason Molenda584ce2f2013-03-22 00:38:45 +00002502 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
2503 // but it doesn't actually have the eh_frame content. And if we have a dSYM, we don't need to do any
2504 // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
2505 // the module.
2506 if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
Jason Molenda5635f772013-03-21 03:36:01 +00002507 {
2508 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindGCC, true);
2509 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
2510 eh_frame.GetFunctionAddressAndSizeVector (functions);
2511 addr_t text_base_addr = text_section_sp->GetFileAddress();
2512 size_t count = functions.GetSize();
2513 for (size_t i = 0; i < count; ++i)
2514 {
2515 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
2516 if (func)
2517 {
2518 FunctionStarts::Entry function_start_entry;
2519 function_start_entry.addr = func->base - text_base_addr;
2520 function_starts.Append(function_start_entry);
2521 }
2522 }
2523 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002524 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002525
Greg Claytonc7bece562013-01-25 18:06:21 +00002526 const size_t function_starts_count = function_starts.GetSize();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002527
Saleem Abdulrasoolb5c128b2014-07-23 01:53:52 +00002528 const user_id_t TEXT_eh_frame_sectID =
2529 eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
2530 : static_cast<user_id_t>(NO_SECT);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002531
Greg Claytonc7bece562013-01-25 18:06:21 +00002532 lldb::offset_t nlist_data_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002533
2534 uint32_t N_SO_index = UINT32_MAX;
2535
2536 MachSymtabSectionInfo section_info (section_list);
2537 std::vector<uint32_t> N_FUN_indexes;
2538 std::vector<uint32_t> N_NSYM_indexes;
2539 std::vector<uint32_t> N_INCL_indexes;
2540 std::vector<uint32_t> N_BRAC_indexes;
2541 std::vector<uint32_t> N_COMM_indexes;
Greg Claytond81088c2014-01-16 01:38:29 +00002542 typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002543 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
Greg Claytondacc4a92013-05-14 22:19:37 +00002544 typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002545 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2546 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
Greg Claytondacc4a92013-05-14 22:19:37 +00002547 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002548 // Any symbols that get merged into another will get an entry
2549 // in this map so we know
2550 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2551 uint32_t nlist_idx = 0;
2552 Symbol *symbol_ptr = NULL;
2553
2554 uint32_t sym_idx = 0;
Jason Molendaa5609c82012-06-21 01:51:02 +00002555 Symbol *sym = NULL;
Greg Claytonc7bece562013-01-25 18:06:21 +00002556 size_t num_syms = 0;
Greg Clayton4c82d422012-05-18 23:20:01 +00002557 std::string memory_symbol_name;
Jason Molendaa5609c82012-06-21 01:51:02 +00002558 uint32_t unmapped_local_symbols_found = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002559
Jim Inghamea3ac272014-01-10 22:55:37 +00002560 std::vector<TrieEntryWithOffset> trie_entries;
2561 std::set<lldb::addr_t> resolver_addresses;
2562
2563 if (dyld_trie_data.GetByteSize() > 0)
2564 {
2565 std::vector<llvm::StringRef> nameSlices;
2566 ParseTrieEntries (dyld_trie_data,
2567 0,
Greg Claytonb887da12015-07-16 19:50:57 +00002568 is_arm,
Jim Inghamea3ac272014-01-10 22:55:37 +00002569 nameSlices,
2570 resolver_addresses,
2571 trie_entries);
2572
2573 ConstString text_segment_name ("__TEXT");
2574 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2575 if (text_segment_sp)
2576 {
2577 const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
2578 if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
2579 {
2580 for (auto &e : trie_entries)
2581 e.entry.address += text_segment_file_addr;
2582 }
2583 }
2584 }
2585
Greg Claytonb65c6292015-02-20 22:20:05 +00002586 typedef std::set<ConstString> IndirectSymbols;
2587 IndirectSymbols indirect_symbol_names;
2588
Todd Fiala013434e2014-07-09 01:29:05 +00002589#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa5609c82012-06-21 01:51:02 +00002590
2591 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
2592 // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
2593 // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
2594 // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
2595 // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
2596 // nlist parser to ignore all LOCAL symbols.
2597
2598 if (m_header.flags & 0x80000000u)
2599 {
2600 // Before we can start mapping the DSC, we need to make certain the target process is actually
2601 // using the cache we can find.
2602
Jason Molendaa5609c82012-06-21 01:51:02 +00002603 // Next we need to determine the correct path for the dyld shared cache.
2604
Greg Clayton7ab7f892014-05-29 21:33:45 +00002605 ArchSpec header_arch;
2606 GetArchitecture(header_arch);
Jason Molendaa5609c82012-06-21 01:51:02 +00002607 char dsc_path[PATH_MAX];
2608
2609 snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
Jason Molenda4e7511e2013-03-06 23:19:17 +00002610 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
2611 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
Jason Molendaa5609c82012-06-21 01:51:02 +00002612 header_arch.GetArchitectureName());
2613
2614 FileSpec dsc_filespec(dsc_path, false);
2615
2616 // We need definitions of two structures in the on-disk DSC, copy them here manually
Jason Molendad63d3c72013-04-16 00:18:44 +00002617 struct lldb_copy_dyld_cache_header_v0
Greg Clayton946f8902012-09-05 22:30:51 +00002618 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002619 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2620 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2621 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
Jason Molenda4e7511e2013-03-06 23:19:17 +00002622 uint32_t imagesOffset;
2623 uint32_t imagesCount;
2624 uint64_t dyldBaseAddress;
2625 uint64_t codeSignatureOffset;
2626 uint64_t codeSignatureSize;
2627 uint64_t slideInfoOffset;
2628 uint64_t slideInfoSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002629 uint64_t localSymbolsOffset; // file offset of where local symbols are stored
2630 uint64_t localSymbolsSize; // size of local symbols information
2631 };
2632 struct lldb_copy_dyld_cache_header_v1
2633 {
2634 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2635 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2636 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
2637 uint32_t imagesOffset;
2638 uint32_t imagesCount;
2639 uint64_t dyldBaseAddress;
2640 uint64_t codeSignatureOffset;
2641 uint64_t codeSignatureSize;
2642 uint64_t slideInfoOffset;
2643 uint64_t slideInfoSize;
Jason Molenda4e7511e2013-03-06 23:19:17 +00002644 uint64_t localSymbolsOffset;
2645 uint64_t localSymbolsSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002646 uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later
Greg Clayton946f8902012-09-05 22:30:51 +00002647 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002648
Jason Molendad63d3c72013-04-16 00:18:44 +00002649 struct lldb_copy_dyld_cache_mapping_info
2650 {
2651 uint64_t address;
2652 uint64_t size;
2653 uint64_t fileOffset;
2654 uint32_t maxProt;
2655 uint32_t initProt;
2656 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002657
Greg Clayton946f8902012-09-05 22:30:51 +00002658 struct lldb_copy_dyld_cache_local_symbols_info
2659 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002660 uint32_t nlistOffset;
2661 uint32_t nlistCount;
2662 uint32_t stringsOffset;
2663 uint32_t stringsSize;
2664 uint32_t entriesOffset;
2665 uint32_t entriesCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002666 };
2667 struct lldb_copy_dyld_cache_local_symbols_entry
2668 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002669 uint32_t dylibOffset;
2670 uint32_t nlistStartIndex;
2671 uint32_t nlistCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002672 };
Jason Molendaa5609c82012-06-21 01:51:02 +00002673
Jason Molendaf8130862012-06-22 03:28:35 +00002674 /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
2675 The dyld_cache_local_symbols_info structure gives us three things:
2676 1. The start and count of the nlist records in the dyld_shared_cache file
2677 2. The start and size of the strings for these nlist records
2678 3. The start and count of dyld_cache_local_symbols_entry entries
2679
2680 There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
2681 The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
Jason Molenda4e7511e2013-03-06 23:19:17 +00002682 The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
Jason Molendaf8130862012-06-22 03:28:35 +00002683 and the count of how many nlist records there are for this dylib/framework.
2684 */
2685
Jason Molendaa5609c82012-06-21 01:51:02 +00002686 // Process the dsc header to find the unmapped symbols
2687 //
2688 // Save some VM space, do not map the entire cache in one shot.
2689
Jason Molenda255f9bb2013-03-06 23:17:36 +00002690 DataBufferSP dsc_data_sp;
Greg Clayton736888c2015-02-23 23:47:09 +00002691 dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
Jason Molenda255f9bb2013-03-06 23:17:36 +00002692
2693 if (dsc_data_sp)
Jason Molendaa5609c82012-06-21 01:51:02 +00002694 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002695 DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002696
Jason Molenda255f9bb2013-03-06 23:17:36 +00002697 char version_str[17];
2698 int version = -1;
2699 lldb::offset_t offset = 0;
2700 memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16);
2701 version_str[16] = '\0';
2702 if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6]))
2703 {
2704 int v;
2705 if (::sscanf (version_str + 6, "%d", &v) == 1)
2706 {
2707 version = v;
2708 }
2709 }
2710
Jason Molenda0e0954c2013-04-16 06:24:42 +00002711 UUID dsc_uuid;
2712 if (version >= 1)
2713 {
2714 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
2715 uint8_t uuid_bytes[sizeof (uuid_t)];
2716 memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
2717 dsc_uuid.SetBytes (uuid_bytes);
2718 }
2719
2720 bool uuid_match = true;
2721 if (dsc_uuid.IsValid() && process)
2722 {
2723 UUID shared_cache_uuid(GetProcessSharedCacheUUID(process));
2724
2725 if (shared_cache_uuid.IsValid() && dsc_uuid != shared_cache_uuid)
2726 {
2727 // The on-disk dyld_shared_cache file is not the same as the one in this
2728 // process' memory, don't use it.
2729 uuid_match = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002730 ModuleSP module_sp (GetModule());
2731 if (module_sp)
2732 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 +00002733 }
2734 }
2735
Jason Molenda4e7511e2013-03-06 23:19:17 +00002736 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);
Jason Molenda255f9bb2013-03-06 23:17:36 +00002737
Jason Molendaa5609c82012-06-21 01:51:02 +00002738 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
2739
2740 // If the mappingOffset points to a location inside the header, we've
2741 // opened an old dyld shared cache, and should not proceed further.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002742 if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
Jason Molendaa5609c82012-06-21 01:51:02 +00002743 {
2744
Greg Clayton736888c2015-02-23 23:47:09 +00002745 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 +00002746 DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
2747 offset = 0;
2748
2749 // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
2750 // in the shared library cache need to be adjusted by an offset to match up with the
2751 // dylibOffset identifying field in the dyld_cache_local_symbol_entry's. This offset is
2752 // recorded in mapping_offset_value.
2753 const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
2754
2755 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
Jason Molendaa5609c82012-06-21 01:51:02 +00002756 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
2757 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
2758
Jason Molenda4e7511e2013-03-06 23:19:17 +00002759 if (localSymbolsOffset && localSymbolsSize)
Jason Molendaa5609c82012-06-21 01:51:02 +00002760 {
2761 // Map the local symbols
Greg Clayton736888c2015-02-23 23:47:09 +00002762 if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(localSymbolsOffset, localSymbolsSize))
Jason Molendaa5609c82012-06-21 01:51:02 +00002763 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002764 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002765
2766 offset = 0;
2767
Greg Claytonb65c6292015-02-20 22:20:05 +00002768 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
2769 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
2770 UndefinedNameToDescMap undefined_name_to_desc;
2771 SymbolIndexToName reexport_shlib_needs_fixup;
2772
2773
Jason Molendaa5609c82012-06-21 01:51:02 +00002774 // Read the local_symbols_infos struct in one shot
2775 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
2776 dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
2777
Jason Molendaa5609c82012-06-21 01:51:02 +00002778 SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
2779
Jason Molenda255f9bb2013-03-06 23:17:36 +00002780 uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00002781
2782 offset = local_symbols_info.entriesOffset;
2783 for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
2784 {
2785 struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
2786 local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
2787 local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
2788 local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
2789
Jason Molenda4e7511e2013-03-06 23:19:17 +00002790 if (header_file_offset == local_symbols_entry.dylibOffset)
Jason Molendaa5609c82012-06-21 01:51:02 +00002791 {
2792 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
2793
2794 // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
2795 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2796 num_syms = symtab->GetNumSymbols();
2797
2798 nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
2799 uint32_t string_table_offset = local_symbols_info.stringsOffset;
2800
Jason Molenda4e7511e2013-03-06 23:19:17 +00002801 for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
Jason Molendaa5609c82012-06-21 01:51:02 +00002802 {
2803 /////////////////////////////
2804 {
2805 struct nlist_64 nlist;
2806 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2807 break;
2808
2809 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
2810 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2811 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2812 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
2813 nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
2814
2815 SymbolType type = eSymbolTypeInvalid;
2816 const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
2817
2818 if (symbol_name == NULL)
2819 {
2820 // No symbol should be NULL, even the symbols with no
2821 // string values should have an offset zero which points
2822 // to an empty C-string
2823 Host::SystemLog (Host::eSystemLogError,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002824 "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 +00002825 entry_index,
2826 nlist.n_strx,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002827 module_sp->GetFileSpec().GetPath().c_str());
Jason Molendaa5609c82012-06-21 01:51:02 +00002828 continue;
2829 }
2830 if (symbol_name[0] == '\0')
2831 symbol_name = NULL;
2832
2833 const char *symbol_name_non_abi_mangled = NULL;
2834
2835 SectionSP symbol_section;
2836 uint32_t symbol_byte_size = 0;
2837 bool add_nlist = true;
Charles Davis510938e2013-08-27 05:04:57 +00002838 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002839 bool demangled_is_synthesized = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00002840 bool is_gsym = false;
Greg Clayton60038be2015-02-14 00:51:13 +00002841 bool set_value = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00002842
2843 assert (sym_idx < num_syms);
2844
2845 sym[sym_idx].SetDebug (is_debug);
2846
2847 if (is_debug)
2848 {
2849 switch (nlist.n_type)
2850 {
Charles Davis510938e2013-08-27 05:04:57 +00002851 case N_GSYM:
2852 // global symbol: name,,NO_SECT,type,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002853 // Sometimes the N_GSYM value contains the address.
2854
2855 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
2856 // have the same address, but we want to ensure that we always find only the real symbol,
2857 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
2858 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
2859 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
2860 // same address.
2861
Greg Clayton1e28adf2015-02-25 17:25:02 +00002862 is_gsym = true;
2863 sym[sym_idx].SetExternal(true);
2864
2865 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
2866 {
2867 llvm::StringRef symbol_name_ref(symbol_name);
2868 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
2869 {
2870 symbol_name_non_abi_mangled = symbol_name + 1;
2871 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2872 type = eSymbolTypeObjCClass;
2873 demangled_is_synthesized = true;
2874
2875 }
2876 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
2877 {
2878 symbol_name_non_abi_mangled = symbol_name + 1;
2879 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2880 type = eSymbolTypeObjCMetaClass;
2881 demangled_is_synthesized = true;
2882 }
2883 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
2884 {
2885 symbol_name_non_abi_mangled = symbol_name + 1;
2886 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2887 type = eSymbolTypeObjCIVar;
2888 demangled_is_synthesized = true;
2889 }
2890 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002891 else
2892 {
Jason Molendaa5609c82012-06-21 01:51:02 +00002893 if (nlist.n_value != 0)
2894 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2895 type = eSymbolTypeData;
2896 }
2897 break;
2898
Charles Davis510938e2013-08-27 05:04:57 +00002899 case N_FNAME:
2900 // procedure name (f77 kludge): name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002901 type = eSymbolTypeCompiler;
2902 break;
2903
Charles Davis510938e2013-08-27 05:04:57 +00002904 case N_FUN:
2905 // procedure: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002906 if (symbol_name)
2907 {
2908 type = eSymbolTypeCode;
2909 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2910
Greg Claytond81088c2014-01-16 01:38:29 +00002911 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002912 // We use the current number of symbols in the symbol table in lieu of
2913 // using nlist_idx in case we ever start trimming entries out
2914 N_FUN_indexes.push_back(sym_idx);
2915 }
2916 else
2917 {
2918 type = eSymbolTypeCompiler;
2919
2920 if ( !N_FUN_indexes.empty() )
2921 {
2922 // Copy the size of the function into the original STAB entry so we don't have
2923 // to hunt for it later
2924 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
2925 N_FUN_indexes.pop_back();
2926 // We don't really need the end function STAB as it contains the size which
2927 // we already placed with the original symbol, so don't add it if we want a
2928 // minimal symbol table
Greg Clayton3046e662013-07-10 01:23:25 +00002929 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002930 }
2931 }
2932 break;
2933
Charles Davis510938e2013-08-27 05:04:57 +00002934 case N_STSYM:
2935 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00002936 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002937 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2938 type = eSymbolTypeData;
2939 break;
2940
Charles Davis510938e2013-08-27 05:04:57 +00002941 case N_LCSYM:
2942 // .lcomm symbol: name,,n_sect,type,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002943 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2944 type = eSymbolTypeCommonBlock;
2945 break;
2946
Charles Davis510938e2013-08-27 05:04:57 +00002947 case N_BNSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002948 // We use the current number of symbols in the symbol table in lieu of
2949 // using nlist_idx in case we ever start trimming entries out
Greg Clayton3046e662013-07-10 01:23:25 +00002950 // Skip these if we want minimal symbol tables
2951 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002952 break;
2953
Charles Davis510938e2013-08-27 05:04:57 +00002954 case N_ENSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002955 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
2956 // so that we can always skip the entire symbol if we need to navigate
2957 // more quickly at the source level when parsing STABS
Greg Clayton3046e662013-07-10 01:23:25 +00002958 // Skip these if we want minimal symbol tables
2959 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002960 break;
2961
2962
Charles Davis510938e2013-08-27 05:04:57 +00002963 case N_OPT:
2964 // emitted with gcc2_compiled and in gcc source
Jason Molendaa5609c82012-06-21 01:51:02 +00002965 type = eSymbolTypeCompiler;
2966 break;
2967
Charles Davis510938e2013-08-27 05:04:57 +00002968 case N_RSYM:
2969 // register sym: name,,NO_SECT,type,register
Jason Molendaa5609c82012-06-21 01:51:02 +00002970 type = eSymbolTypeVariable;
2971 break;
2972
Charles Davis510938e2013-08-27 05:04:57 +00002973 case N_SLINE:
2974 // src line: 0,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002975 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2976 type = eSymbolTypeLineEntry;
2977 break;
2978
Charles Davis510938e2013-08-27 05:04:57 +00002979 case N_SSYM:
2980 // structure elt: name,,NO_SECT,type,struct_offset
Jason Molendaa5609c82012-06-21 01:51:02 +00002981 type = eSymbolTypeVariableType;
2982 break;
2983
Charles Davis510938e2013-08-27 05:04:57 +00002984 case N_SO:
2985 // source file name
Jason Molendaa5609c82012-06-21 01:51:02 +00002986 type = eSymbolTypeSourceFile;
2987 if (symbol_name == NULL)
2988 {
Greg Clayton3046e662013-07-10 01:23:25 +00002989 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002990 if (N_SO_index != UINT32_MAX)
2991 {
2992 // Set the size of the N_SO to the terminating index of this N_SO
2993 // so that we can always skip the entire N_SO if we need to navigate
2994 // more quickly at the source level when parsing STABS
2995 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
Greg Clayton3046e662013-07-10 01:23:25 +00002996 symbol_ptr->SetByteSize(sym_idx);
Jason Molendaa5609c82012-06-21 01:51:02 +00002997 symbol_ptr->SetSizeIsSibling(true);
2998 }
2999 N_NSYM_indexes.clear();
3000 N_INCL_indexes.clear();
3001 N_BRAC_indexes.clear();
3002 N_COMM_indexes.clear();
3003 N_FUN_indexes.clear();
3004 N_SO_index = UINT32_MAX;
3005 }
3006 else
3007 {
3008 // We use the current number of symbols in the symbol table in lieu of
3009 // using nlist_idx in case we ever start trimming entries out
3010 const bool N_SO_has_full_path = symbol_name[0] == '/';
3011 if (N_SO_has_full_path)
3012 {
Greg Clayton3046e662013-07-10 01:23:25 +00003013 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00003014 {
3015 // We have two consecutive N_SO entries where the first contains a directory
3016 // and the second contains a full path.
Jason Molendad9d5cf52012-07-20 03:35:44 +00003017 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00003018 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3019 add_nlist = false;
3020 }
3021 else
3022 {
3023 // This is the first entry in a N_SO that contains a directory or
3024 // a full path to the source file
3025 N_SO_index = sym_idx;
3026 }
3027 }
Greg Clayton3046e662013-07-10 01:23:25 +00003028 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00003029 {
3030 // This is usually the second N_SO entry that contains just the filename,
3031 // so here we combine it with the first one if we are minimizing the symbol table
3032 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
3033 if (so_path && so_path[0])
3034 {
3035 std::string full_so_path (so_path);
Greg Clayton0662d962012-09-07 20:29:13 +00003036 const size_t double_slash_pos = full_so_path.find("//");
3037 if (double_slash_pos != std::string::npos)
3038 {
3039 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003040 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Clayton0662d962012-09-07 20:29:13 +00003041 // and the second is the directory for the source file so you end up with
3042 // a path that looks like "/tmp/src//tmp/src/"
3043 FileSpec so_dir(so_path, false);
3044 if (!so_dir.Exists())
3045 {
3046 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3047 if (so_dir.Exists())
3048 {
3049 // Trim off the incorrect path
3050 full_so_path.erase(0, double_slash_pos + 1);
3051 }
3052 }
3053 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003054 if (*full_so_path.rbegin() != '/')
3055 full_so_path += '/';
3056 full_so_path += symbol_name;
Jason Molendad9d5cf52012-07-20 03:35:44 +00003057 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00003058 add_nlist = false;
3059 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3060 }
3061 }
Greg Clayton946f8902012-09-05 22:30:51 +00003062 else
3063 {
3064 // This could be a relative path to a N_SO
3065 N_SO_index = sym_idx;
3066 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003067 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003068 break;
3069
Charles Davis510938e2013-08-27 05:04:57 +00003070 case N_OSO:
3071 // object file name: name,,0,0,st_mtime
Jason Molendaa5609c82012-06-21 01:51:02 +00003072 type = eSymbolTypeObjectFile;
3073 break;
3074
Charles Davis510938e2013-08-27 05:04:57 +00003075 case N_LSYM:
3076 // local sym: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003077 type = eSymbolTypeLocal;
3078 break;
3079
3080 //----------------------------------------------------------------------
3081 // INCL scopes
3082 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003083 case N_BINCL:
3084 // include file beginning: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003085 // We use the current number of symbols in the symbol table in lieu of
3086 // using nlist_idx in case we ever start trimming entries out
3087 N_INCL_indexes.push_back(sym_idx);
3088 type = eSymbolTypeScopeBegin;
3089 break;
3090
Charles Davis510938e2013-08-27 05:04:57 +00003091 case N_EINCL:
3092 // include file end: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003093 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3094 // so that we can always skip the entire symbol if we need to navigate
3095 // more quickly at the source level when parsing STABS
3096 if ( !N_INCL_indexes.empty() )
3097 {
3098 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3099 symbol_ptr->SetByteSize(sym_idx + 1);
3100 symbol_ptr->SetSizeIsSibling(true);
3101 N_INCL_indexes.pop_back();
3102 }
3103 type = eSymbolTypeScopeEnd;
3104 break;
3105
Charles Davis510938e2013-08-27 05:04:57 +00003106 case N_SOL:
3107 // #included file name: name,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003108 type = eSymbolTypeHeaderFile;
3109
3110 // We currently don't use the header files on darwin
Greg Clayton3046e662013-07-10 01:23:25 +00003111 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00003112 break;
3113
Charles Davis510938e2013-08-27 05:04:57 +00003114 case N_PARAMS:
3115 // compiler parameters: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003116 type = eSymbolTypeCompiler;
3117 break;
3118
Charles Davis510938e2013-08-27 05:04:57 +00003119 case N_VERSION:
3120 // compiler version: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003121 type = eSymbolTypeCompiler;
3122 break;
3123
Charles Davis510938e2013-08-27 05:04:57 +00003124 case N_OLEVEL:
3125 // compiler -O level: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003126 type = eSymbolTypeCompiler;
3127 break;
3128
Charles Davis510938e2013-08-27 05:04:57 +00003129 case N_PSYM:
3130 // parameter: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003131 type = eSymbolTypeVariable;
3132 break;
3133
Charles Davis510938e2013-08-27 05:04:57 +00003134 case N_ENTRY:
3135 // alternate entry: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003136 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3137 type = eSymbolTypeLineEntry;
3138 break;
3139
3140 //----------------------------------------------------------------------
3141 // Left and Right Braces
3142 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003143 case N_LBRAC:
3144 // left bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003145 // We use the current number of symbols in the symbol table in lieu of
3146 // using nlist_idx in case we ever start trimming entries out
3147 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3148 N_BRAC_indexes.push_back(sym_idx);
3149 type = eSymbolTypeScopeBegin;
3150 break;
3151
Charles Davis510938e2013-08-27 05:04:57 +00003152 case N_RBRAC:
3153 // right bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003154 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
3155 // so that we can always skip the entire symbol if we need to navigate
3156 // more quickly at the source level when parsing STABS
3157 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3158 if ( !N_BRAC_indexes.empty() )
3159 {
3160 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
3161 symbol_ptr->SetByteSize(sym_idx + 1);
3162 symbol_ptr->SetSizeIsSibling(true);
3163 N_BRAC_indexes.pop_back();
3164 }
3165 type = eSymbolTypeScopeEnd;
3166 break;
3167
Charles Davis510938e2013-08-27 05:04:57 +00003168 case N_EXCL:
3169 // deleted include file: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003170 type = eSymbolTypeHeaderFile;
3171 break;
3172
3173 //----------------------------------------------------------------------
3174 // COMM scopes
3175 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003176 case N_BCOMM:
3177 // begin common: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003178 // We use the current number of symbols in the symbol table in lieu of
3179 // using nlist_idx in case we ever start trimming entries out
3180 type = eSymbolTypeScopeBegin;
3181 N_COMM_indexes.push_back(sym_idx);
3182 break;
3183
Charles Davis510938e2013-08-27 05:04:57 +00003184 case N_ECOML:
3185 // end common (local name): 0,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003186 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3187 // Fall through
3188
Charles Davis510938e2013-08-27 05:04:57 +00003189 case N_ECOMM:
3190 // end common: name,,n_sect,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003191 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
3192 // so that we can always skip the entire symbol if we need to navigate
3193 // more quickly at the source level when parsing STABS
3194 if ( !N_COMM_indexes.empty() )
3195 {
3196 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
3197 symbol_ptr->SetByteSize(sym_idx + 1);
3198 symbol_ptr->SetSizeIsSibling(true);
3199 N_COMM_indexes.pop_back();
3200 }
3201 type = eSymbolTypeScopeEnd;
3202 break;
3203
Charles Davis510938e2013-08-27 05:04:57 +00003204 case N_LENG:
3205 // second stab entry with length information
Jason Molendaa5609c82012-06-21 01:51:02 +00003206 type = eSymbolTypeAdditional;
3207 break;
3208
3209 default: break;
3210 }
3211 }
3212 else
3213 {
Charles Davis510938e2013-08-27 05:04:57 +00003214 //uint8_t n_pext = N_PEXT & nlist.n_type;
3215 uint8_t n_type = N_TYPE & nlist.n_type;
3216 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Jason Molendaa5609c82012-06-21 01:51:02 +00003217
3218 switch (n_type)
3219 {
Greg Clayton60038be2015-02-14 00:51:13 +00003220 case N_INDR:
3221 {
3222 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3223 if (reexport_name_cstr && reexport_name_cstr[0])
3224 {
3225 type = eSymbolTypeReExported;
3226 ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
3227 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3228 set_value = false;
3229 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3230 indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3231 }
3232 else
3233 type = eSymbolTypeUndefined;
3234 }
3235 break;
3236
Charles Davis510938e2013-08-27 05:04:57 +00003237 case N_UNDF:
Greg Clayton786ad182015-03-03 01:40:46 +00003238 if (symbol_name && symbol_name[0])
Greg Clayton60038be2015-02-14 00:51:13 +00003239 {
3240 ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
3241 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3242 }
3243 // Fall through
3244 case N_PBUD:
Jason Molendaa5609c82012-06-21 01:51:02 +00003245 type = eSymbolTypeUndefined;
3246 break;
3247
Charles Davis510938e2013-08-27 05:04:57 +00003248 case N_ABS:
Jason Molendaa5609c82012-06-21 01:51:02 +00003249 type = eSymbolTypeAbsolute;
3250 break;
3251
Charles Davis510938e2013-08-27 05:04:57 +00003252 case N_SECT:
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003253 {
3254 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00003255
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003256 if (symbol_section == NULL)
Jason Molendaa5609c82012-06-21 01:51:02 +00003257 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003258 // TODO: warn about this?
3259 add_nlist = false;
3260 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003261 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003262
3263 if (TEXT_eh_frame_sectID == nlist.n_sect)
Jason Molendaa5609c82012-06-21 01:51:02 +00003264 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003265 type = eSymbolTypeException;
3266 }
3267 else
3268 {
Charles Davis510938e2013-08-27 05:04:57 +00003269 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003270
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003271 switch (section_type)
Jason Molendaa5609c82012-06-21 01:51:02 +00003272 {
Charles Davis510938e2013-08-27 05:04:57 +00003273 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
3274 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
3275 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
3276 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
3277 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
3278 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
3279 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
3280 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
3281 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00003282 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
3283 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
3284 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
3285 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00003286 default:
3287 switch (symbol_section->GetType())
3288 {
3289 case lldb::eSectionTypeCode:
3290 type = eSymbolTypeCode;
3291 break;
3292 case eSectionTypeData:
3293 case eSectionTypeDataCString: // Inlined C string data
3294 case eSectionTypeDataCStringPointers: // Pointers to C string data
3295 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
3296 case eSectionTypeData4:
3297 case eSectionTypeData8:
3298 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00003299 type = eSymbolTypeData;
3300 break;
3301 default:
3302 break;
3303 }
3304 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003305 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003306
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003307 if (type == eSymbolTypeInvalid)
3308 {
3309 const char *symbol_sect_name = symbol_section->GetName().AsCString();
3310 if (symbol_section->IsDescendant (text_section_sp.get()))
3311 {
Charles Davis510938e2013-08-27 05:04:57 +00003312 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3313 S_ATTR_SELF_MODIFYING_CODE |
3314 S_ATTR_SOME_INSTRUCTIONS))
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003315 type = eSymbolTypeData;
3316 else
3317 type = eSymbolTypeCode;
3318 }
Greg Claytona381e102015-07-27 23:21:05 +00003319 else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3320 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
3321 symbol_section->IsDescendant(data_const_section_sp.get()))
Jason Molendaa5609c82012-06-21 01:51:02 +00003322 {
3323 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
3324 {
3325 type = eSymbolTypeRuntime;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003326
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003327 if (symbol_name &&
3328 symbol_name[0] == '_' &&
3329 symbol_name[1] == 'O' &&
Jason Molendaa5609c82012-06-21 01:51:02 +00003330 symbol_name[2] == 'B')
3331 {
3332 llvm::StringRef symbol_name_ref(symbol_name);
Jason Molendaa5609c82012-06-21 01:51:02 +00003333 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3334 {
3335 symbol_name_non_abi_mangled = symbol_name + 1;
3336 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3337 type = eSymbolTypeObjCClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003338 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003339 }
3340 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3341 {
3342 symbol_name_non_abi_mangled = symbol_name + 1;
3343 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3344 type = eSymbolTypeObjCMetaClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003345 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003346 }
3347 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3348 {
3349 symbol_name_non_abi_mangled = symbol_name + 1;
3350 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3351 type = eSymbolTypeObjCIVar;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003352 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003353 }
3354 }
3355 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003356 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
Jason Molendaa5609c82012-06-21 01:51:02 +00003357 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003358 type = eSymbolTypeException;
Jason Molendaa5609c82012-06-21 01:51:02 +00003359 }
3360 else
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003361 {
3362 type = eSymbolTypeData;
3363 }
3364 }
3365 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
3366 {
3367 type = eSymbolTypeTrampoline;
3368 }
3369 else if (symbol_section->IsDescendant(objc_section_sp.get()))
3370 {
3371 type = eSymbolTypeRuntime;
3372 if (symbol_name && symbol_name[0] == '.')
3373 {
3374 llvm::StringRef symbol_name_ref(symbol_name);
3375 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
3376 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
Jason Molendaa5609c82012-06-21 01:51:02 +00003377 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003378 symbol_name_non_abi_mangled = symbol_name;
3379 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
3380 type = eSymbolTypeObjCClass;
3381 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003382 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003383 }
3384 }
3385 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003386 }
3387 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003388 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003389 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003390 }
3391
3392 if (add_nlist)
3393 {
3394 uint64_t symbol_value = nlist.n_value;
Jason Molendaa5609c82012-06-21 01:51:02 +00003395 if (symbol_name_non_abi_mangled)
3396 {
Jason Molendad9d5cf52012-07-20 03:35:44 +00003397 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
3398 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Jason Molendaa5609c82012-06-21 01:51:02 +00003399 }
3400 else
3401 {
Greg Clayton3046e662013-07-10 01:23:25 +00003402 bool symbol_name_is_mangled = false;
3403
Jason Molendaa5609c82012-06-21 01:51:02 +00003404 if (symbol_name && symbol_name[0] == '_')
3405 {
3406 symbol_name_is_mangled = symbol_name[1] == '_';
3407 symbol_name++; // Skip the leading underscore
3408 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003409
Jason Molendaa5609c82012-06-21 01:51:02 +00003410 if (symbol_name)
3411 {
Greg Claytondacc4a92013-05-14 22:19:37 +00003412 ConstString const_symbol_name(symbol_name);
Greg Claytondacc4a92013-05-14 22:19:37 +00003413 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Clayton3046e662013-07-10 01:23:25 +00003414 if (is_gsym && is_debug)
Greg Clayton14cd13c2015-07-01 23:29:06 +00003415 {
3416 const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
3417 if (gsym_name)
3418 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3419 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003420 }
3421 }
3422 if (symbol_section)
3423 {
3424 const addr_t section_file_addr = symbol_section->GetFileAddress();
3425 if (symbol_byte_size == 0 && function_starts_count > 0)
3426 {
3427 addr_t symbol_lookup_file_addr = nlist.n_value;
3428 // Do an exact address match for non-ARM addresses, else get the closest since
3429 // the symbol might be a thumb symbol which has an address with bit zero set
3430 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
3431 if (is_arm && func_start_entry)
3432 {
3433 // Verify that the function start address is the symbol address (ARM)
3434 // or the symbol address + 1 (thumb)
3435 if (func_start_entry->addr != symbol_lookup_file_addr &&
3436 func_start_entry->addr != (symbol_lookup_file_addr + 1))
3437 {
3438 // Not the right entry, NULL it out...
3439 func_start_entry = NULL;
3440 }
3441 }
3442 if (func_start_entry)
3443 {
3444 func_start_entry->data = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003445
Jason Molendaa5609c82012-06-21 01:51:02 +00003446 addr_t symbol_file_addr = func_start_entry->addr;
3447 uint32_t symbol_flags = 0;
3448 if (is_arm)
3449 {
3450 if (symbol_file_addr & 1)
3451 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Greg Claytonb887da12015-07-16 19:50:57 +00003452 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Jason Molendaa5609c82012-06-21 01:51:02 +00003453 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003454
Jason Molendaa5609c82012-06-21 01:51:02 +00003455 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3456 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3457 if (next_func_start_entry)
3458 {
3459 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3460 // Be sure the clear the Thumb address bit when we calculate the size
3461 // from the current and next address
3462 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00003463 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Jason Molendaa5609c82012-06-21 01:51:02 +00003464 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
3465 }
3466 else
3467 {
3468 symbol_byte_size = section_end_file_addr - symbol_file_addr;
3469 }
3470 }
3471 }
3472 symbol_value -= section_file_addr;
3473 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003474
Greg Claytondacc4a92013-05-14 22:19:37 +00003475 if (is_debug == false)
3476 {
3477 if (type == eSymbolTypeCode)
3478 {
3479 // See if we can find a N_FUN entry for any code symbols.
3480 // If we do find a match, and the name matches, then we
3481 // can merge the two into just the function symbol to avoid
3482 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003483 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3484 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3485 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003486 {
Greg Claytond81088c2014-01-16 01:38:29 +00003487 bool found_it = false;
3488 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003489 {
Greg Claytond81088c2014-01-16 01:38:29 +00003490 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3491 {
3492 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3493 // We just need the flags from the linker symbol, so put these flags
3494 // into the N_FUN flags to avoid duplicate symbols in the symbol table
3495 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3496 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3497 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
3498 sym[pos->second].SetType (eSymbolTypeResolver);
3499 sym[sym_idx].Clear();
3500 found_it = true;
3501 break;
3502 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003503 }
Greg Claytond81088c2014-01-16 01:38:29 +00003504 if (found_it)
3505 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003506 }
Jim Inghamea3ac272014-01-10 22:55:37 +00003507 else
3508 {
Greg Claytond81088c2014-01-16 01:38:29 +00003509 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00003510 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00003511 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003512 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00003513 else if (type == eSymbolTypeData ||
3514 type == eSymbolTypeObjCClass ||
3515 type == eSymbolTypeObjCMetaClass ||
3516 type == eSymbolTypeObjCIVar )
Greg Claytondacc4a92013-05-14 22:19:37 +00003517 {
3518 // See if we can find a N_STSYM entry for any data symbols.
3519 // If we do find a match, and the name matches, then we
3520 // can merge the two into just the Static symbol to avoid
3521 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003522 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3523 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
3524 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003525 {
Greg Claytond81088c2014-01-16 01:38:29 +00003526 bool found_it = false;
3527 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003528 {
Greg Claytond81088c2014-01-16 01:38:29 +00003529 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3530 {
3531 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3532 // We just need the flags from the linker symbol, so put these flags
3533 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3534 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3535 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3536 sym[sym_idx].Clear();
3537 found_it = true;
3538 break;
3539 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003540 }
Greg Claytond81088c2014-01-16 01:38:29 +00003541 if (found_it)
3542 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003543 }
3544 else
3545 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00003546 const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
3547 if (gsym_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003548 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00003549 // Combine N_GSYM stab entries with the non stab symbol
3550 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
3551 if (pos != N_GSYM_name_to_sym_idx.end())
3552 {
3553 const uint32_t GSYM_sym_idx = pos->second;
3554 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
3555 // Copy the address, because often the N_GSYM address has an invalid address of zero
3556 // when the global is a common symbol
3557 sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
3558 sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
3559 // We just need the flags from the linker symbol, so put these flags
3560 // into the N_GSYM flags to avoid duplicate symbols in the symbol table
3561 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3562 sym[sym_idx].Clear();
3563 continue;
3564 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003565 }
3566 }
3567 }
3568 }
3569
Jason Molendaa5609c82012-06-21 01:51:02 +00003570 sym[sym_idx].SetID (nlist_idx);
3571 sym[sym_idx].SetType (type);
Greg Clayton60038be2015-02-14 00:51:13 +00003572 if (set_value)
3573 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00003574 sym[sym_idx].GetAddressRef().SetSection (symbol_section);
3575 sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
Greg Clayton60038be2015-02-14 00:51:13 +00003576 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003577 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003578
Jason Molendaa5609c82012-06-21 01:51:02 +00003579 if (symbol_byte_size > 0)
3580 sym[sym_idx].SetByteSize(symbol_byte_size);
3581
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003582 if (demangled_is_synthesized)
3583 sym[sym_idx].SetDemangledNameIsSynthesized(true);
Jason Molendaa5609c82012-06-21 01:51:02 +00003584 ++sym_idx;
3585 }
3586 else
3587 {
3588 sym[sym_idx].Clear();
3589 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003590
Jason Molendaa5609c82012-06-21 01:51:02 +00003591 }
3592 /////////////////////////////
3593 }
3594 break; // No more entries to consider
3595 }
3596 }
Greg Clayton60038be2015-02-14 00:51:13 +00003597
3598 for (const auto &pos :reexport_shlib_needs_fixup)
3599 {
3600 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3601 if (undef_pos != undefined_name_to_desc.end())
3602 {
3603 const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3604 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
3605 sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
3606 }
3607 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003608 }
3609 }
3610 }
3611 }
3612 }
3613
3614 // Must reset this in case it was mutated above!
3615 nlist_data_offset = 0;
3616#endif
Jim Inghamea3ac272014-01-10 22:55:37 +00003617
Greg Claytonfd814c52013-08-13 01:42:25 +00003618 if (nlist_data.GetByteSize() > 0)
Jason Molendaa5609c82012-06-21 01:51:02 +00003619 {
Jason Molendaa5609c82012-06-21 01:51:02 +00003620
Greg Claytonfd814c52013-08-13 01:42:25 +00003621 // If the sym array was not created while parsing the DSC unmapped
3622 // symbols, create it now.
3623 if (sym == NULL)
Greg Clayton4c82d422012-05-18 23:20:01 +00003624 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003625 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3626 num_syms = symtab->GetNumSymbols();
3627 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003628
Greg Claytonfd814c52013-08-13 01:42:25 +00003629 if (unmapped_local_symbols_found)
3630 {
3631 assert(m_dysymtab.ilocalsym == 0);
3632 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3633 nlist_idx = m_dysymtab.nlocalsym;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003634 }
Greg Claytondebb8812012-05-25 17:04:00 +00003635 else
3636 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003637 nlist_idx = 0;
Greg Claytondebb8812012-05-25 17:04:00 +00003638 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003639
Greg Clayton60038be2015-02-14 00:51:13 +00003640 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
3641 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
3642 UndefinedNameToDescMap undefined_name_to_desc;
3643 SymbolIndexToName reexport_shlib_needs_fixup;
Greg Claytonfd814c52013-08-13 01:42:25 +00003644 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003645 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003646 struct nlist_64 nlist;
3647 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
3648 break;
3649
3650 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
3651 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
3652 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
3653 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
3654 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
3655
3656 SymbolType type = eSymbolTypeInvalid;
3657 const char *symbol_name = NULL;
3658
3659 if (have_strtab_data)
Greg Clayton77ccca72011-12-30 00:32:24 +00003660 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003661 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003662
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003663 if (symbol_name == NULL)
3664 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003665 // No symbol should be NULL, even the symbols with no
3666 // string values should have an offset zero which points
3667 // to an empty C-string
3668 Host::SystemLog (Host::eSystemLogError,
3669 "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
3670 nlist_idx,
3671 nlist.n_strx,
3672 module_sp->GetFileSpec().GetPath().c_str());
3673 continue;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003674 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003675 if (symbol_name[0] == '\0')
3676 symbol_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003677 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003678 else
3679 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003680 const addr_t str_addr = strtab_addr + nlist.n_strx;
3681 Error str_error;
3682 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
3683 symbol_name = memory_symbol_name.c_str();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003684 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003685 const char *symbol_name_non_abi_mangled = NULL;
3686
3687 SectionSP symbol_section;
3688 lldb::addr_t symbol_byte_size = 0;
3689 bool add_nlist = true;
3690 bool is_gsym = false;
Charles Davis510938e2013-08-27 05:04:57 +00003691 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00003692 bool demangled_is_synthesized = false;
Greg Clayton60038be2015-02-14 00:51:13 +00003693 bool set_value = true;
Greg Claytonfd814c52013-08-13 01:42:25 +00003694 assert (sym_idx < num_syms);
3695
3696 sym[sym_idx].SetDebug (is_debug);
3697
3698 if (is_debug)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003699 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003700 switch (nlist.n_type)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003701 {
Charles Davis510938e2013-08-27 05:04:57 +00003702 case N_GSYM:
3703 // global symbol: name,,NO_SECT,type,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003704 // Sometimes the N_GSYM value contains the address.
Jason Molenda4e7511e2013-03-06 23:19:17 +00003705
Greg Claytonfd814c52013-08-13 01:42:25 +00003706 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
3707 // have the same address, but we want to ensure that we always find only the real symbol,
3708 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
3709 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
3710 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
3711 // same address.
Greg Clayton1e28adf2015-02-25 17:25:02 +00003712 is_gsym = true;
3713 sym[sym_idx].SetExternal(true);
Greg Clayton29e08cb2012-03-14 01:53:24 +00003714
Greg Clayton1e28adf2015-02-25 17:25:02 +00003715 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
3716 {
3717 llvm::StringRef symbol_name_ref(symbol_name);
3718 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3719 {
3720 symbol_name_non_abi_mangled = symbol_name + 1;
3721 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3722 type = eSymbolTypeObjCClass;
3723 demangled_is_synthesized = true;
3724
3725 }
3726 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3727 {
3728 symbol_name_non_abi_mangled = symbol_name + 1;
3729 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3730 type = eSymbolTypeObjCMetaClass;
3731 demangled_is_synthesized = true;
3732 }
3733 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3734 {
3735 symbol_name_non_abi_mangled = symbol_name + 1;
3736 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3737 type = eSymbolTypeObjCIVar;
3738 demangled_is_synthesized = true;
3739 }
3740 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003741 else
3742 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003743 if (nlist.n_value != 0)
3744 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3745 type = eSymbolTypeData;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003746 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003747 break;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003748
Charles Davis510938e2013-08-27 05:04:57 +00003749 case N_FNAME:
3750 // procedure name (f77 kludge): name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003751 type = eSymbolTypeCompiler;
3752 break;
3753
Charles Davis510938e2013-08-27 05:04:57 +00003754 case N_FUN:
3755 // procedure: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003756 if (symbol_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003757 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003758 type = eSymbolTypeCode;
3759 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3760
Greg Claytond81088c2014-01-16 01:38:29 +00003761 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003762 // We use the current number of symbols in the symbol table in lieu of
3763 // using nlist_idx in case we ever start trimming entries out
3764 N_FUN_indexes.push_back(sym_idx);
Greg Claytondacc4a92013-05-14 22:19:37 +00003765 }
3766 else
3767 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003768 type = eSymbolTypeCompiler;
3769
3770 if ( !N_FUN_indexes.empty() )
Greg Claytondacc4a92013-05-14 22:19:37 +00003771 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003772 // Copy the size of the function into the original STAB entry so we don't have
3773 // to hunt for it later
3774 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
3775 N_FUN_indexes.pop_back();
3776 // We don't really need the end function STAB as it contains the size which
3777 // we already placed with the original symbol, so don't add it if we want a
3778 // minimal symbol table
3779 add_nlist = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00003780 }
3781 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003782 break;
3783
Charles Davis510938e2013-08-27 05:04:57 +00003784 case N_STSYM:
3785 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00003786 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003787 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3788 type = eSymbolTypeData;
3789 break;
3790
Charles Davis510938e2013-08-27 05:04:57 +00003791 case N_LCSYM:
3792 // .lcomm symbol: name,,n_sect,type,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003793 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3794 type = eSymbolTypeCommonBlock;
3795 break;
3796
Charles Davis510938e2013-08-27 05:04:57 +00003797 case N_BNSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003798 // We use the current number of symbols in the symbol table in lieu of
3799 // using nlist_idx in case we ever start trimming entries out
3800 // Skip these if we want minimal symbol tables
3801 add_nlist = false;
3802 break;
3803
Charles Davis510938e2013-08-27 05:04:57 +00003804 case N_ENSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003805 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
3806 // so that we can always skip the entire symbol if we need to navigate
3807 // more quickly at the source level when parsing STABS
3808 // Skip these if we want minimal symbol tables
3809 add_nlist = false;
3810 break;
3811
3812
Charles Davis510938e2013-08-27 05:04:57 +00003813 case N_OPT:
3814 // emitted with gcc2_compiled and in gcc source
Greg Claytonfd814c52013-08-13 01:42:25 +00003815 type = eSymbolTypeCompiler;
3816 break;
3817
Charles Davis510938e2013-08-27 05:04:57 +00003818 case N_RSYM:
3819 // register sym: name,,NO_SECT,type,register
Greg Claytonfd814c52013-08-13 01:42:25 +00003820 type = eSymbolTypeVariable;
3821 break;
3822
Charles Davis510938e2013-08-27 05:04:57 +00003823 case N_SLINE:
3824 // src line: 0,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003825 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3826 type = eSymbolTypeLineEntry;
3827 break;
3828
Charles Davis510938e2013-08-27 05:04:57 +00003829 case N_SSYM:
3830 // structure elt: name,,NO_SECT,type,struct_offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003831 type = eSymbolTypeVariableType;
3832 break;
3833
Charles Davis510938e2013-08-27 05:04:57 +00003834 case N_SO:
3835 // source file name
Greg Claytonfd814c52013-08-13 01:42:25 +00003836 type = eSymbolTypeSourceFile;
3837 if (symbol_name == NULL)
3838 {
3839 add_nlist = false;
3840 if (N_SO_index != UINT32_MAX)
3841 {
3842 // Set the size of the N_SO to the terminating index of this N_SO
3843 // so that we can always skip the entire N_SO if we need to navigate
3844 // more quickly at the source level when parsing STABS
3845 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
3846 symbol_ptr->SetByteSize(sym_idx);
3847 symbol_ptr->SetSizeIsSibling(true);
3848 }
3849 N_NSYM_indexes.clear();
3850 N_INCL_indexes.clear();
3851 N_BRAC_indexes.clear();
3852 N_COMM_indexes.clear();
3853 N_FUN_indexes.clear();
3854 N_SO_index = UINT32_MAX;
3855 }
3856 else
3857 {
3858 // We use the current number of symbols in the symbol table in lieu of
3859 // using nlist_idx in case we ever start trimming entries out
3860 const bool N_SO_has_full_path = symbol_name[0] == '/';
3861 if (N_SO_has_full_path)
3862 {
3863 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3864 {
3865 // We have two consecutive N_SO entries where the first contains a directory
3866 // and the second contains a full path.
3867 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
3868 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3869 add_nlist = false;
3870 }
3871 else
3872 {
3873 // This is the first entry in a N_SO that contains a directory or
3874 // a full path to the source file
3875 N_SO_index = sym_idx;
3876 }
3877 }
3878 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3879 {
3880 // This is usually the second N_SO entry that contains just the filename,
3881 // so here we combine it with the first one if we are minimizing the symbol table
Greg Claytonddaf6a72015-07-08 22:32:23 +00003882 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString();
Greg Claytonfd814c52013-08-13 01:42:25 +00003883 if (so_path && so_path[0])
3884 {
3885 std::string full_so_path (so_path);
3886 const size_t double_slash_pos = full_so_path.find("//");
3887 if (double_slash_pos != std::string::npos)
3888 {
3889 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003890 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Claytonfd814c52013-08-13 01:42:25 +00003891 // and the second is the directory for the source file so you end up with
3892 // a path that looks like "/tmp/src//tmp/src/"
3893 FileSpec so_dir(so_path, false);
3894 if (!so_dir.Exists())
3895 {
3896 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3897 if (so_dir.Exists())
3898 {
3899 // Trim off the incorrect path
3900 full_so_path.erase(0, double_slash_pos + 1);
3901 }
3902 }
3903 }
3904 if (*full_so_path.rbegin() != '/')
3905 full_so_path += '/';
3906 full_so_path += symbol_name;
3907 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
3908 add_nlist = false;
3909 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3910 }
3911 }
3912 else
3913 {
3914 // This could be a relative path to a N_SO
3915 N_SO_index = sym_idx;
3916 }
3917 }
3918
3919 break;
3920
Charles Davis510938e2013-08-27 05:04:57 +00003921 case N_OSO:
3922 // object file name: name,,0,0,st_mtime
Greg Claytonfd814c52013-08-13 01:42:25 +00003923 type = eSymbolTypeObjectFile;
3924 break;
3925
Charles Davis510938e2013-08-27 05:04:57 +00003926 case N_LSYM:
3927 // local sym: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003928 type = eSymbolTypeLocal;
3929 break;
3930
3931 //----------------------------------------------------------------------
3932 // INCL scopes
3933 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003934 case N_BINCL:
3935 // include file beginning: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00003936 // We use the current number of symbols in the symbol table in lieu of
3937 // using nlist_idx in case we ever start trimming entries out
3938 N_INCL_indexes.push_back(sym_idx);
3939 type = eSymbolTypeScopeBegin;
3940 break;
3941
Charles Davis510938e2013-08-27 05:04:57 +00003942 case N_EINCL:
3943 // include file end: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003944 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3945 // so that we can always skip the entire symbol if we need to navigate
3946 // more quickly at the source level when parsing STABS
3947 if ( !N_INCL_indexes.empty() )
3948 {
3949 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3950 symbol_ptr->SetByteSize(sym_idx + 1);
3951 symbol_ptr->SetSizeIsSibling(true);
3952 N_INCL_indexes.pop_back();
3953 }
3954 type = eSymbolTypeScopeEnd;
3955 break;
3956
Charles Davis510938e2013-08-27 05:04:57 +00003957 case N_SOL:
3958 // #included file name: name,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003959 type = eSymbolTypeHeaderFile;
3960
3961 // We currently don't use the header files on darwin
3962 add_nlist = false;
3963 break;
3964
Charles Davis510938e2013-08-27 05:04:57 +00003965 case N_PARAMS:
3966 // compiler parameters: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003967 type = eSymbolTypeCompiler;
3968 break;
3969
Charles Davis510938e2013-08-27 05:04:57 +00003970 case N_VERSION:
3971 // compiler version: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003972 type = eSymbolTypeCompiler;
3973 break;
3974
Charles Davis510938e2013-08-27 05:04:57 +00003975 case N_OLEVEL:
3976 // compiler -O level: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003977 type = eSymbolTypeCompiler;
3978 break;
3979
Charles Davis510938e2013-08-27 05:04:57 +00003980 case N_PSYM:
3981 // parameter: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003982 type = eSymbolTypeVariable;
3983 break;
3984
Charles Davis510938e2013-08-27 05:04:57 +00003985 case N_ENTRY:
3986 // alternate entry: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003987 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3988 type = eSymbolTypeLineEntry;
3989 break;
3990
3991 //----------------------------------------------------------------------
3992 // Left and Right Braces
3993 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003994 case N_LBRAC:
3995 // left bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003996 // We use the current number of symbols in the symbol table in lieu of
3997 // using nlist_idx in case we ever start trimming entries out
3998 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3999 N_BRAC_indexes.push_back(sym_idx);
4000 type = eSymbolTypeScopeBegin;
4001 break;
4002
Charles Davis510938e2013-08-27 05:04:57 +00004003 case N_RBRAC:
4004 // right bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004005 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
4006 // so that we can always skip the entire symbol if we need to navigate
4007 // more quickly at the source level when parsing STABS
4008 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4009 if ( !N_BRAC_indexes.empty() )
4010 {
4011 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
4012 symbol_ptr->SetByteSize(sym_idx + 1);
4013 symbol_ptr->SetSizeIsSibling(true);
4014 N_BRAC_indexes.pop_back();
4015 }
4016 type = eSymbolTypeScopeEnd;
4017 break;
4018
Charles Davis510938e2013-08-27 05:04:57 +00004019 case N_EXCL:
4020 // deleted include file: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00004021 type = eSymbolTypeHeaderFile;
4022 break;
4023
4024 //----------------------------------------------------------------------
4025 // COMM scopes
4026 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00004027 case N_BCOMM:
4028 // begin common: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004029 // We use the current number of symbols in the symbol table in lieu of
4030 // using nlist_idx in case we ever start trimming entries out
4031 type = eSymbolTypeScopeBegin;
4032 N_COMM_indexes.push_back(sym_idx);
4033 break;
4034
Charles Davis510938e2013-08-27 05:04:57 +00004035 case N_ECOML:
4036 // end common (local name): 0,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004037 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4038 // Fall through
4039
Charles Davis510938e2013-08-27 05:04:57 +00004040 case N_ECOMM:
4041 // end common: name,,n_sect,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004042 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
4043 // so that we can always skip the entire symbol if we need to navigate
4044 // more quickly at the source level when parsing STABS
4045 if ( !N_COMM_indexes.empty() )
4046 {
4047 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
4048 symbol_ptr->SetByteSize(sym_idx + 1);
4049 symbol_ptr->SetSizeIsSibling(true);
4050 N_COMM_indexes.pop_back();
4051 }
4052 type = eSymbolTypeScopeEnd;
4053 break;
4054
Charles Davis510938e2013-08-27 05:04:57 +00004055 case N_LENG:
4056 // second stab entry with length information
Greg Claytonfd814c52013-08-13 01:42:25 +00004057 type = eSymbolTypeAdditional;
4058 break;
4059
4060 default: break;
4061 }
4062 }
4063 else
4064 {
Charles Davis510938e2013-08-27 05:04:57 +00004065 //uint8_t n_pext = N_PEXT & nlist.n_type;
4066 uint8_t n_type = N_TYPE & nlist.n_type;
4067 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00004068
4069 switch (n_type)
4070 {
Greg Clayton60038be2015-02-14 00:51:13 +00004071 case N_INDR:
4072 {
4073 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4074 if (reexport_name_cstr && reexport_name_cstr[0])
4075 {
4076 type = eSymbolTypeReExported;
4077 ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
4078 sym[sym_idx].SetReExportedSymbolName(reexport_name);
4079 set_value = false;
4080 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4081 indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
4082 }
4083 else
4084 type = eSymbolTypeUndefined;
4085 }
4086 break;
4087
Charles Davis510938e2013-08-27 05:04:57 +00004088 case N_UNDF:
Greg Clayton786ad182015-03-03 01:40:46 +00004089 if (symbol_name && symbol_name[0])
Greg Clayton60038be2015-02-14 00:51:13 +00004090 {
4091 ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
4092 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4093 }
4094 // Fall through
4095 case N_PBUD:
Greg Claytonfd814c52013-08-13 01:42:25 +00004096 type = eSymbolTypeUndefined;
4097 break;
4098
Charles Davis510938e2013-08-27 05:04:57 +00004099 case N_ABS:
Greg Claytonfd814c52013-08-13 01:42:25 +00004100 type = eSymbolTypeAbsolute;
4101 break;
4102
Charles Davis510938e2013-08-27 05:04:57 +00004103 case N_SECT:
Greg Claytonfd814c52013-08-13 01:42:25 +00004104 {
4105 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4106
4107 if (!symbol_section)
4108 {
4109 // TODO: warn about this?
4110 add_nlist = false;
4111 break;
4112 }
4113
4114 if (TEXT_eh_frame_sectID == nlist.n_sect)
4115 {
4116 type = eSymbolTypeException;
4117 }
4118 else
4119 {
Charles Davis510938e2013-08-27 05:04:57 +00004120 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Greg Claytonfd814c52013-08-13 01:42:25 +00004121
4122 switch (section_type)
4123 {
Charles Davis510938e2013-08-27 05:04:57 +00004124 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
4125 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
4126 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
4127 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
4128 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
4129 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
4130 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
4131 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
4132 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00004133 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
4134 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
4135 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
4136 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00004137 default:
4138 switch (symbol_section->GetType())
4139 {
4140 case lldb::eSectionTypeCode:
4141 type = eSymbolTypeCode;
4142 break;
4143 case eSectionTypeData:
4144 case eSectionTypeDataCString: // Inlined C string data
4145 case eSectionTypeDataCStringPointers: // Pointers to C string data
4146 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
4147 case eSectionTypeData4:
4148 case eSectionTypeData8:
4149 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00004150 type = eSymbolTypeData;
4151 break;
4152 default:
4153 break;
4154 }
4155 break;
Greg Claytonfd814c52013-08-13 01:42:25 +00004156 }
4157
4158 if (type == eSymbolTypeInvalid)
4159 {
4160 const char *symbol_sect_name = symbol_section->GetName().AsCString();
4161 if (symbol_section->IsDescendant (text_section_sp.get()))
4162 {
Charles Davis510938e2013-08-27 05:04:57 +00004163 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4164 S_ATTR_SELF_MODIFYING_CODE |
4165 S_ATTR_SOME_INSTRUCTIONS))
Greg Claytonfd814c52013-08-13 01:42:25 +00004166 type = eSymbolTypeData;
4167 else
4168 type = eSymbolTypeCode;
4169 }
4170 else
Greg Claytona381e102015-07-27 23:21:05 +00004171 if (symbol_section->IsDescendant(data_section_sp.get()) ||
4172 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
4173 symbol_section->IsDescendant(data_const_section_sp.get()))
Greg Claytonfd814c52013-08-13 01:42:25 +00004174 {
4175 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
4176 {
4177 type = eSymbolTypeRuntime;
4178
4179 if (symbol_name &&
4180 symbol_name[0] == '_' &&
4181 symbol_name[1] == 'O' &&
4182 symbol_name[2] == 'B')
4183 {
4184 llvm::StringRef symbol_name_ref(symbol_name);
Greg Claytonfd814c52013-08-13 01:42:25 +00004185 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
4186 {
4187 symbol_name_non_abi_mangled = symbol_name + 1;
4188 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
4189 type = eSymbolTypeObjCClass;
4190 demangled_is_synthesized = true;
4191 }
4192 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
4193 {
4194 symbol_name_non_abi_mangled = symbol_name + 1;
4195 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
4196 type = eSymbolTypeObjCMetaClass;
4197 demangled_is_synthesized = true;
4198 }
4199 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
4200 {
4201 symbol_name_non_abi_mangled = symbol_name + 1;
4202 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
4203 type = eSymbolTypeObjCIVar;
4204 demangled_is_synthesized = true;
4205 }
4206 }
4207 }
4208 else
4209 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
4210 {
4211 type = eSymbolTypeException;
4212 }
4213 else
4214 {
4215 type = eSymbolTypeData;
4216 }
4217 }
4218 else
4219 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
4220 {
4221 type = eSymbolTypeTrampoline;
4222 }
4223 else
4224 if (symbol_section->IsDescendant(objc_section_sp.get()))
4225 {
4226 type = eSymbolTypeRuntime;
4227 if (symbol_name && symbol_name[0] == '.')
4228 {
4229 llvm::StringRef symbol_name_ref(symbol_name);
4230 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
4231 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
4232 {
4233 symbol_name_non_abi_mangled = symbol_name;
4234 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4235 type = eSymbolTypeObjCClass;
4236 demangled_is_synthesized = true;
4237 }
4238 }
4239 }
4240 }
4241 }
4242 }
4243 break;
Greg Claytondacc4a92013-05-14 22:19:37 +00004244 }
4245 }
4246
Greg Claytonfd814c52013-08-13 01:42:25 +00004247 if (add_nlist)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004248 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004249 uint64_t symbol_value = nlist.n_value;
4250
4251 if (symbol_name_non_abi_mangled)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004252 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004253 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
4254 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
4255 }
4256 else
4257 {
4258 bool symbol_name_is_mangled = false;
4259
4260 if (symbol_name && symbol_name[0] == '_')
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004261 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004262 symbol_name_is_mangled = symbol_name[1] == '_';
4263 symbol_name++; // Skip the leading underscore
4264 }
4265
4266 if (symbol_name)
4267 {
4268 ConstString const_symbol_name(symbol_name);
4269 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Claytonfd814c52013-08-13 01:42:25 +00004270 }
4271 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004272
4273 if (is_gsym)
Greg Clayton14cd13c2015-07-01 23:29:06 +00004274 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004275 const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
Greg Clayton14cd13c2015-07-01 23:29:06 +00004276 if (gsym_name)
4277 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4278 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004279
Greg Claytonfd814c52013-08-13 01:42:25 +00004280 if (symbol_section)
4281 {
4282 const addr_t section_file_addr = symbol_section->GetFileAddress();
4283 if (symbol_byte_size == 0 && function_starts_count > 0)
4284 {
4285 addr_t symbol_lookup_file_addr = nlist.n_value;
4286 // Do an exact address match for non-ARM addresses, else get the closest since
4287 // the symbol might be a thumb symbol which has an address with bit zero set
4288 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
4289 if (is_arm && func_start_entry)
4290 {
4291 // Verify that the function start address is the symbol address (ARM)
4292 // or the symbol address + 1 (thumb)
4293 if (func_start_entry->addr != symbol_lookup_file_addr &&
4294 func_start_entry->addr != (symbol_lookup_file_addr + 1))
4295 {
4296 // Not the right entry, NULL it out...
4297 func_start_entry = NULL;
4298 }
4299 }
4300 if (func_start_entry)
4301 {
4302 func_start_entry->data = true;
4303
4304 addr_t symbol_file_addr = func_start_entry->addr;
4305 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004306 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Claytonfd814c52013-08-13 01:42:25 +00004307
4308 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4309 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4310 if (next_func_start_entry)
4311 {
4312 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4313 // Be sure the clear the Thumb address bit when we calculate the size
4314 // from the current and next address
4315 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004316 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Claytonfd814c52013-08-13 01:42:25 +00004317 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
4318 }
4319 else
4320 {
4321 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4322 }
4323 }
4324 }
4325 symbol_value -= section_file_addr;
4326 }
4327
4328 if (is_debug == false)
4329 {
4330 if (type == eSymbolTypeCode)
4331 {
4332 // See if we can find a N_FUN entry for any code symbols.
4333 // If we do find a match, and the name matches, then we
4334 // can merge the two into just the function symbol to avoid
4335 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004336 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4337 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4338 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004339 {
Greg Claytond81088c2014-01-16 01:38:29 +00004340 bool found_it = false;
4341 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004342 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004343 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 +00004344 {
4345 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4346 // We just need the flags from the linker symbol, so put these flags
4347 // into the N_FUN flags to avoid duplicate symbols in the symbol table
4348 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4349 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4350 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
4351 sym[pos->second].SetType (eSymbolTypeResolver);
4352 sym[sym_idx].Clear();
4353 found_it = true;
4354 break;
4355 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004356 }
Greg Claytond81088c2014-01-16 01:38:29 +00004357 if (found_it)
4358 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004359 }
Jim Inghamea3ac272014-01-10 22:55:37 +00004360 else
4361 {
4362 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00004363 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00004364 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004365 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004366 else if (type == eSymbolTypeData ||
4367 type == eSymbolTypeObjCClass ||
4368 type == eSymbolTypeObjCMetaClass ||
4369 type == eSymbolTypeObjCIVar )
Greg Claytonfd814c52013-08-13 01:42:25 +00004370 {
4371 // See if we can find a N_STSYM entry for any data symbols.
4372 // If we do find a match, and the name matches, then we
4373 // can merge the two into just the Static symbol to avoid
4374 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004375 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4376 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4377 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004378 {
Greg Claytond81088c2014-01-16 01:38:29 +00004379 bool found_it = false;
4380 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004381 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004382 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 +00004383 {
4384 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4385 // We just need the flags from the linker symbol, so put these flags
4386 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
4387 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4388 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4389 sym[sym_idx].Clear();
4390 found_it = true;
4391 break;
4392 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004393 }
Greg Claytond81088c2014-01-16 01:38:29 +00004394 if (found_it)
4395 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004396 }
4397 else
4398 {
4399 // Combine N_GSYM stab entries with the non stab symbol
Greg Claytonddaf6a72015-07-08 22:32:23 +00004400 const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
Greg Clayton14cd13c2015-07-01 23:29:06 +00004401 if (gsym_name)
Greg Claytonfd814c52013-08-13 01:42:25 +00004402 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00004403 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
4404 if (pos != N_GSYM_name_to_sym_idx.end())
4405 {
4406 const uint32_t GSYM_sym_idx = pos->second;
4407 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4408 // Copy the address, because often the N_GSYM address has an invalid address of zero
4409 // when the global is a common symbol
4410 sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
4411 sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
4412 // We just need the flags from the linker symbol, so put these flags
4413 // into the N_GSYM flags to avoid duplicate symbols in the symbol table
4414 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4415 sym[sym_idx].Clear();
4416 continue;
4417 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004418 }
4419 }
4420 }
4421 }
4422
4423 sym[sym_idx].SetID (nlist_idx);
4424 sym[sym_idx].SetType (type);
Greg Clayton60038be2015-02-14 00:51:13 +00004425 if (set_value)
4426 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004427 sym[sym_idx].GetAddressRef().SetSection (symbol_section);
4428 sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
Greg Clayton60038be2015-02-14 00:51:13 +00004429 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004430 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4431
4432 if (symbol_byte_size > 0)
4433 sym[sym_idx].SetByteSize(symbol_byte_size);
4434
4435 if (demangled_is_synthesized)
4436 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4437
4438 ++sym_idx;
4439 }
4440 else
4441 {
4442 sym[sym_idx].Clear();
4443 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004444 }
Greg Clayton60038be2015-02-14 00:51:13 +00004445
4446 for (const auto &pos :reexport_shlib_needs_fixup)
4447 {
4448 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4449 if (undef_pos != undefined_name_to_desc.end())
4450 {
4451 const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4452 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4453 sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
4454 }
4455 }
4456
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004457 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004458
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004459 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4460
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004461 if (function_starts_count > 0)
4462 {
4463 char synthetic_function_symbol[PATH_MAX];
4464 uint32_t num_synthetic_function_symbols = 0;
4465 for (i=0; i<function_starts_count; ++i)
4466 {
4467 if (function_starts.GetEntryRef (i).data == false)
4468 ++num_synthetic_function_symbols;
4469 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004470
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004471 if (num_synthetic_function_symbols > 0)
4472 {
4473 if (num_syms < sym_idx + num_synthetic_function_symbols)
4474 {
4475 num_syms = sym_idx + num_synthetic_function_symbols;
4476 sym = symtab->Resize (num_syms);
4477 }
4478 uint32_t synthetic_function_symbol_idx = 0;
4479 for (i=0; i<function_starts_count; ++i)
4480 {
4481 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
4482 if (func_start_entry->data == false)
4483 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004484 addr_t symbol_file_addr = func_start_entry->addr;
4485 uint32_t symbol_flags = 0;
4486 if (is_arm)
4487 {
4488 if (symbol_file_addr & 1)
4489 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Greg Claytonb887da12015-07-16 19:50:57 +00004490 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004491 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004492 Address symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004493 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004494 {
4495 SectionSP symbol_section (symbol_addr.GetSection());
4496 uint32_t symbol_byte_size = 0;
4497 if (symbol_section)
4498 {
4499 const addr_t section_file_addr = symbol_section->GetFileAddress();
4500 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4501 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4502 if (next_func_start_entry)
4503 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004504 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4505 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004506 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004507 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 +00004508 }
4509 else
4510 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004511 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004512 }
4513 snprintf (synthetic_function_symbol,
4514 sizeof(synthetic_function_symbol),
4515 "___lldb_unnamed_function%u$$%s",
4516 ++synthetic_function_symbol_idx,
4517 module_sp->GetFileSpec().GetFilename().GetCString());
4518 sym[sym_idx].SetID (synthetic_sym_id++);
Greg Clayton037520e2012-07-18 23:18:10 +00004519 sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004520 sym[sym_idx].SetType (eSymbolTypeCode);
4521 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004522 sym[sym_idx].GetAddressRef() = symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004523 if (symbol_flags)
4524 sym[sym_idx].SetFlags (symbol_flags);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004525 if (symbol_byte_size)
4526 sym[sym_idx].SetByteSize (symbol_byte_size);
4527 ++sym_idx;
4528 }
4529 }
4530 }
4531 }
4532 }
4533 }
4534
4535 // Trim our symbols down to just what we ended up with after
4536 // removing any symbols.
4537 if (sym_idx < num_syms)
4538 {
4539 num_syms = sym_idx;
4540 sym = symtab->Resize (num_syms);
4541 }
4542
4543 // Now synthesize indirect symbols
4544 if (m_dysymtab.nindirectsyms != 0)
4545 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004546 if (indirect_symbol_index_data.GetByteSize())
4547 {
4548 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
4549
4550 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
4551 {
Charles Davis510938e2013-08-27 05:04:57 +00004552 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004553 {
4554 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4555 if (symbol_stub_byte_size == 0)
4556 continue;
4557
4558 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4559
4560 if (num_symbol_stubs == 0)
4561 continue;
4562
4563 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
4564 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
4565 {
4566 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
4567 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 +00004568 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004569 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
4570 {
4571 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
Charles Davis510938e2013-08-27 05:04:57 +00004572 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004573 continue;
4574
4575 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
4576 Symbol *stub_symbol = NULL;
4577 if (index_pos != end_index_pos)
4578 {
4579 // We have a remapping from the original nlist index to
4580 // a current symbol index, so just look this up by index
4581 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
4582 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004583 else
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004584 {
4585 // We need to lookup a symbol using the original nlist
Jason Molenda4e7511e2013-03-06 23:19:17 +00004586 // symbol index since this index is coming from the
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004587 // S_SYMBOL_STUBS
4588 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
4589 }
4590
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004591 if (stub_symbol)
4592 {
4593 Address so_addr(symbol_stub_addr, section_list);
4594
4595 if (stub_symbol->GetType() == eSymbolTypeUndefined)
4596 {
4597 // Change the external symbol into a trampoline that makes sense
4598 // These symbols were N_UNDF N_EXT, and are useless to us, so we
4599 // can re-use them so we don't have to make up a synthetic symbol
4600 // for no good reason.
Greg Clayton9191db42013-10-21 18:40:51 +00004601 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4602 stub_symbol->SetType (eSymbolTypeTrampoline);
4603 else
4604 stub_symbol->SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004605 stub_symbol->SetExternal (false);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004606 stub_symbol->GetAddressRef() = so_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004607 stub_symbol->SetByteSize (symbol_stub_byte_size);
4608 }
4609 else
4610 {
4611 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda0a287e02012-04-24 02:09:58 +00004612 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004613 if (sym_idx >= num_syms)
Jason Molenda0a287e02012-04-24 02:09:58 +00004614 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004615 sym = symtab->Resize (++num_syms);
Jason Molenda0a287e02012-04-24 02:09:58 +00004616 stub_symbol = NULL; // this pointer no longer valid
4617 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004618 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda0a287e02012-04-24 02:09:58 +00004619 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton9191db42013-10-21 18:40:51 +00004620 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4621 sym[sym_idx].SetType (eSymbolTypeTrampoline);
4622 else
4623 sym[sym_idx].SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004624 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004625 sym[sym_idx].GetAddressRef() = so_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004626 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
4627 ++sym_idx;
4628 }
4629 }
Greg Clayton3f839a32012-09-05 01:38:55 +00004630 else
4631 {
4632 if (log)
4633 log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
4634 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004635 }
4636 }
4637 }
4638 }
4639 }
4640 }
Greg Clayton9191db42013-10-21 18:40:51 +00004641
4642
4643 if (!trie_entries.empty())
4644 {
4645 for (const auto &e : trie_entries)
4646 {
4647 if (e.entry.import_name)
4648 {
Greg Clayton60038be2015-02-14 00:51:13 +00004649 // Only add indirect symbols from the Trie entries if we
4650 // didn't have a N_INDR nlist entry for this already
4651 if (indirect_symbol_names.find(e.entry.name) == indirect_symbol_names.end())
Greg Clayton9191db42013-10-21 18:40:51 +00004652 {
Greg Clayton60038be2015-02-14 00:51:13 +00004653 // Make a synthetic symbol to describe re-exported symbol.
4654 if (sym_idx >= num_syms)
4655 sym = symtab->Resize (++num_syms);
4656 sym[sym_idx].SetID (synthetic_sym_id++);
4657 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4658 sym[sym_idx].SetType (eSymbolTypeReExported);
4659 sym[sym_idx].SetIsSynthetic (true);
4660 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4661 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
4662 {
4663 sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
4664 }
4665 ++sym_idx;
Greg Clayton9191db42013-10-21 18:40:51 +00004666 }
Greg Clayton9191db42013-10-21 18:40:51 +00004667 }
4668 }
4669 }
4670
4671
Greg Clayton3046e662013-07-10 01:23:25 +00004672
4673// StreamFile s(stdout, false);
4674// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
4675// symtab->Dump(&s, NULL, eSortOrderNone);
4676 // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
4677 symtab->CalculateSymbolSizes();
4678
4679// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
4680// symtab->Dump(&s, NULL, eSortOrderNone);
4681
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004682 return symtab->GetNumSymbols();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004683 }
4684 return 0;
4685}
4686
4687
4688void
4689ObjectFileMachO::Dump (Stream *s)
4690{
Greg Claytona1743492012-03-13 23:14:29 +00004691 ModuleSP module_sp(GetModule());
4692 if (module_sp)
4693 {
4694 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004695 s->Printf("%p: ", static_cast<void*>(this));
Greg Claytona1743492012-03-13 23:14:29 +00004696 s->Indent();
Charles Davis510938e2013-08-27 05:04:57 +00004697 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
Greg Claytona1743492012-03-13 23:14:29 +00004698 s->PutCString("ObjectFileMachO64");
4699 else
4700 s->PutCString("ObjectFileMachO32");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004701
Greg Clayton7ab7f892014-05-29 21:33:45 +00004702 ArchSpec header_arch;
4703 GetArchitecture(header_arch);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004704
Greg Claytona1743492012-03-13 23:14:29 +00004705 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004706
Greg Clayton3046e662013-07-10 01:23:25 +00004707 SectionList *sections = GetSectionList();
4708 if (sections)
4709 sections->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004710
Greg Claytona1743492012-03-13 23:14:29 +00004711 if (m_symtab_ap.get())
4712 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
4713 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004714}
4715
Greg Claytonf4d6de62013-04-24 22:29:28 +00004716bool
4717ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header,
4718 const lldb_private::DataExtractor &data,
4719 lldb::offset_t lc_offset,
4720 lldb_private::UUID& uuid)
4721{
4722 uint32_t i;
4723 struct uuid_command load_cmd;
4724
4725 lldb::offset_t offset = lc_offset;
4726 for (i=0; i<header.ncmds; ++i)
4727 {
4728 const lldb::offset_t cmd_offset = offset;
4729 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4730 break;
4731
Charles Davis510938e2013-08-27 05:04:57 +00004732 if (load_cmd.cmd == LC_UUID)
Greg Claytonf4d6de62013-04-24 22:29:28 +00004733 {
4734 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4735
4736 if (uuid_bytes)
4737 {
4738 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4739 // We pretend these object files have no UUID to prevent crashing.
4740
4741 const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
4742 0x3b, 0xa8,
4743 0x4b, 0x16,
4744 0xb6, 0xa4,
4745 0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
4746
4747 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4748 return false;
4749
4750 uuid.SetBytes (uuid_bytes);
4751 return true;
4752 }
4753 return false;
4754 }
4755 offset = cmd_offset + load_cmd.cmdsize;
4756 }
4757 return false;
4758}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004759
Greg Clayton7ab7f892014-05-29 21:33:45 +00004760
4761bool
4762ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header,
4763 const lldb_private::DataExtractor &data,
4764 lldb::offset_t lc_offset,
4765 ArchSpec &arch)
4766{
4767 arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype);
4768
4769 if (arch.IsValid())
4770 {
4771 llvm::Triple &triple = arch.GetTriple();
4772 if (header.filetype == MH_PRELOAD)
4773 {
4774 // Set OS to "unknown" - this is a standalone binary with no dyld et al
4775 triple.setOS(llvm::Triple::UnknownOS);
4776 return true;
4777 }
4778 else
4779 {
4780 struct load_command load_cmd;
4781
4782 lldb::offset_t offset = lc_offset;
4783 for (uint32_t i=0; i<header.ncmds; ++i)
4784 {
4785 const lldb::offset_t cmd_offset = offset;
4786 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4787 break;
4788
4789 switch (load_cmd.cmd)
4790 {
4791 case LC_VERSION_MIN_IPHONEOS:
4792 triple.setOS (llvm::Triple::IOS);
4793 return true;
4794
4795 case LC_VERSION_MIN_MACOSX:
4796 triple.setOS (llvm::Triple::MacOSX);
4797 return true;
4798
4799 default:
4800 break;
4801 }
4802
4803 offset = cmd_offset + load_cmd.cmdsize;
4804 }
4805
Greg Claytona3a6c122014-07-29 18:04:57 +00004806 // Only set the OS to iOS for ARM, we don't want to set it for x86 and x86_64.
4807 // We do this because we now have MacOSX or iOS as the OS value for x86 and
4808 // x86_64 for normal desktop (MacOSX) and simulator (iOS) binaries. And if
4809 // we compare a "x86_64-apple-ios" to a "x86_64-apple-" triple, it will say
4810 // it is compatible (because the OS is unspecified in the second one and will
4811 // match anything in the first
Greg Clayton7ab7f892014-05-29 21:33:45 +00004812 if (header.cputype == CPU_TYPE_ARM || header.cputype == CPU_TYPE_ARM64)
4813 triple.setOS (llvm::Triple::IOS);
Greg Clayton7ab7f892014-05-29 21:33:45 +00004814 }
4815 }
4816 return arch.IsValid();
4817}
4818
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004819bool
Greg Clayton60830262011-02-04 18:53:10 +00004820ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004821{
Greg Claytona1743492012-03-13 23:14:29 +00004822 ModuleSP module_sp(GetModule());
4823 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004824 {
Greg Claytona1743492012-03-13 23:14:29 +00004825 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Claytonc7bece562013-01-25 18:06:21 +00004826 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +00004827 return GetUUID (m_header, m_data, offset, *uuid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004828 }
4829 return false;
4830}
4831
4832
4833uint32_t
4834ObjectFileMachO::GetDependentModules (FileSpecList& files)
4835{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004836 uint32_t count = 0;
Greg Claytona1743492012-03-13 23:14:29 +00004837 ModuleSP module_sp(GetModule());
4838 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004839 {
Greg Claytona1743492012-03-13 23:14:29 +00004840 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4841 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004842 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Clayton5a271952015-06-02 22:43:29 +00004843 std::vector<std::string> rpath_paths;
4844 std::vector<std::string> rpath_relative_paths;
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004845 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 +00004846 uint32_t i;
4847 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004848 {
Greg Claytona1743492012-03-13 23:14:29 +00004849 const uint32_t cmd_offset = offset;
4850 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4851 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004852
Greg Claytona1743492012-03-13 23:14:29 +00004853 switch (load_cmd.cmd)
4854 {
Greg Clayton5a271952015-06-02 22:43:29 +00004855 case LC_RPATH:
Charles Davis510938e2013-08-27 05:04:57 +00004856 case LC_LOAD_DYLIB:
4857 case LC_LOAD_WEAK_DYLIB:
4858 case LC_REEXPORT_DYLIB:
4859 case LC_LOAD_DYLINKER:
4860 case LC_LOADFVMLIB:
4861 case LC_LOAD_UPWARD_DYLIB:
Greg Claytona1743492012-03-13 23:14:29 +00004862 {
4863 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
4864 const char *path = m_data.PeekCStr(name_offset);
Greg Clayton5a271952015-06-02 22:43:29 +00004865 if (path)
Greg Claytona1743492012-03-13 23:14:29 +00004866 {
Greg Clayton5a271952015-06-02 22:43:29 +00004867 if (load_cmd.cmd == LC_RPATH)
4868 rpath_paths.push_back(path);
4869 else
4870 {
4871 if (path[0] == '@')
4872 {
4873 if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
4874 rpath_relative_paths.push_back(path + strlen("@rpath"));
4875 }
4876 else
4877 {
4878 FileSpec file_spec(path, resolve_path);
4879 if (files.AppendIfUnique(file_spec))
4880 count++;
4881 }
4882 }
Greg Claytona1743492012-03-13 23:14:29 +00004883 }
4884 }
4885 break;
4886
4887 default:
4888 break;
4889 }
4890 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004891 }
Greg Clayton5a271952015-06-02 22:43:29 +00004892
4893 if (!rpath_paths.empty())
4894 {
4895 // Fixup all LC_RPATH values to be absolute paths
4896 FileSpec this_file_spec(m_file);
4897 this_file_spec.ResolvePath();
4898 std::string loader_path("@loader_path");
4899 std::string executable_path("@executable_path");
4900 for (auto &rpath : rpath_paths)
4901 {
4902 if (rpath.find(loader_path) == 0)
4903 {
4904 rpath.erase(0, loader_path.size());
4905 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
4906 }
4907 else if (rpath.find(executable_path) == 0)
4908 {
4909 rpath.erase(0, executable_path.size());
4910 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
4911 }
4912 }
4913
4914 for (const auto &rpath_relative_path : rpath_relative_paths)
4915 {
4916 for (const auto &rpath : rpath_paths)
4917 {
4918 std::string path = rpath;
4919 path += rpath_relative_path;
4920 // It is OK to resolve this path because we must find a file on
4921 // disk for us to accept it anyway if it is rpath relative.
4922 FileSpec file_spec(path, true);
4923 // Remove any redundant parts of the path (like "../foo") since
4924 // LC_RPATH values often contain "..".
4925 file_spec.NormalizePath ();
4926 if (file_spec.Exists() && files.AppendIfUnique(file_spec))
4927 {
4928 count++;
4929 break;
4930 }
4931 }
4932 }
4933 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004934 }
4935 return count;
4936}
4937
Jim Ingham672e6f52011-03-07 23:44:08 +00004938lldb_private::Address
Jason Molenda4e7511e2013-03-06 23:19:17 +00004939ObjectFileMachO::GetEntryPointAddress ()
Jim Ingham672e6f52011-03-07 23:44:08 +00004940{
4941 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
4942 // is initialized to an invalid address, so we can just return that.
4943 // 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 +00004944
Jim Ingham672e6f52011-03-07 23:44:08 +00004945 if (!IsExecutable() || m_entry_point_address.IsValid())
4946 return m_entry_point_address;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004947
4948 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
Jim Ingham672e6f52011-03-07 23:44:08 +00004949 // /usr/include/mach-o.h, but it is basically:
4950 //
4951 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
4952 // uint32_t count - this is the count of longs in the thread state data
4953 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
4954 // <repeat this trio>
Jason Molenda4e7511e2013-03-06 23:19:17 +00004955 //
Jim Ingham672e6f52011-03-07 23:44:08 +00004956 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
4957 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
4958 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
4959 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
4960 //
4961 // For now we hard-code the offsets and flavors we need:
4962 //
4963 //
4964
Greg Claytona1743492012-03-13 23:14:29 +00004965 ModuleSP module_sp(GetModule());
4966 if (module_sp)
Jim Ingham672e6f52011-03-07 23:44:08 +00004967 {
Greg Claytona1743492012-03-13 23:14:29 +00004968 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4969 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004970 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00004971 uint32_t i;
4972 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
4973 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004974
Greg Claytona1743492012-03-13 23:14:29 +00004975 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham672e6f52011-03-07 23:44:08 +00004976 {
Greg Claytonc7bece562013-01-25 18:06:21 +00004977 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00004978 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4979 break;
4980
4981 switch (load_cmd.cmd)
Jim Ingham672e6f52011-03-07 23:44:08 +00004982 {
Charles Davis510938e2013-08-27 05:04:57 +00004983 case LC_UNIXTHREAD:
4984 case LC_THREAD:
Jim Ingham672e6f52011-03-07 23:44:08 +00004985 {
Greg Claytona1743492012-03-13 23:14:29 +00004986 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham672e6f52011-03-07 23:44:08 +00004987 {
Greg Claytona1743492012-03-13 23:14:29 +00004988 uint32_t flavor = m_data.GetU32(&offset);
4989 uint32_t count = m_data.GetU32(&offset);
4990 if (count == 0)
4991 {
4992 // We've gotten off somehow, log and exit;
4993 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00004994 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004995
Greg Claytona1743492012-03-13 23:14:29 +00004996 switch (m_header.cputype)
4997 {
Charles Davis510938e2013-08-27 05:04:57 +00004998 case llvm::MachO::CPU_TYPE_ARM:
Greg Claytona1743492012-03-13 23:14:29 +00004999 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
5000 {
5001 offset += 60; // This is the offset of pc in the GPR thread state data structure.
5002 start_address = m_data.GetU32(&offset);
5003 done = true;
5004 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005005 break;
Jason Molendaa3329782014-03-29 18:54:20 +00005006 case llvm::MachO::CPU_TYPE_ARM64:
5007 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
5008 {
5009 offset += 256; // This is the offset of pc in the GPR thread state data structure.
5010 start_address = m_data.GetU64(&offset);
5011 done = true;
5012 }
5013 break;
Charles Davis510938e2013-08-27 05:04:57 +00005014 case llvm::MachO::CPU_TYPE_I386:
Greg Claytona1743492012-03-13 23:14:29 +00005015 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
5016 {
5017 offset += 40; // This is the offset of eip in the GPR thread state data structure.
5018 start_address = m_data.GetU32(&offset);
5019 done = true;
5020 }
5021 break;
Charles Davis510938e2013-08-27 05:04:57 +00005022 case llvm::MachO::CPU_TYPE_X86_64:
Greg Claytona1743492012-03-13 23:14:29 +00005023 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
5024 {
5025 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
5026 start_address = m_data.GetU64(&offset);
5027 done = true;
5028 }
5029 break;
5030 default:
5031 return m_entry_point_address;
5032 }
5033 // Haven't found the GPR flavor yet, skip over the data for this flavor:
5034 if (done)
5035 break;
5036 offset += count * 4;
5037 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005038 }
Greg Claytona1743492012-03-13 23:14:29 +00005039 break;
Charles Davis510938e2013-08-27 05:04:57 +00005040 case LC_MAIN:
Sean Callanan226b70c2012-03-08 02:39:03 +00005041 {
Greg Claytona1743492012-03-13 23:14:29 +00005042 ConstString text_segment_name ("__TEXT");
5043 uint64_t entryoffset = m_data.GetU64(&offset);
5044 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
5045 if (text_segment_sp)
5046 {
5047 done = true;
5048 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5049 }
Sean Callanan226b70c2012-03-08 02:39:03 +00005050 }
Greg Claytona1743492012-03-13 23:14:29 +00005051
5052 default:
5053 break;
Sean Callanan226b70c2012-03-08 02:39:03 +00005054 }
Greg Claytona1743492012-03-13 23:14:29 +00005055 if (done)
5056 break;
Jim Ingham672e6f52011-03-07 23:44:08 +00005057
Greg Claytona1743492012-03-13 23:14:29 +00005058 // Go to the next load command:
5059 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham672e6f52011-03-07 23:44:08 +00005060 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005061
Greg Claytona1743492012-03-13 23:14:29 +00005062 if (start_address != LLDB_INVALID_ADDRESS)
Greg Claytone72dfb32012-02-24 01:59:29 +00005063 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00005064 // We got the start address from the load commands, so now resolve that address in the sections
Greg Claytona1743492012-03-13 23:14:29 +00005065 // of this ObjectFile:
5066 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Claytone72dfb32012-02-24 01:59:29 +00005067 {
Greg Claytona1743492012-03-13 23:14:29 +00005068 m_entry_point_address.Clear();
5069 }
5070 }
5071 else
5072 {
5073 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
5074 // "start" symbol in the main executable.
Jason Molenda4e7511e2013-03-06 23:19:17 +00005075
Greg Claytona1743492012-03-13 23:14:29 +00005076 ModuleSP module_sp (GetModule());
Jason Molenda4e7511e2013-03-06 23:19:17 +00005077
Greg Claytona1743492012-03-13 23:14:29 +00005078 if (module_sp)
5079 {
5080 SymbolContextList contexts;
5081 SymbolContext context;
5082 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
5083 {
5084 if (contexts.GetContextAtIndex(0, context))
5085 m_entry_point_address = context.symbol->GetAddress();
5086 }
Greg Claytone72dfb32012-02-24 01:59:29 +00005087 }
5088 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005089 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005090
Jim Ingham672e6f52011-03-07 23:44:08 +00005091 return m_entry_point_address;
5092
5093}
5094
Greg Claytonc9660542012-02-05 02:38:54 +00005095lldb_private::Address
5096ObjectFileMachO::GetHeaderAddress ()
5097{
5098 lldb_private::Address header_addr;
5099 SectionList *section_list = GetSectionList();
5100 if (section_list)
5101 {
5102 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
5103 if (text_segment_sp)
5104 {
Greg Claytone72dfb32012-02-24 01:59:29 +00005105 header_addr.SetSection (text_segment_sp);
Greg Claytonc9660542012-02-05 02:38:54 +00005106 header_addr.SetOffset (0);
5107 }
5108 }
5109 return header_addr;
5110}
5111
Greg Claytonc3776bf2012-02-09 06:16:32 +00005112uint32_t
5113ObjectFileMachO::GetNumThreadContexts ()
5114{
Greg Claytona1743492012-03-13 23:14:29 +00005115 ModuleSP module_sp(GetModule());
5116 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005117 {
Greg Claytona1743492012-03-13 23:14:29 +00005118 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5119 if (!m_thread_context_offsets_valid)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005120 {
Greg Claytona1743492012-03-13 23:14:29 +00005121 m_thread_context_offsets_valid = true;
Greg Claytonc7bece562013-01-25 18:06:21 +00005122 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005123 FileRangeArray::Entry file_range;
5124 thread_command thread_cmd;
5125 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005126 {
Greg Claytona1743492012-03-13 23:14:29 +00005127 const uint32_t cmd_offset = offset;
5128 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
5129 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005130
Charles Davis510938e2013-08-27 05:04:57 +00005131 if (thread_cmd.cmd == LC_THREAD)
Greg Claytona1743492012-03-13 23:14:29 +00005132 {
5133 file_range.SetRangeBase (offset);
5134 file_range.SetByteSize (thread_cmd.cmdsize - 8);
5135 m_thread_context_offsets.Append (file_range);
5136 }
5137 offset = cmd_offset + thread_cmd.cmdsize;
Greg Claytonc3776bf2012-02-09 06:16:32 +00005138 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00005139 }
5140 }
5141 return m_thread_context_offsets.GetSize();
5142}
5143
5144lldb::RegisterContextSP
5145ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
5146{
Greg Claytonc3776bf2012-02-09 06:16:32 +00005147 lldb::RegisterContextSP reg_ctx_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +00005148
Greg Claytona1743492012-03-13 23:14:29 +00005149 ModuleSP module_sp(GetModule());
5150 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005151 {
Greg Claytona1743492012-03-13 23:14:29 +00005152 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5153 if (!m_thread_context_offsets_valid)
5154 GetNumThreadContexts ();
5155
5156 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
Jim Ingham28eb5712012-10-12 17:34:26 +00005157 if (thread_context_file_range)
Greg Claytona1743492012-03-13 23:14:29 +00005158 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00005159
5160 DataExtractor data (m_data,
5161 thread_context_file_range->GetRangeBase(),
Jim Ingham28eb5712012-10-12 17:34:26 +00005162 thread_context_file_range->GetByteSize());
5163
5164 switch (m_header.cputype)
5165 {
Jason Molendaa3329782014-03-29 18:54:20 +00005166 case llvm::MachO::CPU_TYPE_ARM64:
5167 reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
5168 break;
5169
Charles Davis510938e2013-08-27 05:04:57 +00005170 case llvm::MachO::CPU_TYPE_ARM:
Jim Ingham28eb5712012-10-12 17:34:26 +00005171 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
5172 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005173
Charles Davis510938e2013-08-27 05:04:57 +00005174 case llvm::MachO::CPU_TYPE_I386:
Jim Ingham28eb5712012-10-12 17:34:26 +00005175 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
5176 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005177
Charles Davis510938e2013-08-27 05:04:57 +00005178 case llvm::MachO::CPU_TYPE_X86_64:
Jim Ingham28eb5712012-10-12 17:34:26 +00005179 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
5180 break;
5181 }
Greg Claytona1743492012-03-13 23:14:29 +00005182 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00005183 }
5184 return reg_ctx_sp;
5185}
5186
Greg Claytonc9660542012-02-05 02:38:54 +00005187
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005188ObjectFile::Type
5189ObjectFileMachO::CalculateType()
5190{
5191 switch (m_header.filetype)
5192 {
Charles Davis510938e2013-08-27 05:04:57 +00005193 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005194 if (GetAddressByteSize () == 4)
5195 {
5196 // 32 bit kexts are just object files, but they do have a valid
5197 // UUID load command.
5198 UUID uuid;
5199 if (GetUUID(&uuid))
5200 {
5201 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00005202 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005203 // "OSKextGetCurrentIdentifier" as this is required of kexts
5204 if (m_strata == eStrataInvalid)
5205 m_strata = eStrataKernel;
5206 return eTypeSharedLibrary;
5207 }
5208 }
5209 return eTypeObjectFile;
5210
Charles Davis510938e2013-08-27 05:04:57 +00005211 case MH_EXECUTE: return eTypeExecutable; // 0x2u
5212 case MH_FVMLIB: return eTypeSharedLibrary; // 0x3u
5213 case MH_CORE: return eTypeCoreFile; // 0x4u
5214 case MH_PRELOAD: return eTypeSharedLibrary; // 0x5u
5215 case MH_DYLIB: return eTypeSharedLibrary; // 0x6u
5216 case MH_DYLINKER: return eTypeDynamicLinker; // 0x7u
5217 case MH_BUNDLE: return eTypeSharedLibrary; // 0x8u
5218 case MH_DYLIB_STUB: return eTypeStubLibrary; // 0x9u
5219 case MH_DSYM: return eTypeDebugInfo; // 0xAu
5220 case MH_KEXT_BUNDLE: return eTypeSharedLibrary; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005221 default:
5222 break;
5223 }
5224 return eTypeUnknown;
5225}
5226
5227ObjectFile::Strata
5228ObjectFileMachO::CalculateStrata()
5229{
5230 switch (m_header.filetype)
5231 {
Charles Davis510938e2013-08-27 05:04:57 +00005232 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005233 {
5234 // 32 bit kexts are just object files, but they do have a valid
5235 // UUID load command.
5236 UUID uuid;
5237 if (GetUUID(&uuid))
5238 {
5239 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00005240 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005241 // "OSKextGetCurrentIdentifier" as this is required of kexts
5242 if (m_type == eTypeInvalid)
5243 m_type = eTypeSharedLibrary;
5244
5245 return eStrataKernel;
5246 }
5247 }
5248 return eStrataUnknown;
5249
Charles Davis510938e2013-08-27 05:04:57 +00005250 case MH_EXECUTE: // 0x2u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005251 // Check for the MH_DYLDLINK bit in the flags
Charles Davis510938e2013-08-27 05:04:57 +00005252 if (m_header.flags & MH_DYLDLINK)
Sean Callanan49bce8e2012-02-10 20:22:35 +00005253 {
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005254 return eStrataUser;
Sean Callanan49bce8e2012-02-10 20:22:35 +00005255 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005256 else
Sean Callanan49bce8e2012-02-10 20:22:35 +00005257 {
5258 SectionList *section_list = GetSectionList();
5259 if (section_list)
5260 {
5261 static ConstString g_kld_section_name ("__KLD");
5262 if (section_list->FindSectionByName(g_kld_section_name))
5263 return eStrataKernel;
5264 }
5265 }
5266 return eStrataRawImage;
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005267
Charles Davis510938e2013-08-27 05:04:57 +00005268 case MH_FVMLIB: return eStrataUser; // 0x3u
5269 case MH_CORE: return eStrataUnknown; // 0x4u
5270 case MH_PRELOAD: return eStrataRawImage; // 0x5u
5271 case MH_DYLIB: return eStrataUser; // 0x6u
5272 case MH_DYLINKER: return eStrataUser; // 0x7u
5273 case MH_BUNDLE: return eStrataUser; // 0x8u
5274 case MH_DYLIB_STUB: return eStrataUser; // 0x9u
5275 case MH_DSYM: return eStrataUnknown; // 0xAu
5276 case MH_KEXT_BUNDLE: return eStrataKernel; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005277 default:
5278 break;
5279 }
5280 return eStrataUnknown;
5281}
5282
5283
Greg Claytonc2ff9312012-02-22 19:41:02 +00005284uint32_t
5285ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
5286{
Greg Claytona1743492012-03-13 23:14:29 +00005287 ModuleSP module_sp(GetModule());
5288 if (module_sp)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005289 {
Greg Claytona1743492012-03-13 23:14:29 +00005290 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5291 struct dylib_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00005292 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005293 uint32_t version_cmd = 0;
5294 uint64_t version = 0;
5295 uint32_t i;
5296 for (i=0; i<m_header.ncmds; ++i)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005297 {
Greg Claytonc7bece562013-01-25 18:06:21 +00005298 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00005299 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
5300 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005301
Charles Davis510938e2013-08-27 05:04:57 +00005302 if (load_cmd.cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005303 {
Greg Claytona1743492012-03-13 23:14:29 +00005304 if (version_cmd == 0)
5305 {
5306 version_cmd = load_cmd.cmd;
5307 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
5308 break;
5309 version = load_cmd.dylib.current_version;
5310 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005311 break; // Break for now unless there is another more complete version
Greg Claytona1743492012-03-13 23:14:29 +00005312 // number load command in the future.
Greg Claytonc2ff9312012-02-22 19:41:02 +00005313 }
Greg Claytona1743492012-03-13 23:14:29 +00005314 offset = cmd_offset + load_cmd.cmdsize;
Greg Claytonc2ff9312012-02-22 19:41:02 +00005315 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005316
Charles Davis510938e2013-08-27 05:04:57 +00005317 if (version_cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005318 {
Greg Claytona1743492012-03-13 23:14:29 +00005319 if (versions != NULL && num_versions > 0)
5320 {
5321 if (num_versions > 0)
5322 versions[0] = (version & 0xFFFF0000ull) >> 16;
5323 if (num_versions > 1)
5324 versions[1] = (version & 0x0000FF00ull) >> 8;
5325 if (num_versions > 2)
5326 versions[2] = (version & 0x000000FFull);
5327 // Fill in an remaining version numbers with invalid values
5328 for (i=3; i<num_versions; ++i)
5329 versions[i] = UINT32_MAX;
5330 }
5331 // The LC_ID_DYLIB load command has a version with 3 version numbers
5332 // in it, so always return 3
5333 return 3;
Greg Claytonc2ff9312012-02-22 19:41:02 +00005334 }
Greg Claytonc2ff9312012-02-22 19:41:02 +00005335 }
5336 return false;
5337}
5338
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005339bool
Greg Clayton514487e2011-02-15 21:59:32 +00005340ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005341{
Greg Claytona1743492012-03-13 23:14:29 +00005342 ModuleSP module_sp(GetModule());
5343 if (module_sp)
Greg Clayton593577a2011-09-21 03:57:31 +00005344 {
Greg Claytona1743492012-03-13 23:14:29 +00005345 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Clayton7ab7f892014-05-29 21:33:45 +00005346 return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch);
Greg Clayton593577a2011-09-21 03:57:31 +00005347 }
Greg Claytona1743492012-03-13 23:14:29 +00005348 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005349}
5350
5351
Jason Molenda0e0954c2013-04-16 06:24:42 +00005352UUID
5353ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
5354{
5355 UUID uuid;
5356 if (process)
5357 {
5358 addr_t all_image_infos = process->GetImageInfoAddress();
5359
5360 // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
5361 // or it may be the address of the dyld_all_image_infos structure (want). The first four
5362 // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
5363 // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
5364
5365 Error err;
5366 uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00005367 if (version_or_magic != static_cast<uint32_t>(-1)
Charles Davis510938e2013-08-27 05:04:57 +00005368 && version_or_magic != MH_MAGIC
5369 && version_or_magic != MH_CIGAM
5370 && version_or_magic != MH_MAGIC_64
5371 && version_or_magic != MH_CIGAM_64
Jason Molenda0e0954c2013-04-16 06:24:42 +00005372 && version_or_magic >= 13)
5373 {
5374 addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
5375 int wordsize = process->GetAddressByteSize();
5376 if (wordsize == 8)
5377 {
5378 sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
5379 }
5380 if (wordsize == 4)
5381 {
5382 sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
5383 }
5384 if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
5385 {
5386 uuid_t shared_cache_uuid;
5387 if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
5388 {
5389 uuid.SetBytes (shared_cache_uuid);
5390 }
5391 }
5392 }
5393 }
5394 return uuid;
5395}
5396
5397UUID
5398ObjectFileMachO::GetLLDBSharedCacheUUID ()
5399{
5400 UUID uuid;
Todd Fiala013434e2014-07-09 01:29:05 +00005401#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +00005402 uint8_t *(*dyld_get_all_image_infos)(void);
5403 dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
5404 if (dyld_get_all_image_infos)
5405 {
5406 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5407 if (dyld_all_image_infos_address)
5408 {
Jason Molendac9cb7d22013-04-16 21:42:58 +00005409 uint32_t *version = (uint32_t*) dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5410 if (*version >= 13)
Jason Molenda0e0954c2013-04-16 06:24:42 +00005411 {
Jason Molendaa3329782014-03-29 18:54:20 +00005412 uuid_t *sharedCacheUUID_address = 0;
5413 int wordsize = sizeof (uint8_t *);
5414 if (wordsize == 8)
5415 {
5416 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
5417 }
5418 else
5419 {
5420 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84); // sharedCacheUUID <mach-o/dyld_images.h>
5421 }
Jason Molenda0e0954c2013-04-16 06:24:42 +00005422 uuid.SetBytes (sharedCacheUUID_address);
5423 }
5424 }
5425 }
5426#endif
5427 return uuid;
5428}
5429
Greg Clayton9b234982013-10-24 22:54:08 +00005430uint32_t
5431ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
5432{
5433 if (m_min_os_versions.empty())
5434 {
5435 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5436 bool success = false;
5437 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5438 {
5439 const lldb::offset_t load_cmd_offset = offset;
5440
5441 version_min_command lc;
5442 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5443 break;
5444 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5445 {
5446 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5447 {
5448 const uint32_t xxxx = lc.version >> 16;
5449 const uint32_t yy = (lc.version >> 8) & 0xffu;
5450 const uint32_t zz = lc.version & 0xffu;
5451 if (xxxx)
5452 {
5453 m_min_os_versions.push_back(xxxx);
Greg Clayton8031d282015-02-04 00:40:25 +00005454 m_min_os_versions.push_back(yy);
5455 m_min_os_versions.push_back(zz);
Greg Clayton9b234982013-10-24 22:54:08 +00005456 }
5457 success = true;
5458 }
5459 }
5460 offset = load_cmd_offset + lc.cmdsize;
5461 }
5462
5463 if (success == false)
5464 {
5465 // Push an invalid value so we don't keep trying to
5466 m_min_os_versions.push_back(UINT32_MAX);
5467 }
5468 }
5469
5470 if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
5471 {
5472 if (versions != NULL && num_versions > 0)
5473 {
5474 for (size_t i=0; i<num_versions; ++i)
5475 {
5476 if (i < m_min_os_versions.size())
5477 versions[i] = m_min_os_versions[i];
5478 else
5479 versions[i] = 0;
5480 }
5481 }
5482 return m_min_os_versions.size();
5483 }
5484 // Call the superclasses version that will empty out the data
5485 return ObjectFile::GetMinimumOSVersion (versions, num_versions);
5486}
5487
5488uint32_t
5489ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions)
5490{
5491 if (m_sdk_versions.empty())
5492 {
5493 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5494 bool success = false;
5495 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5496 {
5497 const lldb::offset_t load_cmd_offset = offset;
5498
5499 version_min_command lc;
5500 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5501 break;
5502 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5503 {
5504 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5505 {
Todd Fialaebecb382014-09-04 19:31:52 +00005506 const uint32_t xxxx = lc.sdk >> 16;
5507 const uint32_t yy = (lc.sdk >> 8) & 0xffu;
5508 const uint32_t zz = lc.sdk & 0xffu;
Greg Clayton9b234982013-10-24 22:54:08 +00005509 if (xxxx)
5510 {
5511 m_sdk_versions.push_back(xxxx);
Greg Clayton8031d282015-02-04 00:40:25 +00005512 m_sdk_versions.push_back(yy);
5513 m_sdk_versions.push_back(zz);
Greg Clayton9b234982013-10-24 22:54:08 +00005514 }
5515 success = true;
5516 }
5517 }
5518 offset = load_cmd_offset + lc.cmdsize;
5519 }
5520
5521 if (success == false)
5522 {
5523 // Push an invalid value so we don't keep trying to
5524 m_sdk_versions.push_back(UINT32_MAX);
5525 }
5526 }
5527
5528 if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
5529 {
5530 if (versions != NULL && num_versions > 0)
5531 {
5532 for (size_t i=0; i<num_versions; ++i)
5533 {
5534 if (i < m_sdk_versions.size())
5535 versions[i] = m_sdk_versions[i];
5536 else
5537 versions[i] = 0;
5538 }
5539 }
5540 return m_sdk_versions.size();
5541 }
5542 // Call the superclasses version that will empty out the data
5543 return ObjectFile::GetSDKVersion (versions, num_versions);
5544}
5545
Jason Molenda0e0954c2013-04-16 06:24:42 +00005546
Greg Clayton08928f32015-02-05 02:01:34 +00005547bool
5548ObjectFileMachO::GetIsDynamicLinkEditor()
5549{
5550 return m_header.filetype == llvm::MachO::MH_DYLINKER;
5551}
5552
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005553//------------------------------------------------------------------
5554// PluginInterface protocol
5555//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00005556lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005557ObjectFileMachO::GetPluginName()
5558{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005559 return GetPluginNameStatic();
5560}
5561
5562uint32_t
5563ObjectFileMachO::GetPluginVersion()
5564{
5565 return 1;
5566}
5567
Greg Clayton7524e092014-02-06 20:10:16 +00005568
Greg Clayton07347372015-06-08 21:53:11 +00005569Section *
5570ObjectFileMachO::GetMachHeaderSection()
5571{
5572 // Find the first address of the mach header which is the first non-zero
5573 // file sized section whose file offset is zero. This is the base file address
5574 // of the mach-o file which can be subtracted from the vmaddr of the other
5575 // segments found in memory and added to the load address
5576 ModuleSP module_sp = GetModule();
5577 if (module_sp)
5578 {
5579 SectionList *section_list = GetSectionList ();
5580 if (section_list)
5581 {
5582 lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
5583 const size_t num_sections = section_list->GetSize();
5584
5585 for (size_t sect_idx = 0;
5586 sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
5587 ++sect_idx)
5588 {
5589 Section *section = section_list->GetSectionAtIndex (sect_idx).get();
5590 if (section &&
5591 section->GetFileSize() > 0 &&
5592 section->GetFileOffset() == 0 &&
5593 section->IsThreadSpecific() == false &&
5594 module_sp.get() == section->GetModule().get())
5595 {
5596 return section;
5597 }
5598 }
5599 }
5600 }
5601 return nullptr;
5602}
5603
5604lldb::addr_t
5605ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const Section *mach_header_section, const Section *section)
5606{
5607 ModuleSP module_sp = GetModule();
5608 if (module_sp && mach_header_section && section && mach_header_load_address != LLDB_INVALID_ADDRESS)
5609 {
5610 lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
5611 if (mach_header_file_addr != LLDB_INVALID_ADDRESS)
5612 {
5613 if (section &&
5614 section->GetFileSize() > 0 &&
5615 section->IsThreadSpecific() == false &&
5616 module_sp.get() == section->GetModule().get())
5617 {
5618 // Ignore __LINKEDIT and __DWARF segments
5619 if (section->GetName() == GetSegmentNameLINKEDIT())
5620 {
5621 // Only map __LINKEDIT if we have an in memory image and this isn't
5622 // a kernel binary like a kext or mach_kernel.
5623 const bool is_memory_image = (bool)m_process_wp.lock();
5624 const Strata strata = GetStrata();
5625 if (is_memory_image == false || strata == eStrataKernel)
5626 return LLDB_INVALID_ADDRESS;
5627 }
5628 return section->GetFileAddress() - mach_header_file_addr + mach_header_load_address;
5629 }
5630 }
5631 }
5632 return LLDB_INVALID_ADDRESS;
5633}
5634
Greg Clayton7524e092014-02-06 20:10:16 +00005635bool
Greg Clayton751caf62014-02-07 22:54:47 +00005636ObjectFileMachO::SetLoadAddress (Target &target,
5637 lldb::addr_t value,
5638 bool value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005639{
Greg Clayton7524e092014-02-06 20:10:16 +00005640 ModuleSP module_sp = GetModule();
5641 if (module_sp)
5642 {
5643 size_t num_loaded_sections = 0;
5644 SectionList *section_list = GetSectionList ();
5645 if (section_list)
5646 {
Greg Clayton7524e092014-02-06 20:10:16 +00005647 const size_t num_sections = section_list->GetSize();
5648
Greg Clayton751caf62014-02-07 22:54:47 +00005649 if (value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005650 {
Greg Clayton751caf62014-02-07 22:54:47 +00005651 // "value" is an offset to apply to each top level segment
Greg Clayton7524e092014-02-06 20:10:16 +00005652 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5653 {
5654 // Iterate through the object file sections to find all
5655 // of the sections that size on disk (to avoid __PAGEZERO)
5656 // and load them
5657 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton751caf62014-02-07 22:54:47 +00005658 if (section_sp &&
5659 section_sp->GetFileSize() > 0 &&
5660 section_sp->IsThreadSpecific() == false &&
5661 module_sp.get() == section_sp->GetModule().get())
Greg Clayton7524e092014-02-06 20:10:16 +00005662 {
Greg Clayton751caf62014-02-07 22:54:47 +00005663 // Ignore __LINKEDIT and __DWARF segments
Greg Clayton07347372015-06-08 21:53:11 +00005664 if (section_sp->GetName() == GetSegmentNameLINKEDIT())
Greg Clayton751caf62014-02-07 22:54:47 +00005665 {
5666 // Only map __LINKEDIT if we have an in memory image and this isn't
5667 // a kernel binary like a kext or mach_kernel.
Greg Clayton07347372015-06-08 21:53:11 +00005668 const bool is_memory_image = (bool)m_process_wp.lock();
5669 const Strata strata = GetStrata();
Greg Clayton751caf62014-02-07 22:54:47 +00005670 if (is_memory_image == false || strata == eStrataKernel)
5671 continue;
5672 }
5673 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
Greg Clayton7524e092014-02-06 20:10:16 +00005674 ++num_loaded_sections;
5675 }
5676 }
5677 }
Greg Clayton751caf62014-02-07 22:54:47 +00005678 else
5679 {
5680 // "value" is the new base address of the mach_header, adjust each
5681 // section accordingly
5682
Greg Clayton07347372015-06-08 21:53:11 +00005683 Section *mach_header_section = GetMachHeaderSection();
5684 if (mach_header_section)
Greg Clayton751caf62014-02-07 22:54:47 +00005685 {
5686 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5687 {
Greg Clayton751caf62014-02-07 22:54:47 +00005688 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton07347372015-06-08 21:53:11 +00005689
5690 lldb::addr_t section_load_addr = CalculateSectionLoadAddressForMemoryImage(value, mach_header_section, section_sp.get());
5691 if (section_load_addr != LLDB_INVALID_ADDRESS)
Greg Clayton751caf62014-02-07 22:54:47 +00005692 {
Greg Clayton07347372015-06-08 21:53:11 +00005693 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_load_addr))
Greg Clayton751caf62014-02-07 22:54:47 +00005694 ++num_loaded_sections;
5695 }
5696 }
5697 }
5698 }
Greg Clayton7524e092014-02-06 20:10:16 +00005699 }
Greg Clayton7524e092014-02-06 20:10:16 +00005700 return num_loaded_sections > 0;
5701 }
Jason Molenda5cf1e232014-10-16 07:41:32 +00005702 return false;
Greg Clayton7524e092014-02-06 20:10:16 +00005703}
5704
Greg Claytona2715cf2014-06-13 00:54:12 +00005705bool
5706ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp,
5707 const FileSpec &outfile,
5708 Error &error)
5709{
5710 if (process_sp)
5711 {
5712 Target &target = process_sp->GetTarget();
5713 const ArchSpec target_arch = target.GetArchitecture();
5714 const llvm::Triple &target_triple = target_arch.GetTriple();
5715 if (target_triple.getVendor() == llvm::Triple::Apple &&
5716 (target_triple.getOS() == llvm::Triple::MacOSX ||
5717 target_triple.getOS() == llvm::Triple::IOS))
5718 {
5719 bool make_core = false;
5720 switch (target_arch.GetMachine())
5721 {
Jason Molenda16dc86d2015-06-25 23:58:25 +00005722 case llvm::Triple::aarch64:
Jason Molenda4b0c1182014-11-12 02:39:14 +00005723 case llvm::Triple::arm:
Greg Claytona2715cf2014-06-13 00:54:12 +00005724 case llvm::Triple::x86:
5725 case llvm::Triple::x86_64:
5726 make_core = true;
5727 break;
5728 default:
5729 error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str());
5730 break;
5731 }
5732
5733 if (make_core)
5734 {
5735 std::vector<segment_command_64> segment_load_commands;
Saleem Abdulrasool3924d752014-06-13 03:30:39 +00005736// uint32_t range_info_idx = 0;
Greg Claytona2715cf2014-06-13 00:54:12 +00005737 MemoryRegionInfo range_info;
5738 Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
Jason Molendad20359d2014-11-11 10:59:15 +00005739 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
5740 const ByteOrder byte_order = target_arch.GetByteOrder();
Greg Claytona2715cf2014-06-13 00:54:12 +00005741 if (range_error.Success())
5742 {
5743 while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS)
5744 {
5745 const addr_t addr = range_info.GetRange().GetRangeBase();
5746 const addr_t size = range_info.GetRange().GetByteSize();
5747
5748 if (size == 0)
5749 break;
5750
5751 // Calculate correct protections
5752 uint32_t prot = 0;
5753 if (range_info.GetReadable() == MemoryRegionInfo::eYes)
5754 prot |= VM_PROT_READ;
5755 if (range_info.GetWritable() == MemoryRegionInfo::eYes)
5756 prot |= VM_PROT_WRITE;
5757 if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
5758 prot |= VM_PROT_EXECUTE;
5759
5760// printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n",
5761// range_info_idx,
5762// addr,
5763// size,
5764// (prot & VM_PROT_READ ) ? 'r' : '-',
5765// (prot & VM_PROT_WRITE ) ? 'w' : '-',
5766// (prot & VM_PROT_EXECUTE) ? 'x' : '-');
5767
5768 if (prot != 0)
5769 {
Jason Molendad20359d2014-11-11 10:59:15 +00005770 uint32_t cmd_type = LC_SEGMENT_64;
5771 uint32_t segment_size = sizeof (segment_command_64);
5772 if (addr_byte_size == 4)
5773 {
5774 cmd_type = LC_SEGMENT;
5775 segment_size = sizeof (segment_command);
5776 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005777 segment_command_64 segment = {
Jason Molendad20359d2014-11-11 10:59:15 +00005778 cmd_type, // uint32_t cmd;
5779 segment_size, // uint32_t cmdsize;
Greg Claytona2715cf2014-06-13 00:54:12 +00005780 {0}, // char segname[16];
Jason Molendad20359d2014-11-11 10:59:15 +00005781 addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
5782 size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
5783 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
5784 size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
Greg Claytona2715cf2014-06-13 00:54:12 +00005785 prot, // uint32_t maxprot;
5786 prot, // uint32_t initprot;
5787 0, // uint32_t nsects;
5788 0 }; // uint32_t flags;
5789 segment_load_commands.push_back(segment);
5790 }
5791 else
5792 {
5793 // No protections and a size of 1 used to be returned from old
5794 // debugservers when we asked about a region that was past the
5795 // last memory region and it indicates the end...
5796 if (size == 1)
5797 break;
5798 }
5799
5800 range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info);
5801 if (range_error.Fail())
5802 break;
5803 }
5804
Greg Claytona2715cf2014-06-13 00:54:12 +00005805 StreamString buffer (Stream::eBinary,
5806 addr_byte_size,
5807 byte_order);
5808
5809 mach_header_64 mach_header;
Jason Molendad20359d2014-11-11 10:59:15 +00005810 if (addr_byte_size == 8)
5811 {
5812 mach_header.magic = MH_MAGIC_64;
5813 }
5814 else
5815 {
5816 mach_header.magic = MH_MAGIC;
5817 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005818 mach_header.cputype = target_arch.GetMachOCPUType();
5819 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
5820 mach_header.filetype = MH_CORE;
5821 mach_header.ncmds = segment_load_commands.size();
5822 mach_header.flags = 0;
5823 mach_header.reserved = 0;
5824 ThreadList &thread_list = process_sp->GetThreadList();
5825 const uint32_t num_threads = thread_list.GetSize();
5826
5827 // Make an array of LC_THREAD data items. Each one contains
5828 // the contents of the LC_THREAD load command. The data doesn't
5829 // contain the load command + load command size, we will
5830 // add the load command and load command size as we emit the data.
5831 std::vector<StreamString> LC_THREAD_datas(num_threads);
5832 for (auto &LC_THREAD_data : LC_THREAD_datas)
5833 {
5834 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
5835 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
5836 LC_THREAD_data.SetByteOrder(byte_order);
5837 }
5838 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
5839 {
5840 ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx));
5841 if (thread_sp)
5842 {
5843 switch (mach_header.cputype)
5844 {
Jason Molenda22952582014-11-12 01:11:36 +00005845 case llvm::MachO::CPU_TYPE_ARM64:
5846 RegisterContextDarwin_arm64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005847 break;
Jason Molenda22952582014-11-12 01:11:36 +00005848
5849 case llvm::MachO::CPU_TYPE_ARM:
5850 RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5851 break;
5852
Greg Claytona2715cf2014-06-13 00:54:12 +00005853 case llvm::MachO::CPU_TYPE_I386:
Jason Molendad20359d2014-11-11 10:59:15 +00005854 RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005855 break;
5856
5857 case llvm::MachO::CPU_TYPE_X86_64:
5858 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5859 break;
5860 }
5861
5862 }
5863 }
5864
5865 // The size of the load command is the size of the segments...
Jason Molendad20359d2014-11-11 10:59:15 +00005866 if (addr_byte_size == 8)
5867 {
5868 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64);
5869 }
5870 else
5871 {
5872 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command);
5873 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005874
5875 // and the size of all LC_THREAD load command
5876 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5877 {
Greg Claytone37df2e2014-09-16 20:50:29 +00005878 ++mach_header.ncmds;
Greg Claytona2715cf2014-06-13 00:54:12 +00005879 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
5880 }
5881
5882 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",
5883 mach_header.magic,
5884 mach_header.cputype,
5885 mach_header.cpusubtype,
5886 mach_header.filetype,
5887 mach_header.ncmds,
5888 mach_header.sizeofcmds,
5889 mach_header.flags,
5890 mach_header.reserved);
5891
5892 // Write the mach header
5893 buffer.PutHex32(mach_header.magic);
5894 buffer.PutHex32(mach_header.cputype);
5895 buffer.PutHex32(mach_header.cpusubtype);
5896 buffer.PutHex32(mach_header.filetype);
5897 buffer.PutHex32(mach_header.ncmds);
5898 buffer.PutHex32(mach_header.sizeofcmds);
5899 buffer.PutHex32(mach_header.flags);
Jason Molendad20359d2014-11-11 10:59:15 +00005900 if (addr_byte_size == 8)
5901 {
5902 buffer.PutHex32(mach_header.reserved);
5903 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005904
5905 // Skip the mach header and all load commands and align to the next
5906 // 0x1000 byte boundary
5907 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
5908 if (file_offset & 0x00000fff)
5909 {
5910 file_offset += 0x00001000ull;
5911 file_offset &= (~0x00001000ull + 1);
5912 }
5913
5914 for (auto &segment : segment_load_commands)
5915 {
5916 segment.fileoff = file_offset;
5917 file_offset += segment.filesize;
5918 }
5919
5920 // Write out all of the LC_THREAD load commands
5921 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5922 {
5923 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
5924 buffer.PutHex32(LC_THREAD);
5925 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
5926 buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size);
5927 }
5928
5929 // Write out all of the segment load commands
5930 for (const auto &segment : segment_load_commands)
5931 {
5932 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",
5933 segment.cmd,
5934 segment.cmdsize,
5935 segment.vmaddr,
5936 segment.vmaddr + segment.vmsize,
5937 segment.fileoff,
5938 segment.filesize,
5939 segment.maxprot,
5940 segment.initprot,
5941 segment.nsects,
5942 segment.flags);
5943
5944 buffer.PutHex32(segment.cmd);
5945 buffer.PutHex32(segment.cmdsize);
5946 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
Jason Molendad20359d2014-11-11 10:59:15 +00005947 if (addr_byte_size == 8)
5948 {
5949 buffer.PutHex64(segment.vmaddr);
5950 buffer.PutHex64(segment.vmsize);
5951 buffer.PutHex64(segment.fileoff);
5952 buffer.PutHex64(segment.filesize);
5953 }
5954 else
5955 {
5956 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
5957 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
5958 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
5959 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
5960 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005961 buffer.PutHex32(segment.maxprot);
5962 buffer.PutHex32(segment.initprot);
5963 buffer.PutHex32(segment.nsects);
5964 buffer.PutHex32(segment.flags);
5965 }
5966
5967 File core_file;
5968 std::string core_file_path(outfile.GetPath());
5969 error = core_file.Open(core_file_path.c_str(),
5970 File::eOpenOptionWrite |
5971 File::eOpenOptionTruncate |
5972 File::eOpenOptionCanCreate);
5973 if (error.Success())
5974 {
5975 // Read 1 page at a time
5976 uint8_t bytes[0x1000];
5977 // Write the mach header and load commands out to the core file
5978 size_t bytes_written = buffer.GetString().size();
5979 error = core_file.Write(buffer.GetString().data(), bytes_written);
5980 if (error.Success())
5981 {
5982 // Now write the file data for all memory segments in the process
5983 for (const auto &segment : segment_load_commands)
5984 {
David Majnemerb98a5e02014-07-24 00:24:12 +00005985 if (core_file.SeekFromStart(segment.fileoff) == -1)
Greg Claytona2715cf2014-06-13 00:54:12 +00005986 {
5987 error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str());
5988 break;
5989 }
5990
Jason Molendad20359d2014-11-11 10:59:15 +00005991 printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr);
Greg Claytona2715cf2014-06-13 00:54:12 +00005992 addr_t bytes_left = segment.vmsize;
5993 addr_t addr = segment.vmaddr;
5994 Error memory_read_error;
5995 while (bytes_left > 0 && error.Success())
5996 {
5997 const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
5998 const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error);
5999 if (bytes_read == bytes_to_read)
6000 {
6001 size_t bytes_written = bytes_read;
6002 error = core_file.Write(bytes, bytes_written);
6003 bytes_left -= bytes_read;
6004 addr += bytes_read;
6005 }
6006 else
6007 {
6008 // Some pages within regions are not readable, those
6009 // should be zero filled
6010 memset (bytes, 0, bytes_to_read);
6011 size_t bytes_written = bytes_to_read;
6012 error = core_file.Write(bytes, bytes_written);
6013 bytes_left -= bytes_to_read;
6014 addr += bytes_to_read;
6015 }
6016 }
6017 }
6018 }
6019 }
6020 }
6021 else
6022 {
6023 error.SetErrorString("process doesn't support getting memory region info");
6024 }
6025 }
6026 return true; // This is the right plug to handle saving core files for this process
6027 }
6028 }
6029 return false;
6030}
6031