blob: 40e370bb92ab03c6acece08cf41eaa16424ad590 [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
Eugene Zelenko8157a882015-10-23 16:56:07 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
Jim Ingham46d005d2014-04-02 22:53:21 +000013#include "llvm/ADT/StringRef.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014
Eugene Zelenko8157a882015-10-23 16:56:07 +000015// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/ArchSpec.h"
17#include "lldb/Core/DataBuffer.h"
Jason Molendaf6ce26f2013-04-10 05:58:57 +000018#include "lldb/Core/Debugger.h"
Greg Claytona2715cf2014-06-13 00:54:12 +000019#include "lldb/Core/Error.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/FileSpecList.h"
Greg Clayton3f839a32012-09-05 01:38:55 +000021#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/Module.h"
Greg Claytonf4d6de62013-04-24 22:29:28 +000023#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/PluginManager.h"
Greg Clayton1eac0c72012-04-24 03:06:13 +000025#include "lldb/Core/RangeMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Core/Section.h"
27#include "lldb/Core/StreamFile.h"
28#include "lldb/Core/StreamString.h"
29#include "lldb/Core/Timer.h"
30#include "lldb/Core/UUID.h"
Greg Claytone38a5ed2012-01-05 03:57:59 +000031#include "lldb/Host/Host.h"
32#include "lldb/Host/FileSpec.h"
Jason Molenda5635f772013-03-21 03:36:01 +000033#include "lldb/Symbol/DWARFCallFrameInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Symbol/ObjectFile.h"
Zachary Turner93749ab2015-03-03 21:51:25 +000035#include "lldb/Target/MemoryRegionInfo.h"
Greg Clayton26b47e22012-04-18 05:19:20 +000036#include "lldb/Target/Platform.h"
Greg Claytonc9660542012-02-05 02:38:54 +000037#include "lldb/Target/Process.h"
Greg Clayton7524e092014-02-06 20:10:16 +000038#include "lldb/Target/SectionLoadList.h"
Greg Clayton26b47e22012-04-18 05:19:20 +000039#include "lldb/Target/Target.h"
Greg Claytona2715cf2014-06-13 00:54:12 +000040#include "lldb/Target/Thread.h"
41#include "lldb/Target/ThreadList.h"
Greg Claytonc859e2d2012-02-13 23:10:39 +000042#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
Jason Molendaa3329782014-03-29 18:54:20 +000043#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
Greg Claytonc859e2d2012-02-13 23:10:39 +000044#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
Greg Claytonc3776bf2012-02-09 06:16:32 +000045#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046
Jim Ingham46d005d2014-04-02 22:53:21 +000047#include "lldb/Utility/SafeMachO.h"
48
49#include "ObjectFileMachO.h"
50
Todd Fiala013434e2014-07-09 01:29:05 +000051#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +000052// GetLLDBSharedCacheUUID() needs to call dlsym()
53#include <dlfcn.h>
54#endif
55
Daniel Maleaffeb4b62013-04-17 19:24:22 +000056#ifndef __APPLE__
57#include "Utility/UuidCompatibility.h"
58#endif
59
Greg Claytonb887da12015-07-16 19:50:57 +000060#define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061using namespace lldb;
62using namespace lldb_private;
Greg Claytone1a916a2010-07-21 22:12:05 +000063using namespace llvm::MachO;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064
Jason Molenda4e7511e2013-03-06 23:19:17 +000065class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
Greg Claytonc3776bf2012-02-09 06:16:32 +000066{
67public:
68 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
69 RegisterContextDarwin_x86_64 (thread, 0)
70 {
71 SetRegisterDataFrom_LC_THREAD (data);
72 }
73
Eugene Zelenko8157a882015-10-23 16:56:07 +000074 void
75 InvalidateAllRegisters() override
Greg Claytonc3776bf2012-02-09 06:16:32 +000076 {
77 // Do nothing... registers are always valid...
78 }
79
80 void
81 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
82 {
Greg Claytonc7bece562013-01-25 18:06:21 +000083 lldb::offset_t offset = 0;
Greg Claytonc3776bf2012-02-09 06:16:32 +000084 SetError (GPRRegSet, Read, -1);
85 SetError (FPURegSet, Read, -1);
86 SetError (EXCRegSet, Read, -1);
Greg Claytonc859e2d2012-02-13 23:10:39 +000087 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +000088
Greg Claytonc859e2d2012-02-13 23:10:39 +000089 while (!done)
Greg Claytonc3776bf2012-02-09 06:16:32 +000090 {
Greg Claytonc859e2d2012-02-13 23:10:39 +000091 int flavor = data.GetU32 (&offset);
92 if (flavor == 0)
93 done = true;
94 else
Greg Claytonc3776bf2012-02-09 06:16:32 +000095 {
Greg Claytonc859e2d2012-02-13 23:10:39 +000096 uint32_t i;
97 uint32_t count = data.GetU32 (&offset);
98 switch (flavor)
99 {
100 case GPRRegSet:
101 for (i=0; i<count; ++i)
102 (&gpr.rax)[i] = data.GetU64(&offset);
103 SetError (GPRRegSet, Read, 0);
104 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000105
Greg Claytonc859e2d2012-02-13 23:10:39 +0000106 break;
107 case FPURegSet:
108 // TODO: fill in FPU regs....
109 //SetError (FPURegSet, Read, -1);
110 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000111
Greg Claytonc859e2d2012-02-13 23:10:39 +0000112 break;
113 case EXCRegSet:
114 exc.trapno = data.GetU32(&offset);
115 exc.err = data.GetU32(&offset);
116 exc.faultvaddr = data.GetU64(&offset);
117 SetError (EXCRegSet, Read, 0);
118 done = true;
119 break;
120 case 7:
121 case 8:
122 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000123 // fancy flavors that encapsulate of the above
124 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000125 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000126
Greg Claytonc859e2d2012-02-13 23:10:39 +0000127 default:
128 done = true;
129 break;
130 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000131 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000132 }
133 }
Jason Molendad20359d2014-11-11 10:59:15 +0000134
Greg Claytona2715cf2014-06-13 00:54:12 +0000135 static size_t
136 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
137 {
138 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
139 if (reg_info == NULL)
140 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
141 if (reg_info)
142 {
143 lldb_private::RegisterValue reg_value;
144 if (reg_ctx->ReadRegister(reg_info, reg_value))
145 {
146 if (reg_info->byte_size >= reg_byte_size)
147 data.Write(reg_value.GetBytes(), reg_byte_size);
148 else
149 {
150 data.Write(reg_value.GetBytes(), reg_info->byte_size);
151 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
152 data.PutChar(0);
153 }
154 return reg_byte_size;
155 }
156 }
157 // Just write zeros if all else fails
158 for (size_t i=0; i<reg_byte_size; ++ i)
159 data.PutChar(0);
160 return reg_byte_size;
161 }
Jason Molendad20359d2014-11-11 10:59:15 +0000162
Greg Claytona2715cf2014-06-13 00:54:12 +0000163 static bool
164 Create_LC_THREAD (Thread *thread, Stream &data)
165 {
166 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
167 if (reg_ctx_sp)
168 {
169 RegisterContext *reg_ctx = reg_ctx_sp.get();
170
171 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000172 data.PutHex32 (GPRWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000173 WriteRegister (reg_ctx, "rax", NULL, 8, data);
174 WriteRegister (reg_ctx, "rbx", NULL, 8, data);
175 WriteRegister (reg_ctx, "rcx", NULL, 8, data);
176 WriteRegister (reg_ctx, "rdx", NULL, 8, data);
177 WriteRegister (reg_ctx, "rdi", NULL, 8, data);
178 WriteRegister (reg_ctx, "rsi", NULL, 8, data);
179 WriteRegister (reg_ctx, "rbp", NULL, 8, data);
180 WriteRegister (reg_ctx, "rsp", NULL, 8, data);
181 WriteRegister (reg_ctx, "r8", NULL, 8, data);
182 WriteRegister (reg_ctx, "r9", NULL, 8, data);
183 WriteRegister (reg_ctx, "r10", NULL, 8, data);
184 WriteRegister (reg_ctx, "r11", NULL, 8, data);
185 WriteRegister (reg_ctx, "r12", NULL, 8, data);
186 WriteRegister (reg_ctx, "r13", NULL, 8, data);
187 WriteRegister (reg_ctx, "r14", NULL, 8, data);
188 WriteRegister (reg_ctx, "r15", NULL, 8, data);
189 WriteRegister (reg_ctx, "rip", NULL, 8, data);
190 WriteRegister (reg_ctx, "rflags", NULL, 8, data);
191 WriteRegister (reg_ctx, "cs", NULL, 8, data);
192 WriteRegister (reg_ctx, "fs", NULL, 8, data);
193 WriteRegister (reg_ctx, "gs", NULL, 8, data);
194
195// // Write out the FPU registers
196// const size_t fpu_byte_size = sizeof(FPU);
197// size_t bytes_written = 0;
198// data.PutHex32 (FPURegSet);
199// data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
200// bytes_written += data.PutHex32(0); // uint32_t pad[0]
201// bytes_written += data.PutHex32(0); // uint32_t pad[1]
202// bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, data); // uint16_t fcw; // "fctrl"
203// bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, data); // uint16_t fsw; // "fstat"
204// bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, data); // uint8_t ftw; // "ftag"
205// bytes_written += data.PutHex8 (0); // uint8_t pad1;
206// bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, data); // uint16_t fop; // "fop"
207// bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, data); // uint32_t ip; // "fioff"
208// bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, data); // uint16_t cs; // "fiseg"
209// bytes_written += data.PutHex16 (0); // uint16_t pad2;
210// bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, data); // uint32_t dp; // "fooff"
211// bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, data); // uint16_t ds; // "foseg"
212// bytes_written += data.PutHex16 (0); // uint16_t pad3;
213// bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, data); // uint32_t mxcsr;
214// bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, 4, data);// uint32_t mxcsrmask;
215// bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, sizeof(MMSReg), data);
216// bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, sizeof(MMSReg), data);
217// bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, sizeof(MMSReg), data);
218// bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, sizeof(MMSReg), data);
219// bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, sizeof(MMSReg), data);
220// bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, sizeof(MMSReg), data);
221// bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, sizeof(MMSReg), data);
222// bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, sizeof(MMSReg), data);
223// bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, sizeof(XMMReg), data);
224// bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, sizeof(XMMReg), data);
225// bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, sizeof(XMMReg), data);
226// bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, sizeof(XMMReg), data);
227// bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, sizeof(XMMReg), data);
228// bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, sizeof(XMMReg), data);
229// bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, sizeof(XMMReg), data);
230// bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, sizeof(XMMReg), data);
231// bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, sizeof(XMMReg), data);
232// bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, sizeof(XMMReg), data);
233// bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, sizeof(XMMReg), data);
234// bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, sizeof(XMMReg), data);
235// bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, sizeof(XMMReg), data);
236// bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, sizeof(XMMReg), data);
237// bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, sizeof(XMMReg), data);
238// bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, sizeof(XMMReg), data);
239//
240// // Fill rest with zeros
241// for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ i)
242// data.PutChar(0);
243
244 // Write out the EXC registers
245 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000246 data.PutHex32 (EXCWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000247 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
248 WriteRegister (reg_ctx, "err", NULL, 4, data);
249 WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data);
250 return true;
251 }
252 return false;
253 }
254
Greg Claytonc859e2d2012-02-13 23:10:39 +0000255protected:
Eugene Zelenko8157a882015-10-23 16:56:07 +0000256 int
257 DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000258 {
259 return 0;
260 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000261
Eugene Zelenko8157a882015-10-23 16:56:07 +0000262 int
263 DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000264 {
265 return 0;
266 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000267
Eugene Zelenko8157a882015-10-23 16:56:07 +0000268 int
269 DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000270 {
271 return 0;
272 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000273
Eugene Zelenko8157a882015-10-23 16:56:07 +0000274 int
275 DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000276 {
277 return 0;
278 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000279
Eugene Zelenko8157a882015-10-23 16:56:07 +0000280 int
281 DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000282 {
283 return 0;
284 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000285
Eugene Zelenko8157a882015-10-23 16:56:07 +0000286 int
287 DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000288 {
289 return 0;
290 }
291};
Greg Claytonc3776bf2012-02-09 06:16:32 +0000292
Jason Molenda4e7511e2013-03-06 23:19:17 +0000293class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
Greg Claytonc859e2d2012-02-13 23:10:39 +0000294{
295public:
296 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
297 RegisterContextDarwin_i386 (thread, 0)
298 {
299 SetRegisterDataFrom_LC_THREAD (data);
300 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000301
Eugene Zelenko8157a882015-10-23 16:56:07 +0000302 void
303 InvalidateAllRegisters() override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000304 {
305 // Do nothing... registers are always valid...
306 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000307
Greg Claytonc859e2d2012-02-13 23:10:39 +0000308 void
309 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
310 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000311 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000312 SetError (GPRRegSet, Read, -1);
313 SetError (FPURegSet, Read, -1);
314 SetError (EXCRegSet, Read, -1);
315 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000316
Greg Claytonc859e2d2012-02-13 23:10:39 +0000317 while (!done)
318 {
319 int flavor = data.GetU32 (&offset);
320 if (flavor == 0)
321 done = true;
322 else
Greg Claytonc3776bf2012-02-09 06:16:32 +0000323 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000324 uint32_t i;
325 uint32_t count = data.GetU32 (&offset);
326 switch (flavor)
327 {
328 case GPRRegSet:
329 for (i=0; i<count; ++i)
330 (&gpr.eax)[i] = data.GetU32(&offset);
331 SetError (GPRRegSet, Read, 0);
332 done = true;
333
334 break;
335 case FPURegSet:
336 // TODO: fill in FPU regs....
337 //SetError (FPURegSet, Read, -1);
338 done = true;
339
340 break;
341 case EXCRegSet:
342 exc.trapno = data.GetU32(&offset);
343 exc.err = data.GetU32(&offset);
344 exc.faultvaddr = data.GetU32(&offset);
345 SetError (EXCRegSet, Read, 0);
346 done = true;
347 break;
348 case 7:
349 case 8:
350 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000351 // fancy flavors that encapsulate of the above
352 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000353 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000354
Greg Claytonc859e2d2012-02-13 23:10:39 +0000355 default:
356 done = true;
357 break;
358 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000359 }
360 }
361 }
Jason Molendad20359d2014-11-11 10:59:15 +0000362
363 static size_t
364 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
365 {
366 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
367 if (reg_info == NULL)
368 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
369 if (reg_info)
370 {
371 lldb_private::RegisterValue reg_value;
372 if (reg_ctx->ReadRegister(reg_info, reg_value))
373 {
374 if (reg_info->byte_size >= reg_byte_size)
375 data.Write(reg_value.GetBytes(), reg_byte_size);
376 else
377 {
378 data.Write(reg_value.GetBytes(), reg_info->byte_size);
379 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
380 data.PutChar(0);
381 }
382 return reg_byte_size;
383 }
384 }
385 // Just write zeros if all else fails
386 for (size_t i=0; i<reg_byte_size; ++ i)
387 data.PutChar(0);
388 return reg_byte_size;
389 }
390
391 static bool
392 Create_LC_THREAD (Thread *thread, Stream &data)
393 {
394 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
395 if (reg_ctx_sp)
396 {
397 RegisterContext *reg_ctx = reg_ctx_sp.get();
398
399 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000400 data.PutHex32 (GPRWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000401 WriteRegister (reg_ctx, "eax", NULL, 4, data);
402 WriteRegister (reg_ctx, "ebx", NULL, 4, data);
403 WriteRegister (reg_ctx, "ecx", NULL, 4, data);
404 WriteRegister (reg_ctx, "edx", NULL, 4, data);
405 WriteRegister (reg_ctx, "edi", NULL, 4, data);
406 WriteRegister (reg_ctx, "esi", NULL, 4, data);
407 WriteRegister (reg_ctx, "ebp", NULL, 4, data);
408 WriteRegister (reg_ctx, "esp", NULL, 4, data);
409 WriteRegister (reg_ctx, "ss", NULL, 4, data);
410 WriteRegister (reg_ctx, "eflags", NULL, 4, data);
411 WriteRegister (reg_ctx, "eip", NULL, 4, data);
412 WriteRegister (reg_ctx, "cs", NULL, 4, data);
413 WriteRegister (reg_ctx, "ds", NULL, 4, data);
414 WriteRegister (reg_ctx, "es", NULL, 4, data);
415 WriteRegister (reg_ctx, "fs", NULL, 4, data);
416 WriteRegister (reg_ctx, "gs", NULL, 4, data);
417
418 // Write out the EXC registers
419 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000420 data.PutHex32 (EXCWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000421 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
422 WriteRegister (reg_ctx, "err", NULL, 4, data);
Jason Molenda22952582014-11-12 01:11:36 +0000423 WriteRegister (reg_ctx, "faultvaddr", NULL, 4, data);
Jason Molendad20359d2014-11-11 10:59:15 +0000424 return true;
425 }
426 return false;
427 }
428
Greg Claytonc3776bf2012-02-09 06:16:32 +0000429protected:
Eugene Zelenko8157a882015-10-23 16:56:07 +0000430 int
431 DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000432 {
433 return 0;
434 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000435
Eugene Zelenko8157a882015-10-23 16:56:07 +0000436 int
437 DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000438 {
439 return 0;
440 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000441
Eugene Zelenko8157a882015-10-23 16:56:07 +0000442 int
443 DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000444 {
445 return 0;
446 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000447
Eugene Zelenko8157a882015-10-23 16:56:07 +0000448 int
449 DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000450 {
451 return 0;
452 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000453
Eugene Zelenko8157a882015-10-23 16:56:07 +0000454 int
455 DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000456 {
457 return 0;
458 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000459
Eugene Zelenko8157a882015-10-23 16:56:07 +0000460 int
461 DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000462 {
463 return 0;
464 }
465};
466
Jason Molenda4e7511e2013-03-06 23:19:17 +0000467class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000468{
469public:
470 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
Greg Claytonc2807462012-10-30 23:57:32 +0000471 RegisterContextDarwin_arm (thread, 0)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000472 {
473 SetRegisterDataFrom_LC_THREAD (data);
474 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000475
Eugene Zelenko8157a882015-10-23 16:56:07 +0000476 void
477 InvalidateAllRegisters() override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000478 {
479 // Do nothing... registers are always valid...
480 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000481
Greg Claytonc859e2d2012-02-13 23:10:39 +0000482 void
483 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
484 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000485 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000486 SetError (GPRRegSet, Read, -1);
487 SetError (FPURegSet, Read, -1);
488 SetError (EXCRegSet, Read, -1);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000489 bool done = false;
490
491 while (!done)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000492 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000493 int flavor = data.GetU32 (&offset);
494 uint32_t count = data.GetU32 (&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000495 lldb::offset_t next_thread_state = offset + (count * 4);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000496 switch (flavor)
497 {
498 case GPRRegSet:
499 for (uint32_t i=0; i<count; ++i)
Jason Molendaddf91772013-05-14 04:50:47 +0000500 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000501 gpr.r[i] = data.GetU32(&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000502 }
503
504 // Note that gpr.cpsr is also copied by the above loop; this loop technically extends
505 // one element past the end of the gpr.r[] array.
506
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000507 SetError (GPRRegSet, Read, 0);
Jason Molendaddf91772013-05-14 04:50:47 +0000508 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000509 break;
510
511 case FPURegSet:
512 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000513 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0];
514 const int fpu_reg_buf_size = sizeof (fpu.floats);
515 if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000516 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000517 offset += fpu_reg_buf_size;
518 fpu.fpscr = data.GetU32(&offset);
519 SetError (FPURegSet, Read, 0);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000520 }
Jason Molenda663d2e12013-05-14 03:52:22 +0000521 else
522 {
523 done = true;
524 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000525 }
Jason Molendaddf91772013-05-14 04:50:47 +0000526 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000527 break;
528
529 case EXCRegSet:
Jason Molendaddf91772013-05-14 04:50:47 +0000530 if (count == 3)
531 {
532 exc.exception = data.GetU32(&offset);
533 exc.fsr = data.GetU32(&offset);
534 exc.far = data.GetU32(&offset);
535 SetError (EXCRegSet, Read, 0);
536 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000537 done = true;
Jason Molendaddf91772013-05-14 04:50:47 +0000538 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000539 break;
540
541 // Unknown register set flavor, stop trying to parse.
542 default:
543 done = true;
544 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000545 }
546 }
Jason Molenda22952582014-11-12 01:11:36 +0000547
548 static size_t
549 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
550 {
551 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
552 if (reg_info == NULL)
553 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
554 if (reg_info)
555 {
556 lldb_private::RegisterValue reg_value;
557 if (reg_ctx->ReadRegister(reg_info, reg_value))
558 {
559 if (reg_info->byte_size >= reg_byte_size)
560 data.Write(reg_value.GetBytes(), reg_byte_size);
561 else
562 {
563 data.Write(reg_value.GetBytes(), reg_info->byte_size);
564 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
565 data.PutChar(0);
566 }
567 return reg_byte_size;
568 }
569 }
570 // Just write zeros if all else fails
571 for (size_t i=0; i<reg_byte_size; ++ i)
572 data.PutChar(0);
573 return reg_byte_size;
574 }
575
576 static bool
577 Create_LC_THREAD (Thread *thread, Stream &data)
578 {
579 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
580 if (reg_ctx_sp)
581 {
582 RegisterContext *reg_ctx = reg_ctx_sp.get();
583
584 data.PutHex32 (GPRRegSet); // Flavor
585 data.PutHex32 (GPRWordCount);
586 WriteRegister (reg_ctx, "r0", NULL, 4, data);
587 WriteRegister (reg_ctx, "r1", NULL, 4, data);
588 WriteRegister (reg_ctx, "r2", NULL, 4, data);
589 WriteRegister (reg_ctx, "r3", NULL, 4, data);
590 WriteRegister (reg_ctx, "r4", NULL, 4, data);
591 WriteRegister (reg_ctx, "r5", NULL, 4, data);
592 WriteRegister (reg_ctx, "r6", NULL, 4, data);
593 WriteRegister (reg_ctx, "r7", NULL, 4, data);
594 WriteRegister (reg_ctx, "r8", NULL, 4, data);
595 WriteRegister (reg_ctx, "r9", NULL, 4, data);
596 WriteRegister (reg_ctx, "r10", NULL, 4, data);
597 WriteRegister (reg_ctx, "r11", NULL, 4, data);
598 WriteRegister (reg_ctx, "r12", NULL, 4, data);
599 WriteRegister (reg_ctx, "sp", NULL, 4, data);
600 WriteRegister (reg_ctx, "lr", NULL, 4, data);
601 WriteRegister (reg_ctx, "pc", NULL, 4, data);
602 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
603
604 // Write out the EXC registers
605// data.PutHex32 (EXCRegSet);
606// data.PutHex32 (EXCWordCount);
607// WriteRegister (reg_ctx, "exception", NULL, 4, data);
608// WriteRegister (reg_ctx, "fsr", NULL, 4, data);
609// WriteRegister (reg_ctx, "far", NULL, 4, data);
610 return true;
611 }
612 return false;
613 }
614
Greg Claytonc859e2d2012-02-13 23:10:39 +0000615protected:
Eugene Zelenko8157a882015-10-23 16:56:07 +0000616 int
617 DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000618 {
Jason Molendaddf91772013-05-14 04:50:47 +0000619 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000620 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000621
Eugene Zelenko8157a882015-10-23 16:56:07 +0000622 int
623 DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000624 {
Jason Molendaddf91772013-05-14 04:50:47 +0000625 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000626 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000627
Eugene Zelenko8157a882015-10-23 16:56:07 +0000628 int
629 DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000630 {
Jason Molendaddf91772013-05-14 04:50:47 +0000631 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000632 }
Greg Claytonc2807462012-10-30 23:57:32 +0000633
Eugene Zelenko8157a882015-10-23 16:56:07 +0000634 int
635 DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
Greg Claytonc2807462012-10-30 23:57:32 +0000636 {
637 return -1;
638 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000639
Eugene Zelenko8157a882015-10-23 16:56:07 +0000640 int
641 DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000642 {
643 return 0;
644 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000645
Eugene Zelenko8157a882015-10-23 16:56:07 +0000646 int
647 DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000648 {
649 return 0;
650 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000651
Eugene Zelenko8157a882015-10-23 16:56:07 +0000652 int
653 DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000654 {
655 return 0;
656 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000657
Eugene Zelenko8157a882015-10-23 16:56:07 +0000658 int
659 DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
Greg Claytonc2807462012-10-30 23:57:32 +0000660 {
661 return -1;
662 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000663};
664
Jason Molendaa3329782014-03-29 18:54:20 +0000665class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
666{
667public:
668 RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
669 RegisterContextDarwin_arm64 (thread, 0)
670 {
671 SetRegisterDataFrom_LC_THREAD (data);
672 }
673
Eugene Zelenko8157a882015-10-23 16:56:07 +0000674 void
675 InvalidateAllRegisters() override
Jason Molendaa3329782014-03-29 18:54:20 +0000676 {
677 // Do nothing... registers are always valid...
678 }
679
680 void
681 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
682 {
683 lldb::offset_t offset = 0;
684 SetError (GPRRegSet, Read, -1);
685 SetError (FPURegSet, Read, -1);
686 SetError (EXCRegSet, Read, -1);
687 bool done = false;
688 while (!done)
689 {
690 int flavor = data.GetU32 (&offset);
691 uint32_t count = data.GetU32 (&offset);
692 lldb::offset_t next_thread_state = offset + (count * 4);
693 switch (flavor)
694 {
695 case GPRRegSet:
696 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
697 if (count >= (33 * 2) + 1)
698 {
699 for (uint32_t i=0; i<33; ++i)
700 gpr.x[i] = data.GetU64(&offset);
701 gpr.cpsr = data.GetU32(&offset);
702 SetError (GPRRegSet, Read, 0);
703 }
704 offset = next_thread_state;
705 break;
706 case FPURegSet:
707 {
708 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
709 const int fpu_reg_buf_size = sizeof (fpu);
710 if (fpu_reg_buf_size == count
711 && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
712 {
713 SetError (FPURegSet, Read, 0);
714 }
715 else
716 {
717 done = true;
718 }
719 }
720 offset = next_thread_state;
721 break;
722 case EXCRegSet:
723 if (count == 4)
724 {
725 exc.far = data.GetU64(&offset);
726 exc.esr = data.GetU32(&offset);
727 exc.exception = data.GetU32(&offset);
728 SetError (EXCRegSet, Read, 0);
729 }
730 offset = next_thread_state;
731 break;
732 default:
733 done = true;
734 break;
735 }
736 }
737 }
Jason Molenda22952582014-11-12 01:11:36 +0000738
739 static size_t
740 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
741 {
742 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
743 if (reg_info == NULL)
744 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
745 if (reg_info)
746 {
747 lldb_private::RegisterValue reg_value;
748 if (reg_ctx->ReadRegister(reg_info, reg_value))
749 {
750 if (reg_info->byte_size >= reg_byte_size)
751 data.Write(reg_value.GetBytes(), reg_byte_size);
752 else
753 {
754 data.Write(reg_value.GetBytes(), reg_info->byte_size);
755 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
756 data.PutChar(0);
757 }
758 return reg_byte_size;
759 }
760 }
761 // Just write zeros if all else fails
762 for (size_t i=0; i<reg_byte_size; ++ i)
763 data.PutChar(0);
764 return reg_byte_size;
765 }
766
767 static bool
768 Create_LC_THREAD (Thread *thread, Stream &data)
769 {
770 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
771 if (reg_ctx_sp)
772 {
773 RegisterContext *reg_ctx = reg_ctx_sp.get();
774
775 data.PutHex32 (GPRRegSet); // Flavor
776 data.PutHex32 (GPRWordCount);
777 WriteRegister (reg_ctx, "x0", NULL, 8, data);
778 WriteRegister (reg_ctx, "x1", NULL, 8, data);
779 WriteRegister (reg_ctx, "x2", NULL, 8, data);
780 WriteRegister (reg_ctx, "x3", NULL, 8, data);
781 WriteRegister (reg_ctx, "x4", NULL, 8, data);
782 WriteRegister (reg_ctx, "x5", NULL, 8, data);
783 WriteRegister (reg_ctx, "x6", NULL, 8, data);
784 WriteRegister (reg_ctx, "x7", NULL, 8, data);
785 WriteRegister (reg_ctx, "x8", NULL, 8, data);
786 WriteRegister (reg_ctx, "x9", NULL, 8, data);
787 WriteRegister (reg_ctx, "x10", NULL, 8, data);
788 WriteRegister (reg_ctx, "x11", NULL, 8, data);
789 WriteRegister (reg_ctx, "x12", NULL, 8, data);
790 WriteRegister (reg_ctx, "x13", NULL, 8, data);
791 WriteRegister (reg_ctx, "x14", NULL, 8, data);
792 WriteRegister (reg_ctx, "x15", NULL, 8, data);
793 WriteRegister (reg_ctx, "x16", NULL, 8, data);
794 WriteRegister (reg_ctx, "x17", NULL, 8, data);
795 WriteRegister (reg_ctx, "x18", NULL, 8, data);
796 WriteRegister (reg_ctx, "x19", NULL, 8, data);
797 WriteRegister (reg_ctx, "x20", NULL, 8, data);
798 WriteRegister (reg_ctx, "x21", NULL, 8, data);
799 WriteRegister (reg_ctx, "x22", NULL, 8, data);
800 WriteRegister (reg_ctx, "x23", NULL, 8, data);
801 WriteRegister (reg_ctx, "x24", NULL, 8, data);
802 WriteRegister (reg_ctx, "x25", NULL, 8, data);
803 WriteRegister (reg_ctx, "x26", NULL, 8, data);
804 WriteRegister (reg_ctx, "x27", NULL, 8, data);
805 WriteRegister (reg_ctx, "x28", NULL, 8, data);
806 WriteRegister (reg_ctx, "fp", NULL, 8, data);
807 WriteRegister (reg_ctx, "lr", NULL, 8, data);
808 WriteRegister (reg_ctx, "sp", NULL, 8, data);
809 WriteRegister (reg_ctx, "pc", NULL, 8, data);
810 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
811
812 // Write out the EXC registers
813// data.PutHex32 (EXCRegSet);
814// data.PutHex32 (EXCWordCount);
815// WriteRegister (reg_ctx, "far", NULL, 8, data);
816// WriteRegister (reg_ctx, "esr", NULL, 4, data);
817// WriteRegister (reg_ctx, "exception", NULL, 4, data);
818 return true;
819 }
820 return false;
821 }
822
Jason Molendaa3329782014-03-29 18:54:20 +0000823protected:
Eugene Zelenko8157a882015-10-23 16:56:07 +0000824 int
825 DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
Jason Molendaa3329782014-03-29 18:54:20 +0000826 {
827 return -1;
828 }
829
Eugene Zelenko8157a882015-10-23 16:56:07 +0000830 int
831 DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
Jason Molendaa3329782014-03-29 18:54:20 +0000832 {
833 return -1;
834 }
835
Eugene Zelenko8157a882015-10-23 16:56:07 +0000836 int
837 DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
Jason Molendaa3329782014-03-29 18:54:20 +0000838 {
839 return -1;
840 }
841
Eugene Zelenko8157a882015-10-23 16:56:07 +0000842 int
843 DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
Jason Molendaa3329782014-03-29 18:54:20 +0000844 {
845 return -1;
846 }
847
Eugene Zelenko8157a882015-10-23 16:56:07 +0000848 int
849 DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
Jason Molendaa3329782014-03-29 18:54:20 +0000850 {
851 return 0;
852 }
853
Eugene Zelenko8157a882015-10-23 16:56:07 +0000854 int
855 DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
Jason Molendaa3329782014-03-29 18:54:20 +0000856 {
857 return 0;
858 }
859
Eugene Zelenko8157a882015-10-23 16:56:07 +0000860 int
861 DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
Jason Molendaa3329782014-03-29 18:54:20 +0000862 {
863 return 0;
864 }
865
Eugene Zelenko8157a882015-10-23 16:56:07 +0000866 int
867 DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
Jason Molendaa3329782014-03-29 18:54:20 +0000868 {
869 return -1;
870 }
871};
872
Greg Clayton9aae0a12013-05-15 19:52:08 +0000873static uint32_t
874MachHeaderSizeFromMagic(uint32_t magic)
875{
876 switch (magic)
877 {
Charles Davis510938e2013-08-27 05:04:57 +0000878 case MH_MAGIC:
879 case MH_CIGAM:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000880 return sizeof(struct mach_header);
881
Charles Davis510938e2013-08-27 05:04:57 +0000882 case MH_MAGIC_64:
883 case MH_CIGAM_64:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000884 return sizeof(struct mach_header_64);
885 break;
886
887 default:
888 break;
889 }
890 return 0;
891}
892
Greg Claytonded470d2011-03-19 01:12:21 +0000893#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000894
895void
896ObjectFileMachO::Initialize()
897{
898 PluginManager::RegisterPlugin (GetPluginNameStatic(),
899 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000900 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000901 CreateMemoryInstance,
Greg Claytona2715cf2014-06-13 00:54:12 +0000902 GetModuleSpecifications,
903 SaveCore);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000904}
905
906void
907ObjectFileMachO::Terminate()
908{
909 PluginManager::UnregisterPlugin (CreateInstance);
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
Greg Claytonc9660542012-02-05 02:38:54 +00001014const ConstString &
1015ObjectFileMachO::GetSegmentNameTEXT()
1016{
1017 static ConstString g_segment_name_TEXT ("__TEXT");
1018 return g_segment_name_TEXT;
1019}
1020
1021const ConstString &
1022ObjectFileMachO::GetSegmentNameDATA()
1023{
1024 static ConstString g_segment_name_DATA ("__DATA");
1025 return g_segment_name_DATA;
1026}
1027
1028const ConstString &
Greg Claytona381e102015-07-27 23:21:05 +00001029ObjectFileMachO::GetSegmentNameDATA_DIRTY()
1030{
1031 static ConstString g_segment_name ("__DATA_DIRTY");
1032 return g_segment_name;
1033}
1034
1035const ConstString &
1036ObjectFileMachO::GetSegmentNameDATA_CONST()
1037{
1038 static ConstString g_segment_name ("__DATA_CONST");
1039 return g_segment_name;
1040}
1041
1042const ConstString &
Greg Claytonc9660542012-02-05 02:38:54 +00001043ObjectFileMachO::GetSegmentNameOBJC()
1044{
1045 static ConstString g_segment_name_OBJC ("__OBJC");
1046 return g_segment_name_OBJC;
1047}
1048
1049const ConstString &
1050ObjectFileMachO::GetSegmentNameLINKEDIT()
1051{
1052 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
1053 return g_section_name_LINKEDIT;
1054}
1055
1056const ConstString &
1057ObjectFileMachO::GetSectionNameEHFrame()
1058{
1059 static ConstString g_section_name_eh_frame ("__eh_frame");
1060 return g_section_name_eh_frame;
1061}
1062
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063bool
Jason Molenda4e7511e2013-03-06 23:19:17 +00001064ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
1065 lldb::addr_t data_offset,
Greg Clayton44435ed2012-01-12 05:25:17 +00001066 lldb::addr_t data_length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067{
Greg Clayton44435ed2012-01-12 05:25:17 +00001068 DataExtractor data;
1069 data.SetData (data_sp, data_offset, data_length);
Greg Claytonc7bece562013-01-25 18:06:21 +00001070 lldb::offset_t offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001071 uint32_t magic = data.GetU32(&offset);
1072 return MachHeaderSizeFromMagic(magic) != 0;
1073}
1074
Greg Clayton5ce9c562013-02-06 17:22:03 +00001075ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
1076 DataBufferSP& data_sp,
1077 lldb::offset_t data_offset,
1078 const FileSpec* file,
1079 lldb::offset_t file_offset,
1080 lldb::offset_t length) :
1081 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001082 m_mach_segments(),
1083 m_mach_sections(),
1084 m_entry_point_address(),
1085 m_thread_context_offsets(),
1086 m_thread_context_offsets_valid(false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001087{
Greg Clayton72b77eb2011-02-04 21:13:05 +00001088 ::memset (&m_header, 0, sizeof(m_header));
1089 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090}
1091
Greg Claytone72dfb32012-02-24 01:59:29 +00001092ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonc9660542012-02-05 02:38:54 +00001093 lldb::DataBufferSP& header_data_sp,
1094 const lldb::ProcessSP &process_sp,
1095 lldb::addr_t header_addr) :
Greg Claytone72dfb32012-02-24 01:59:29 +00001096 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001097 m_mach_segments(),
1098 m_mach_sections(),
1099 m_entry_point_address(),
1100 m_thread_context_offsets(),
1101 m_thread_context_offsets_valid(false)
Greg Claytonc9660542012-02-05 02:38:54 +00001102{
1103 ::memset (&m_header, 0, sizeof(m_header));
1104 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1105}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106
Greg Claytonf4d6de62013-04-24 22:29:28 +00001107bool
1108ObjectFileMachO::ParseHeader (DataExtractor &data,
1109 lldb::offset_t *data_offset_ptr,
1110 llvm::MachO::mach_header &header)
1111{
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001112 data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytonf4d6de62013-04-24 22:29:28 +00001113 // Leave magic in the original byte order
1114 header.magic = data.GetU32(data_offset_ptr);
1115 bool can_parse = false;
1116 bool is_64_bit = false;
1117 switch (header.magic)
1118 {
Charles Davis510938e2013-08-27 05:04:57 +00001119 case MH_MAGIC:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001120 data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytonf4d6de62013-04-24 22:29:28 +00001121 data.SetAddressByteSize(4);
1122 can_parse = true;
1123 break;
1124
Charles Davis510938e2013-08-27 05:04:57 +00001125 case MH_MAGIC_64:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001126 data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytonf4d6de62013-04-24 22:29:28 +00001127 data.SetAddressByteSize(8);
1128 can_parse = true;
1129 is_64_bit = true;
1130 break;
1131
Charles Davis510938e2013-08-27 05:04:57 +00001132 case MH_CIGAM:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001133 data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Greg Claytonf4d6de62013-04-24 22:29:28 +00001134 data.SetAddressByteSize(4);
1135 can_parse = true;
1136 break;
1137
Charles Davis510938e2013-08-27 05:04:57 +00001138 case MH_CIGAM_64:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001139 data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Greg Claytonf4d6de62013-04-24 22:29:28 +00001140 data.SetAddressByteSize(8);
1141 is_64_bit = true;
1142 can_parse = true;
1143 break;
1144
1145 default:
1146 break;
1147 }
1148
1149 if (can_parse)
1150 {
1151 data.GetU32(data_offset_ptr, &header.cputype, 6);
1152 if (is_64_bit)
1153 *data_offset_ptr += 4;
1154 return true;
1155 }
1156 else
1157 {
1158 memset(&header, 0, sizeof(header));
1159 }
1160 return false;
1161}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162
1163bool
1164ObjectFileMachO::ParseHeader ()
1165{
Greg Claytona1743492012-03-13 23:14:29 +00001166 ModuleSP module_sp(GetModule());
1167 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001168 {
Greg Claytona1743492012-03-13 23:14:29 +00001169 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1170 bool can_parse = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00001171 lldb::offset_t offset = 0;
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001172 m_data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001173 // Leave magic in the original byte order
1174 m_header.magic = m_data.GetU32(&offset);
1175 switch (m_header.magic)
Greg Claytonc9660542012-02-05 02:38:54 +00001176 {
Charles Davis510938e2013-08-27 05:04:57 +00001177 case MH_MAGIC:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001178 m_data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001179 m_data.SetAddressByteSize(4);
1180 can_parse = true;
1181 break;
1182
Charles Davis510938e2013-08-27 05:04:57 +00001183 case MH_MAGIC_64:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001184 m_data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001185 m_data.SetAddressByteSize(8);
1186 can_parse = true;
1187 break;
1188
Charles Davis510938e2013-08-27 05:04:57 +00001189 case MH_CIGAM:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001190 m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Greg Claytona1743492012-03-13 23:14:29 +00001191 m_data.SetAddressByteSize(4);
1192 can_parse = true;
1193 break;
1194
Charles Davis510938e2013-08-27 05:04:57 +00001195 case MH_CIGAM_64:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001196 m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Greg Claytona1743492012-03-13 23:14:29 +00001197 m_data.SetAddressByteSize(8);
1198 can_parse = true;
1199 break;
1200
1201 default:
1202 break;
Greg Claytonc9660542012-02-05 02:38:54 +00001203 }
Greg Claytona1743492012-03-13 23:14:29 +00001204
1205 if (can_parse)
1206 {
1207 m_data.GetU32(&offset, &m_header.cputype, 6);
1208
Greg Clayton7ab7f892014-05-29 21:33:45 +00001209
1210 ArchSpec mach_arch;
1211
1212 if (GetArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001213 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001214 // Check if the module has a required architecture
1215 const ArchSpec &module_arch = module_sp->GetArchitecture();
1216 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
1217 return false;
1218
1219 if (SetModulesArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001220 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001221 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
1222 if (m_data.GetByteSize() < header_and_lc_size)
Greg Claytona1743492012-03-13 23:14:29 +00001223 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001224 DataBufferSP data_sp;
1225 ProcessSP process_sp (m_process_wp.lock());
1226 if (process_sp)
1227 {
1228 data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
1229 }
1230 else
1231 {
1232 // Read in all only the load command data from the file on disk
1233 data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
1234 if (data_sp->GetByteSize() != header_and_lc_size)
1235 return false;
1236 }
1237 if (data_sp)
1238 m_data.SetData (data_sp);
Greg Claytona1743492012-03-13 23:14:29 +00001239 }
Greg Claytona1743492012-03-13 23:14:29 +00001240 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00001241 return true;
Greg Claytona1743492012-03-13 23:14:29 +00001242 }
Greg Claytona1743492012-03-13 23:14:29 +00001243 }
1244 else
1245 {
1246 memset(&m_header, 0, sizeof(struct mach_header));
1247 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001248 }
1249 return false;
1250}
1251
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001252ByteOrder
1253ObjectFileMachO::GetByteOrder () const
1254{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255 return m_data.GetByteOrder ();
1256}
1257
Jim Ingham5aee1622010-08-09 23:31:02 +00001258bool
1259ObjectFileMachO::IsExecutable() const
1260{
Charles Davis510938e2013-08-27 05:04:57 +00001261 return m_header.filetype == MH_EXECUTE;
Jim Ingham5aee1622010-08-09 23:31:02 +00001262}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001263
Greg Claytonc7bece562013-01-25 18:06:21 +00001264uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001265ObjectFileMachO::GetAddressByteSize () const
1266{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267 return m_data.GetAddressByteSize ();
1268}
1269
Greg Claytone0d378b2011-03-24 21:19:54 +00001270AddressClass
Greg Claytonded470d2011-03-19 01:12:21 +00001271ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
1272{
1273 Symtab *symtab = GetSymtab();
1274 if (symtab)
1275 {
1276 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
1277 if (symbol)
1278 {
Greg Claytone7612132012-03-07 21:03:09 +00001279 if (symbol->ValueIsAddress())
Greg Claytonded470d2011-03-19 01:12:21 +00001280 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00001281 SectionSP section_sp (symbol->GetAddressRef().GetSection());
Greg Claytone72dfb32012-02-24 01:59:29 +00001282 if (section_sp)
Greg Claytonded470d2011-03-19 01:12:21 +00001283 {
Charles Davis510938e2013-08-27 05:04:57 +00001284 const lldb::SectionType section_type = section_sp->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001285 switch (section_type)
1286 {
Jason Molendae589e7e2014-12-08 03:09:00 +00001287 case eSectionTypeInvalid:
1288 return eAddressClassUnknown;
1289
Greg Claytonded470d2011-03-19 01:12:21 +00001290 case eSectionTypeCode:
Charles Davis510938e2013-08-27 05:04:57 +00001291 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001292 {
1293 // For ARM we have a bit in the n_desc field of the symbol
1294 // that tells us ARM/Thumb which is bit 0x0008.
1295 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1296 return eAddressClassCodeAlternateISA;
1297 }
1298 return eAddressClassCode;
1299
Jason Molendae589e7e2014-12-08 03:09:00 +00001300 case eSectionTypeContainer:
1301 return eAddressClassUnknown;
1302
Greg Clayton5009f9d2011-10-27 17:55:14 +00001303 case eSectionTypeData:
1304 case eSectionTypeDataCString:
1305 case eSectionTypeDataCStringPointers:
1306 case eSectionTypeDataSymbolAddress:
1307 case eSectionTypeData4:
1308 case eSectionTypeData8:
1309 case eSectionTypeData16:
1310 case eSectionTypeDataPointers:
1311 case eSectionTypeZeroFill:
1312 case eSectionTypeDataObjCMessageRefs:
1313 case eSectionTypeDataObjCCFStrings:
Ryan Brown65d4d5c2015-09-16 21:20:44 +00001314 case eSectionTypeGoSymtab:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001315 return eAddressClassData;
Jason Molendae589e7e2014-12-08 03:09:00 +00001316
Greg Clayton5009f9d2011-10-27 17:55:14 +00001317 case eSectionTypeDebug:
1318 case eSectionTypeDWARFDebugAbbrev:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001319 case eSectionTypeDWARFDebugAddr:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001320 case eSectionTypeDWARFDebugAranges:
1321 case eSectionTypeDWARFDebugFrame:
1322 case eSectionTypeDWARFDebugInfo:
1323 case eSectionTypeDWARFDebugLine:
1324 case eSectionTypeDWARFDebugLoc:
1325 case eSectionTypeDWARFDebugMacInfo:
1326 case eSectionTypeDWARFDebugPubNames:
1327 case eSectionTypeDWARFDebugPubTypes:
1328 case eSectionTypeDWARFDebugRanges:
1329 case eSectionTypeDWARFDebugStr:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001330 case eSectionTypeDWARFDebugStrOffsets:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001331 case eSectionTypeDWARFAppleNames:
1332 case eSectionTypeDWARFAppleTypes:
1333 case eSectionTypeDWARFAppleNamespaces:
1334 case eSectionTypeDWARFAppleObjC:
1335 return eAddressClassDebug;
Jason Molendae589e7e2014-12-08 03:09:00 +00001336
1337 case eSectionTypeEHFrame:
Tamas Berghammer648f3c72015-09-30 13:50:14 +00001338 case eSectionTypeARMexidx:
1339 case eSectionTypeARMextab:
Jason Molendae589e7e2014-12-08 03:09:00 +00001340 case eSectionTypeCompactUnwind:
1341 return eAddressClassRuntime;
1342
Michael Sartaina7499c92013-07-01 19:45:50 +00001343 case eSectionTypeELFSymbolTable:
1344 case eSectionTypeELFDynamicSymbols:
1345 case eSectionTypeELFRelocationEntries:
1346 case eSectionTypeELFDynamicLinkInfo:
Jason Molendae589e7e2014-12-08 03:09:00 +00001347 case eSectionTypeOther:
1348 return eAddressClassUnknown;
Greg Claytonded470d2011-03-19 01:12:21 +00001349 }
1350 }
1351 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001352
Greg Claytone0d378b2011-03-24 21:19:54 +00001353 const SymbolType symbol_type = symbol->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001354 switch (symbol_type)
1355 {
1356 case eSymbolTypeAny: return eAddressClassUnknown;
1357 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Jason Molenda4e7511e2013-03-06 23:19:17 +00001358
Greg Claytonded470d2011-03-19 01:12:21 +00001359 case eSymbolTypeCode:
1360 case eSymbolTypeTrampoline:
Greg Clayton059f7242013-02-27 21:16:04 +00001361 case eSymbolTypeResolver:
Charles Davis510938e2013-08-27 05:04:57 +00001362 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001363 {
1364 // For ARM we have a bit in the n_desc field of the symbol
1365 // that tells us ARM/Thumb which is bit 0x0008.
1366 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1367 return eAddressClassCodeAlternateISA;
1368 }
1369 return eAddressClassCode;
1370
1371 case eSymbolTypeData: return eAddressClassData;
1372 case eSymbolTypeRuntime: return eAddressClassRuntime;
1373 case eSymbolTypeException: return eAddressClassRuntime;
1374 case eSymbolTypeSourceFile: return eAddressClassDebug;
1375 case eSymbolTypeHeaderFile: return eAddressClassDebug;
1376 case eSymbolTypeObjectFile: return eAddressClassDebug;
1377 case eSymbolTypeCommonBlock: return eAddressClassDebug;
1378 case eSymbolTypeBlock: return eAddressClassDebug;
1379 case eSymbolTypeLocal: return eAddressClassData;
1380 case eSymbolTypeParam: return eAddressClassData;
1381 case eSymbolTypeVariable: return eAddressClassData;
1382 case eSymbolTypeVariableType: return eAddressClassDebug;
1383 case eSymbolTypeLineEntry: return eAddressClassDebug;
1384 case eSymbolTypeLineHeader: return eAddressClassDebug;
1385 case eSymbolTypeScopeBegin: return eAddressClassDebug;
1386 case eSymbolTypeScopeEnd: return eAddressClassDebug;
1387 case eSymbolTypeAdditional: return eAddressClassUnknown;
1388 case eSymbolTypeCompiler: return eAddressClassDebug;
1389 case eSymbolTypeInstrumentation:return eAddressClassDebug;
1390 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton456809c2011-12-03 02:30:59 +00001391 case eSymbolTypeObjCClass: return eAddressClassRuntime;
1392 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
1393 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Clayton9191db42013-10-21 18:40:51 +00001394 case eSymbolTypeReExported: return eAddressClassRuntime;
Greg Claytonded470d2011-03-19 01:12:21 +00001395 }
1396 }
1397 }
1398 return eAddressClassUnknown;
1399}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001400
1401Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001402ObjectFileMachO::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001403{
Greg Claytona1743492012-03-13 23:14:29 +00001404 ModuleSP module_sp(GetModule());
1405 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001406 {
Greg Claytona1743492012-03-13 23:14:29 +00001407 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1408 if (m_symtab_ap.get() == NULL)
1409 {
1410 m_symtab_ap.reset(new Symtab(this));
1411 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
Greg Clayton3046e662013-07-10 01:23:25 +00001412 ParseSymtab ();
Greg Claytona1743492012-03-13 23:14:29 +00001413 m_symtab_ap->Finalize ();
1414 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001415 }
1416 return m_symtab_ap.get();
1417}
1418
Greg Clayton3046e662013-07-10 01:23:25 +00001419bool
1420ObjectFileMachO::IsStripped ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001421{
Greg Clayton3046e662013-07-10 01:23:25 +00001422 if (m_dysymtab.cmd == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001423 {
Greg Clayton3046e662013-07-10 01:23:25 +00001424 ModuleSP module_sp(GetModule());
1425 if (module_sp)
Greg Claytona1743492012-03-13 23:14:29 +00001426 {
Greg Clayton3046e662013-07-10 01:23:25 +00001427 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1428 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton4d78c402012-05-25 18:09:55 +00001429 {
Greg Clayton3046e662013-07-10 01:23:25 +00001430 const lldb::offset_t load_cmd_offset = offset;
1431
1432 load_command lc;
1433 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
1434 break;
Charles Davis510938e2013-08-27 05:04:57 +00001435 if (lc.cmd == LC_DYSYMTAB)
Greg Clayton4d78c402012-05-25 18:09:55 +00001436 {
Greg Clayton3046e662013-07-10 01:23:25 +00001437 m_dysymtab.cmd = lc.cmd;
1438 m_dysymtab.cmdsize = lc.cmdsize;
1439 if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
1440 {
1441 // Clear m_dysymtab if we were unable to read all items from the load command
1442 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1443 }
Greg Clayton4d78c402012-05-25 18:09:55 +00001444 }
Greg Clayton3046e662013-07-10 01:23:25 +00001445 offset = load_cmd_offset + lc.cmdsize;
Greg Clayton4d78c402012-05-25 18:09:55 +00001446 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001447 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001448 }
Greg Clayton3046e662013-07-10 01:23:25 +00001449 if (m_dysymtab.cmd)
Greg Clayton93e28612013-10-11 22:03:48 +00001450 return m_dysymtab.nlocalsym <= 1;
Greg Clayton3046e662013-07-10 01:23:25 +00001451 return false;
1452}
Greg Clayton1eac0c72012-04-24 03:06:13 +00001453
Greg Clayton3046e662013-07-10 01:23:25 +00001454void
1455ObjectFileMachO::CreateSections (SectionList &unified_section_list)
1456{
1457 if (!m_sections_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001458 {
Greg Clayton3046e662013-07-10 01:23:25 +00001459 m_sections_ap.reset(new SectionList());
1460
Charles Davis510938e2013-08-27 05:04:57 +00001461 const bool is_dsym = (m_header.filetype == MH_DSYM);
Greg Clayton3046e662013-07-10 01:23:25 +00001462 lldb::user_id_t segID = 0;
1463 lldb::user_id_t sectID = 0;
1464 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1465 uint32_t i;
1466 const bool is_core = GetType() == eTypeCoreFile;
1467 //bool dump_sections = false;
1468 ModuleSP module_sp (GetModule());
1469 // First look up any LC_ENCRYPTION_INFO load commands
1470 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
1471 EncryptedFileRanges encrypted_file_ranges;
1472 encryption_info_command encryption_cmd;
1473 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001474 {
Greg Clayton3046e662013-07-10 01:23:25 +00001475 const lldb::offset_t load_cmd_offset = offset;
1476 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
1477 break;
1478
Jason Molendadfb02a92015-04-02 05:19:33 +00001479 // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
1480 // the 3 fields we care about, so treat them the same.
1481 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO || encryption_cmd.cmd == LC_ENCRYPTION_INFO_64)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001482 {
Greg Clayton3046e662013-07-10 01:23:25 +00001483 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001484 {
Greg Clayton3046e662013-07-10 01:23:25 +00001485 if (encryption_cmd.cryptid != 0)
Greg Claytond37d6922013-04-16 16:51:19 +00001486 {
Greg Clayton3046e662013-07-10 01:23:25 +00001487 EncryptedFileRanges::Entry entry;
1488 entry.SetRangeBase(encryption_cmd.cryptoff);
1489 entry.SetByteSize(encryption_cmd.cryptsize);
1490 encrypted_file_ranges.Append(entry);
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001491 }
1492 }
Greg Clayton3046e662013-07-10 01:23:25 +00001493 }
1494 offset = load_cmd_offset + encryption_cmd.cmdsize;
1495 }
1496
Jason Molenda05a09c62014-08-22 02:46:46 +00001497 bool section_file_addresses_changed = false;
1498
Greg Clayton3046e662013-07-10 01:23:25 +00001499 offset = MachHeaderSizeFromMagic(m_header.magic);
1500
1501 struct segment_command_64 load_cmd;
1502 for (i=0; i<m_header.ncmds; ++i)
1503 {
1504 const lldb::offset_t load_cmd_offset = offset;
1505 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1506 break;
1507
Charles Davis510938e2013-08-27 05:04:57 +00001508 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
Greg Clayton3046e662013-07-10 01:23:25 +00001509 {
1510 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001511 {
Greg Clayton3046e662013-07-10 01:23:25 +00001512 bool add_section = true;
1513 bool add_to_unified = true;
1514 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 +00001515
Greg Clayton3046e662013-07-10 01:23:25 +00001516 SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
1517 if (is_dsym && unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001518 {
Greg Clayton3046e662013-07-10 01:23:25 +00001519 if (const_segname == GetSegmentNameLINKEDIT())
1520 {
1521 // We need to keep the __LINKEDIT segment private to this object file only
1522 add_to_unified = false;
1523 }
1524 else
1525 {
1526 // This is the dSYM file and this section has already been created by
1527 // the object file, no need to create it.
1528 add_section = false;
1529 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001530 }
Greg Clayton3046e662013-07-10 01:23:25 +00001531 load_cmd.vmaddr = m_data.GetAddress(&offset);
1532 load_cmd.vmsize = m_data.GetAddress(&offset);
1533 load_cmd.fileoff = m_data.GetAddress(&offset);
1534 load_cmd.filesize = m_data.GetAddress(&offset);
1535 if (m_length != 0 && load_cmd.filesize != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001536 {
Greg Clayton3046e662013-07-10 01:23:25 +00001537 if (load_cmd.fileoff > m_length)
1538 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001539 // 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 +00001540 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001541 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001542 // is null out the SectionList vector and if a process has been set up, dump a message
1543 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001544 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001545 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 +00001546 i,
1547 lc_segment_name,
1548 load_cmd.fileoff,
1549 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001550
1551 load_cmd.fileoff = 0;
1552 load_cmd.filesize = 0;
1553 }
1554
1555 if (load_cmd.fileoff + load_cmd.filesize > m_length)
1556 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001557 // 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 +00001558 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001559 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001560 // is null out the SectionList vector and if a process has been set up, dump a message
1561 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001562 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001563 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 +00001564 i,
1565 lc_segment_name,
1566 load_cmd.fileoff + load_cmd.filesize,
1567 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001568
1569 // Tuncase the length
1570 load_cmd.filesize = m_length - load_cmd.fileoff;
1571 }
1572 }
1573 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
1574 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001575
Charles Davis510938e2013-08-27 05:04:57 +00001576 const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001577
Greg Clayton3046e662013-07-10 01:23:25 +00001578 // Keep a list of mach segments around in case we need to
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001579 // get at data that isn't stored in the abstracted Sections.
Greg Clayton3046e662013-07-10 01:23:25 +00001580 m_mach_segments.push_back (load_cmd);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001581
Greg Clayton3046e662013-07-10 01:23:25 +00001582 // Use a segment ID of the segment index shifted left by 8 so they
1583 // never conflict with any of the sections.
1584 SectionSP segment_sp;
1585 if (add_section && (const_segname || is_core))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001586 {
Greg Clayton3046e662013-07-10 01:23:25 +00001587 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
1588 this, // Object file to which this sections belongs
1589 ++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
1590 const_segname, // Name of this section
1591 eSectionTypeContainer, // This section is a container of other sections.
1592 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
1593 load_cmd.vmsize, // VM size in bytes of this section
1594 load_cmd.fileoff, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001595 load_cmd.filesize, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001596 0, // Segments have no alignment information
Greg Clayton3046e662013-07-10 01:23:25 +00001597 load_cmd.flags)); // Flags for this section
Greg Clayton8d38ac42010-06-28 23:51:11 +00001598
Greg Clayton3046e662013-07-10 01:23:25 +00001599 segment_sp->SetIsEncrypted (segment_is_encrypted);
1600 m_sections_ap->AddSection(segment_sp);
1601 if (add_to_unified)
1602 unified_section_list.AddSection(segment_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001603 }
Greg Clayton3046e662013-07-10 01:23:25 +00001604 else if (unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001605 {
Jason Molenda20eb31b2013-08-16 03:20:42 +00001606 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr)
1607 {
1608 // Check to see if the module was read from memory?
1609 if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid())
1610 {
1611 // We have a module that is in memory and needs to have its
1612 // file address adjusted. We need to do this because when we
1613 // load a file from memory, its addresses will be slid already,
1614 // yet the addresses in the new symbol file will still be unslid.
1615 // Since everything is stored as section offset, this shouldn't
1616 // cause any problems.
Jason Molenda5894a732013-08-17 03:39:52 +00001617
1618 // Make sure we've parsed the symbol table from the
1619 // ObjectFile before we go around changing its Sections.
1620 module_sp->GetObjectFile()->GetSymtab();
1621 // eh_frame would present the same problems but we parse that on
1622 // a per-function basis as-needed so it's more difficult to
1623 // remove its use of the Sections. Realistically, the environments
1624 // where this code path will be taken will not have eh_frame sections.
1625
Jason Molenda20eb31b2013-08-16 03:20:42 +00001626 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
Jason Molenda05a09c62014-08-22 02:46:46 +00001627
1628 // Notify the module that the section addresses have been changed once
1629 // we're done so any file-address caches can be updated.
1630 section_file_addresses_changed = true;
Jason Molenda20eb31b2013-08-16 03:20:42 +00001631 }
1632 }
Greg Clayton3046e662013-07-10 01:23:25 +00001633 m_sections_ap->AddSection(unified_section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001634 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001635
Greg Clayton3046e662013-07-10 01:23:25 +00001636 struct section_64 sect64;
1637 ::memset (&sect64, 0, sizeof(sect64));
1638 // Push a section into our mach sections for the section at
Charles Davis510938e2013-08-27 05:04:57 +00001639 // index zero (NO_SECT) if we don't have any mach sections yet...
Greg Clayton3046e662013-07-10 01:23:25 +00001640 if (m_mach_sections.empty())
1641 m_mach_sections.push_back(sect64);
1642 uint32_t segment_sect_idx;
1643 const lldb::user_id_t first_segment_sectID = sectID + 1;
1644
1645
Charles Davis510938e2013-08-27 05:04:57 +00001646 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
Greg Clayton3046e662013-07-10 01:23:25 +00001647 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648 {
Greg Clayton3046e662013-07-10 01:23:25 +00001649 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
Greg Clayton89411422010-10-08 00:21:05 +00001650 break;
Greg Clayton3046e662013-07-10 01:23:25 +00001651 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
1652 break;
1653 sect64.addr = m_data.GetAddress(&offset);
1654 sect64.size = m_data.GetAddress(&offset);
1655
1656 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
1657 break;
1658
1659 // Keep a list of mach sections around in case we need to
1660 // get at data that isn't stored in the abstracted Sections.
1661 m_mach_sections.push_back (sect64);
1662
1663 if (add_section)
1664 {
1665 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
1666 if (!const_segname)
1667 {
1668 // We have a segment with no name so we need to conjure up
1669 // segments that correspond to the section's segname if there
1670 // isn't already such a section. If there is such a section,
1671 // we resize the section so that it spans all sections.
1672 // We also mark these sections as fake so address matches don't
1673 // hit if they land in the gaps between the child sections.
1674 const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
1675 segment_sp = unified_section_list.FindSectionByName (const_segname);
1676 if (segment_sp.get())
1677 {
1678 Section *segment = segment_sp.get();
1679 // Grow the section size as needed.
1680 const lldb::addr_t sect64_min_addr = sect64.addr;
1681 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1682 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
1683 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
1684 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
1685 if (sect64_min_addr >= curr_seg_min_addr)
1686 {
1687 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
1688 // Only grow the section size if needed
1689 if (new_seg_byte_size > curr_seg_byte_size)
1690 segment->SetByteSize (new_seg_byte_size);
1691 }
1692 else
1693 {
1694 // We need to change the base address of the segment and
1695 // adjust the child section offsets for all existing children.
1696 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
1697 segment->Slide(slide_amount, false);
1698 segment->GetChildren().Slide(-slide_amount, false);
1699 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
1700 }
1701
1702 // Grow the section size as needed.
1703 if (sect64.offset)
1704 {
1705 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
1706 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
1707
1708 const lldb::addr_t section_min_file_offset = sect64.offset;
1709 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
1710 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
1711 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
1712 segment->SetFileOffset (new_file_offset);
1713 segment->SetFileSize (new_file_size);
1714 }
1715 }
1716 else
1717 {
1718 // Create a fake section for the section's named segment
1719 segment_sp.reset(new Section (segment_sp, // Parent section
1720 module_sp, // Module to which this section belongs
1721 this, // Object file to which this section belongs
1722 ++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
1723 const_segname, // Name of this section
1724 eSectionTypeContainer, // This section is a container of other sections.
1725 sect64.addr, // File VM address == addresses as they are found in the object file
1726 sect64.size, // VM size in bytes of this section
1727 sect64.offset, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001728 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001729 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001730 load_cmd.flags)); // Flags for this section
1731 segment_sp->SetIsFake(true);
1732
1733 m_sections_ap->AddSection(segment_sp);
1734 if (add_to_unified)
1735 unified_section_list.AddSection(segment_sp);
1736 segment_sp->SetIsEncrypted (segment_is_encrypted);
1737 }
1738 }
1739 assert (segment_sp.get());
1740
Charles Davis510938e2013-08-27 05:04:57 +00001741 lldb::SectionType sect_type = eSectionTypeOther;
Greg Clayton3046e662013-07-10 01:23:25 +00001742
Greg Clayton38f9cc42014-06-16 22:53:16 +00001743 if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1744 sect_type = eSectionTypeCode;
1745 else
Greg Clayton3046e662013-07-10 01:23:25 +00001746 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001747 uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
1748 static ConstString g_sect_name_objc_data ("__objc_data");
1749 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
1750 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
1751 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
1752 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
1753 static ConstString g_sect_name_objc_const ("__objc_const");
1754 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
1755 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton3046e662013-07-10 01:23:25 +00001756
Greg Clayton38f9cc42014-06-16 22:53:16 +00001757 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
1758 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
1759 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
1760 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
1761 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
1762 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
1763 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
1764 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
1765 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
1766 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
1767 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
1768 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
1769 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
1770 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
1771 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
1772 static ConstString g_sect_name_eh_frame ("__eh_frame");
Jason Molendae589e7e2014-12-08 03:09:00 +00001773 static ConstString g_sect_name_compact_unwind ("__unwind_info");
Greg Clayton38f9cc42014-06-16 22:53:16 +00001774 static ConstString g_sect_name_text ("__text");
1775 static ConstString g_sect_name_data ("__data");
Ryan Brown65d4d5c2015-09-16 21:20:44 +00001776 static ConstString g_sect_name_go_symtab ("__gosymtab");
Greg Clayton38f9cc42014-06-16 22:53:16 +00001777
1778
1779 if (section_name == g_sect_name_dwarf_debug_abbrev)
1780 sect_type = eSectionTypeDWARFDebugAbbrev;
1781 else if (section_name == g_sect_name_dwarf_debug_aranges)
1782 sect_type = eSectionTypeDWARFDebugAranges;
1783 else if (section_name == g_sect_name_dwarf_debug_frame)
1784 sect_type = eSectionTypeDWARFDebugFrame;
1785 else if (section_name == g_sect_name_dwarf_debug_info)
1786 sect_type = eSectionTypeDWARFDebugInfo;
1787 else if (section_name == g_sect_name_dwarf_debug_line)
1788 sect_type = eSectionTypeDWARFDebugLine;
1789 else if (section_name == g_sect_name_dwarf_debug_loc)
1790 sect_type = eSectionTypeDWARFDebugLoc;
1791 else if (section_name == g_sect_name_dwarf_debug_macinfo)
1792 sect_type = eSectionTypeDWARFDebugMacInfo;
1793 else if (section_name == g_sect_name_dwarf_debug_pubnames)
1794 sect_type = eSectionTypeDWARFDebugPubNames;
1795 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
1796 sect_type = eSectionTypeDWARFDebugPubTypes;
1797 else if (section_name == g_sect_name_dwarf_debug_ranges)
1798 sect_type = eSectionTypeDWARFDebugRanges;
1799 else if (section_name == g_sect_name_dwarf_debug_str)
1800 sect_type = eSectionTypeDWARFDebugStr;
1801 else if (section_name == g_sect_name_dwarf_apple_names)
1802 sect_type = eSectionTypeDWARFAppleNames;
1803 else if (section_name == g_sect_name_dwarf_apple_types)
1804 sect_type = eSectionTypeDWARFAppleTypes;
1805 else if (section_name == g_sect_name_dwarf_apple_namespaces)
1806 sect_type = eSectionTypeDWARFAppleNamespaces;
1807 else if (section_name == g_sect_name_dwarf_apple_objc)
1808 sect_type = eSectionTypeDWARFAppleObjC;
1809 else if (section_name == g_sect_name_objc_selrefs)
1810 sect_type = eSectionTypeDataCStringPointers;
1811 else if (section_name == g_sect_name_objc_msgrefs)
1812 sect_type = eSectionTypeDataObjCMessageRefs;
1813 else if (section_name == g_sect_name_eh_frame)
1814 sect_type = eSectionTypeEHFrame;
Jason Molendae589e7e2014-12-08 03:09:00 +00001815 else if (section_name == g_sect_name_compact_unwind)
1816 sect_type = eSectionTypeCompactUnwind;
Greg Clayton38f9cc42014-06-16 22:53:16 +00001817 else if (section_name == g_sect_name_cfstring)
1818 sect_type = eSectionTypeDataObjCCFStrings;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00001819 else if (section_name == g_sect_name_go_symtab)
1820 sect_type = eSectionTypeGoSymtab;
Greg Clayton38f9cc42014-06-16 22:53:16 +00001821 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:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001941 MachSymtabSectionInfo (SectionList *section_list) :
1942 m_section_list (section_list),
1943 m_section_infos()
1944 {
1945 // Get the number of sections down to a depth of 1 to include
1946 // all segments and their sections, but no other sections that
1947 // may be added for debug map or
1948 m_section_infos.resize(section_list->GetNumSections(1));
1949 }
1950
Greg Claytone72dfb32012-02-24 01:59:29 +00001951 SectionSP
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001952 GetSection (uint8_t n_sect, addr_t file_addr)
1953 {
1954 if (n_sect == 0)
Greg Claytone72dfb32012-02-24 01:59:29 +00001955 return SectionSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001956 if (n_sect < m_section_infos.size())
1957 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001958 if (!m_section_infos[n_sect].section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001959 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001960 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1961 m_section_infos[n_sect].section_sp = section_sp;
Sean Callanan9a028512012-08-09 00:50:26 +00001962 if (section_sp)
Greg Claytondda0d122011-07-10 17:32:33 +00001963 {
Greg Claytone72dfb32012-02-24 01:59:29 +00001964 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1965 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Claytondda0d122011-07-10 17:32:33 +00001966 }
1967 else
1968 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00001969 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Claytondda0d122011-07-10 17:32:33 +00001970 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001971 }
1972 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton8f258512011-08-26 20:01:35 +00001973 {
1974 // Symbol is in section.
Greg Claytone72dfb32012-02-24 01:59:29 +00001975 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001976 }
1977 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1978 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1979 {
1980 // Symbol is in section with zero size, but has the same start
1981 // address as the section. This can happen with linker symbols
1982 // (symbols that start with the letter 'l' or 'L'.
Greg Claytone72dfb32012-02-24 01:59:29 +00001983 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00001984 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001985 }
Greg Claytone72dfb32012-02-24 01:59:29 +00001986 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001987 }
1988
1989protected:
1990 struct SectionInfo
1991 {
1992 SectionInfo () :
1993 vm_range(),
Greg Claytone72dfb32012-02-24 01:59:29 +00001994 section_sp ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001995 {
1996 }
1997
1998 VMRange vm_range;
Greg Claytone72dfb32012-02-24 01:59:29 +00001999 SectionSP section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002000 };
2001 SectionList *m_section_list;
2002 std::vector<SectionInfo> m_section_infos;
2003};
2004
Greg Clayton9191db42013-10-21 18:40:51 +00002005struct TrieEntry
2006{
2007 TrieEntry () :
2008 name(),
2009 address(LLDB_INVALID_ADDRESS),
2010 flags (0),
2011 other(0),
2012 import_name()
2013 {
2014 }
2015
2016 void
2017 Clear ()
2018 {
2019 name.Clear();
2020 address = LLDB_INVALID_ADDRESS;
2021 flags = 0;
2022 other = 0;
2023 import_name.Clear();
2024 }
2025
2026 void
2027 Dump () const
2028 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002029 printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2030 static_cast<unsigned long long>(address),
2031 static_cast<unsigned long long>(flags),
2032 static_cast<unsigned long long>(other), name.GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +00002033 if (import_name)
2034 printf (" -> \"%s\"\n", import_name.GetCString());
2035 else
2036 printf ("\n");
2037 }
2038 ConstString name;
2039 uint64_t address;
2040 uint64_t flags;
2041 uint64_t other;
2042 ConstString import_name;
2043};
2044
2045struct TrieEntryWithOffset
2046{
2047 lldb::offset_t nodeOffset;
2048 TrieEntry entry;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002049
Greg Clayton9191db42013-10-21 18:40:51 +00002050 TrieEntryWithOffset (lldb::offset_t offset) :
2051 nodeOffset (offset),
2052 entry()
2053 {
2054 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002055
Greg Clayton9191db42013-10-21 18:40:51 +00002056 void
2057 Dump (uint32_t idx) const
2058 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002059 printf ("[%3u] 0x%16.16llx: ", idx,
2060 static_cast<unsigned long long>(nodeOffset));
Greg Clayton9191db42013-10-21 18:40:51 +00002061 entry.Dump();
2062 }
2063
2064 bool
2065 operator<(const TrieEntryWithOffset& other) const
2066 {
2067 return ( nodeOffset < other.nodeOffset );
2068 }
2069};
2070
Greg Clayton8f265f72015-10-28 20:49:34 +00002071static bool
Greg Clayton9191db42013-10-21 18:40:51 +00002072ParseTrieEntries (DataExtractor &data,
2073 lldb::offset_t offset,
Greg Claytonb887da12015-07-16 19:50:57 +00002074 const bool is_arm,
Greg Clayton9191db42013-10-21 18:40:51 +00002075 std::vector<llvm::StringRef> &nameSlices,
2076 std::set<lldb::addr_t> &resolver_addresses,
2077 std::vector<TrieEntryWithOffset>& output)
2078{
2079 if (!data.ValidOffset(offset))
Greg Clayton8f265f72015-10-28 20:49:34 +00002080 return true;
Greg Clayton9191db42013-10-21 18:40:51 +00002081
2082 const uint64_t terminalSize = data.GetULEB128(&offset);
2083 lldb::offset_t children_offset = offset + terminalSize;
2084 if ( terminalSize != 0 ) {
2085 TrieEntryWithOffset e (offset);
2086 e.entry.flags = data.GetULEB128(&offset);
2087 const char *import_name = NULL;
2088 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
2089 e.entry.address = 0;
2090 e.entry.other = data.GetULEB128(&offset); // dylib ordinal
2091 import_name = data.GetCStr(&offset);
2092 }
2093 else {
2094 e.entry.address = data.GetULEB128(&offset);
2095 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
2096 {
Greg Clayton9191db42013-10-21 18:40:51 +00002097 e.entry.other = data.GetULEB128(&offset);
Greg Claytonb887da12015-07-16 19:50:57 +00002098 uint64_t resolver_addr = e.entry.other;
2099 if (is_arm)
2100 resolver_addr &= THUMB_ADDRESS_BIT_MASK;
2101 resolver_addresses.insert(resolver_addr);
Greg Clayton9191db42013-10-21 18:40:51 +00002102 }
2103 else
2104 e.entry.other = 0;
2105 }
2106 // Only add symbols that are reexport symbols with a valid import name
2107 if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
2108 {
2109 std::string name;
2110 if (!nameSlices.empty())
2111 {
2112 for (auto name_slice: nameSlices)
2113 name.append(name_slice.data(), name_slice.size());
2114 }
2115 if (name.size() > 1)
2116 {
2117 // Skip the leading '_'
2118 e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
2119 }
2120 if (import_name)
2121 {
2122 // Skip the leading '_'
2123 e.entry.import_name.SetCString(import_name+1);
2124 }
2125 output.push_back(e);
2126 }
2127 }
2128
2129 const uint8_t childrenCount = data.GetU8(&children_offset);
2130 for (uint8_t i=0; i < childrenCount; ++i) {
Greg Clayton8f265f72015-10-28 20:49:34 +00002131 const char *cstr = data.GetCStr(&children_offset);
2132 if (cstr)
2133 nameSlices.push_back(llvm::StringRef(cstr));
2134 else
2135 return false; // Corrupt data
Greg Clayton9191db42013-10-21 18:40:51 +00002136 lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
2137 if (childNodeOffset)
2138 {
Greg Clayton8f265f72015-10-28 20:49:34 +00002139 if (!ParseTrieEntries(data,
2140 childNodeOffset,
2141 is_arm,
2142 nameSlices,
2143 resolver_addresses,
2144 output))
2145 {
2146 return false;
2147 }
Greg Clayton9191db42013-10-21 18:40:51 +00002148 }
2149 nameSlices.pop_back();
2150 }
Greg Clayton8f265f72015-10-28 20:49:34 +00002151 return true;
Greg Clayton9191db42013-10-21 18:40:51 +00002152}
2153
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002154size_t
Greg Clayton3046e662013-07-10 01:23:25 +00002155ObjectFileMachO::ParseSymtab ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002156{
2157 Timer scoped_timer(__PRETTY_FUNCTION__,
2158 "ObjectFileMachO::ParseSymtab () module = %s",
2159 m_file.GetFilename().AsCString(""));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002160 ModuleSP module_sp (GetModule());
2161 if (!module_sp)
2162 return 0;
2163
2164 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
2165 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
Greg Clayton9191db42013-10-21 18:40:51 +00002166 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 +00002167 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
2168 FunctionStarts function_starts;
Greg Claytonc7bece562013-01-25 18:06:21 +00002169 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002170 uint32_t i;
Greg Clayton9191db42013-10-21 18:40:51 +00002171 FileSpecList dylib_files;
Greg Clayton5160ce52013-03-27 23:08:40 +00002172 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
Greg Clayton1e28adf2015-02-25 17:25:02 +00002173 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2174 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2175 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
Greg Clayton77ccca72011-12-30 00:32:24 +00002176
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002177 for (i=0; i<m_header.ncmds; ++i)
2178 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002179 const lldb::offset_t cmd_offset = offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002180 // Read in the load command and load command size
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002181 struct load_command lc;
2182 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002183 break;
2184 // Watch for the symbol table load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002185 switch (lc.cmd)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002186 {
Charles Davis510938e2013-08-27 05:04:57 +00002187 case LC_SYMTAB:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002188 symtab_load_command.cmd = lc.cmd;
2189 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002190 // Read in the rest of the symtab load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002191 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
2192 return 0;
2193 if (symtab_load_command.symoff == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002194 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002195 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002196 module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002197 return 0;
2198 }
2199
2200 if (symtab_load_command.stroff == 0)
2201 {
2202 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002203 module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002204 return 0;
2205 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002206
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002207 if (symtab_load_command.nsyms == 0)
2208 {
2209 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002210 module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002211 return 0;
2212 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002213
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002214 if (symtab_load_command.strsize == 0)
2215 {
2216 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002217 module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002218 return 0;
2219 }
2220 break;
2221
Greg Clayton9191db42013-10-21 18:40:51 +00002222 case LC_DYLD_INFO:
2223 case LC_DYLD_INFO_ONLY:
2224 if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
2225 {
2226 dyld_info.cmd = lc.cmd;
2227 dyld_info.cmdsize = lc.cmdsize;
2228 }
2229 else
2230 {
2231 memset (&dyld_info, 0, sizeof(dyld_info));
2232 }
2233 break;
2234
2235 case LC_LOAD_DYLIB:
2236 case LC_LOAD_WEAK_DYLIB:
2237 case LC_REEXPORT_DYLIB:
2238 case LC_LOADFVMLIB:
2239 case LC_LOAD_UPWARD_DYLIB:
2240 {
2241 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2242 const char *path = m_data.PeekCStr(name_offset);
2243 if (path)
2244 {
2245 FileSpec file_spec(path, false);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002246 // Strip the path if there is @rpath, @executable, etc so we just use the basename
Greg Clayton9191db42013-10-21 18:40:51 +00002247 if (path[0] == '@')
2248 file_spec.GetDirectory().Clear();
Jim Inghamfbe0b9a2014-05-21 03:58:03 +00002249
2250 if (lc.cmd == LC_REEXPORT_DYLIB)
2251 {
2252 m_reexported_dylibs.AppendIfUnique(file_spec);
2253 }
Greg Clayton9191db42013-10-21 18:40:51 +00002254
2255 dylib_files.Append(file_spec);
2256 }
2257 }
2258 break;
2259
Charles Davis510938e2013-08-27 05:04:57 +00002260 case LC_FUNCTION_STARTS:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002261 function_starts_load_command.cmd = lc.cmd;
2262 function_starts_load_command.cmdsize = lc.cmdsize;
2263 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 +00002264 memset (&function_starts_load_command, 0, sizeof(function_starts_load_command));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002265 break;
2266
2267 default:
2268 break;
2269 }
2270 offset = cmd_offset + lc.cmdsize;
2271 }
2272
2273 if (symtab_load_command.cmd)
2274 {
2275 Symtab *symtab = m_symtab_ap.get();
2276 SectionList *section_list = GetSectionList();
2277 if (section_list == NULL)
2278 return 0;
2279
Greg Claytonc7bece562013-01-25 18:06:21 +00002280 const uint32_t addr_byte_size = m_data.GetAddressByteSize();
2281 const ByteOrder byte_order = m_data.GetByteOrder();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002282 bool bit_width_32 = addr_byte_size == 4;
2283 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
2284
Greg Claytonc7bece562013-01-25 18:06:21 +00002285 DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
2286 DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
2287 DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
Jason Molendad34e6522013-02-05 22:31:24 +00002288 DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002289 DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);
Jason Molenda4e7511e2013-03-06 23:19:17 +00002290
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002291 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
2292 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Clayton4c82d422012-05-18 23:20:01 +00002293 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
Greg Claytonfd814c52013-08-13 01:42:25 +00002294
2295 ProcessSP process_sp (m_process_wp.lock());
2296 Process *process = process_sp.get();
2297
Greg Clayton86eac942013-08-13 21:32:34 +00002298 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
2299
Greg Clayton48672af2014-06-24 22:22:43 +00002300 if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002301 {
Greg Clayton4c82d422012-05-18 23:20:01 +00002302 Target &target = process->GetTarget();
Greg Claytonfd814c52013-08-13 01:42:25 +00002303
Greg Clayton86eac942013-08-13 21:32:34 +00002304 memory_module_load_level = target.GetMemoryModuleLoadLevel();
Greg Claytonfd814c52013-08-13 01:42:25 +00002305
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002306 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2307 // Reading mach file from memory in a process or core file...
2308
2309 if (linkedit_section_sp)
2310 {
Greg Clayton07347372015-06-08 21:53:11 +00002311 addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
2312 if (linkedit_load_addr == LLDB_INVALID_ADDRESS)
2313 {
2314 // We might be trying to access the symbol table before the __LINKEDIT's load
2315 // address has been set in the target. We can't fail to read the symbol table,
2316 // so calculate the right address manually
2317 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2318 }
2319
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002320 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2321 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Clayton4c82d422012-05-18 23:20:01 +00002322 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton26b47e22012-04-18 05:19:20 +00002323
2324 bool data_was_read = false;
2325
Todd Fiala013434e2014-07-09 01:29:05 +00002326#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa3329782014-03-29 18:54:20 +00002327 if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
Greg Clayton77ccca72011-12-30 00:32:24 +00002328 {
Greg Clayton26b47e22012-04-18 05:19:20 +00002329 // This mach-o memory file is in the dyld shared cache. If this
2330 // program is not remote and this is iOS, then this process will
2331 // share the same shared cache as the process we are debugging and
2332 // we can read the entire __LINKEDIT from the address space in this
2333 // process. This is a needed optimization that is used for local iOS
2334 // debugging only since all shared libraries in the shared cache do
2335 // not have corresponding files that exist in the file system of the
2336 // device. They have been combined into a single file. This means we
2337 // always have to load these files from memory. All of the symbol and
2338 // string tables from all of the __LINKEDIT sections from the shared
2339 // libraries in the shared cache have been merged into a single large
2340 // symbol and string table. Reading all of this symbol and string table
2341 // data across can slow down debug launch times, so we optimize this by
2342 // reading the memory for the __LINKEDIT section from this process.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002343
2344 UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
2345 UUID process_shared_cache(GetProcessSharedCacheUUID(process));
2346 bool use_lldb_cache = true;
2347 if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache)
2348 {
2349 use_lldb_cache = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002350 ModuleSP module_sp (GetModule());
2351 if (module_sp)
2352 module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow.");
2353
Jason Molenda0e0954c2013-04-16 06:24:42 +00002354 }
2355
Greg Clayton26b47e22012-04-18 05:19:20 +00002356 PlatformSP platform_sp (target.GetPlatform());
Jason Molenda0e0954c2013-04-16 06:24:42 +00002357 if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
Greg Clayton26b47e22012-04-18 05:19:20 +00002358 {
2359 data_was_read = true;
2360 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Clayton4c82d422012-05-18 23:20:01 +00002361 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton26b47e22012-04-18 05:19:20 +00002362 if (function_starts_load_command.cmd)
2363 {
2364 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2365 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
2366 }
2367 }
2368 }
2369#endif
2370
2371 if (!data_was_read)
2372 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002373 if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
Jason Molendad34e6522013-02-05 22:31:24 +00002374 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002375 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
2376 if (nlist_data_sp)
2377 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2378 // Load strings individually from memory when loading from memory since shared cache
2379 // string tables contain strings for all symbols from all shared cached libraries
2380 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
2381 //if (strtab_data_sp)
2382 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
2383 if (m_dysymtab.nindirectsyms != 0)
2384 {
2385 const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
2386 DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
2387 if (indirect_syms_data_sp)
2388 indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2389 }
Jason Molendad34e6522013-02-05 22:31:24 +00002390 }
Greg Claytonfd814c52013-08-13 01:42:25 +00002391
2392 if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
Greg Clayton26b47e22012-04-18 05:19:20 +00002393 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002394 if (function_starts_load_command.cmd)
2395 {
2396 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2397 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
2398 if (func_start_data_sp)
2399 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
2400 }
Greg Clayton26b47e22012-04-18 05:19:20 +00002401 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002402 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002403 }
2404 }
2405 else
2406 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002407 nlist_data.SetData (m_data,
2408 symtab_load_command.symoff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002409 nlist_data_byte_size);
2410 strtab_data.SetData (m_data,
Jason Molenda4e7511e2013-03-06 23:19:17 +00002411 symtab_load_command.stroff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002412 strtab_data_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002413
2414 if (dyld_info.export_size > 0)
2415 {
2416 dyld_trie_data.SetData (m_data,
2417 dyld_info.export_off,
2418 dyld_info.export_size);
2419 }
2420
Jason Molendad34e6522013-02-05 22:31:24 +00002421 if (m_dysymtab.nindirectsyms != 0)
2422 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002423 indirect_symbol_index_data.SetData (m_data,
2424 m_dysymtab.indirectsymoff,
Jason Molendad34e6522013-02-05 22:31:24 +00002425 m_dysymtab.nindirectsyms * 4);
2426 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002427 if (function_starts_load_command.cmd)
2428 {
2429 function_starts_data.SetData (m_data,
2430 function_starts_load_command.dataoff,
2431 function_starts_load_command.datasize);
2432 }
2433 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002434
Greg Clayton86eac942013-08-13 21:32:34 +00002435 if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete)
2436 {
2437 if (log)
2438 module_sp->LogMessage(log, "failed to read nlist data");
2439 return 0;
2440 }
2441
Greg Claytondebb8812012-05-25 17:04:00 +00002442 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2443 if (!have_strtab_data)
Greg Clayton4c82d422012-05-18 23:20:01 +00002444 {
Greg Claytondebb8812012-05-25 17:04:00 +00002445 if (process)
2446 {
2447 if (strtab_addr == LLDB_INVALID_ADDRESS)
2448 {
2449 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002450 module_sp->LogMessage(log, "failed to locate the strtab in memory");
Greg Claytondebb8812012-05-25 17:04:00 +00002451 return 0;
2452 }
2453 }
2454 else
Greg Clayton4c82d422012-05-18 23:20:01 +00002455 {
2456 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002457 module_sp->LogMessage(log, "failed to read strtab data");
Greg Clayton4c82d422012-05-18 23:20:01 +00002458 return 0;
2459 }
2460 }
Greg Clayton4c82d422012-05-18 23:20:01 +00002461
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002462 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
2463 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
Greg Claytona381e102015-07-27 23:21:05 +00002464 const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
2465 const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002466 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
2467 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
2468 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
2469 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
Greg Claytona381e102015-07-27 23:21:05 +00002470 SectionSP data_dirty_section_sp(section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2471 SectionSP data_const_section_sp(section_list->FindSectionByName(g_segment_name_DATA_CONST));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002472 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
2473 SectionSP eh_frame_section_sp;
2474 if (text_section_sp.get())
2475 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
2476 else
2477 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
2478
Charles Davis510938e2013-08-27 05:04:57 +00002479 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
Jason Molenda5635f772013-03-21 03:36:01 +00002480
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002481 // lldb works best if it knows the start address of all functions in a module.
Jason Molenda5635f772013-03-21 03:36:01 +00002482 // Linker symbols or debug info are normally the best source of information for start addr / size but
2483 // they may be stripped in a released binary.
Jason Molendad63d3c72013-04-16 00:18:44 +00002484 // Two additional sources of information exist in Mach-O binaries:
Jason Molenda5635f772013-03-21 03:36:01 +00002485 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
2486 // binary, relative to the text section.
2487 // eh_frame - the eh_frame FDEs have the start addr & size of each function
2488 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
2489 // Binaries built to run on older releases may need to use eh_frame information.
2490
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002491 if (text_section_sp && function_starts_data.GetByteSize())
2492 {
2493 FunctionStarts::Entry function_start_entry;
2494 function_start_entry.data = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00002495 lldb::offset_t function_start_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002496 function_start_entry.addr = text_section_sp->GetFileAddress();
2497 uint64_t delta;
2498 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
2499 {
2500 // Now append the current entry
2501 function_start_entry.addr += delta;
2502 function_starts.Append(function_start_entry);
2503 }
Jason Molendad63d3c72013-04-16 00:18:44 +00002504 }
Jason Molenda5635f772013-03-21 03:36:01 +00002505 else
2506 {
Jason Molenda584ce2f2013-03-22 00:38:45 +00002507 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
2508 // but it doesn't actually have the eh_frame content. And if we have a dSYM, we don't need to do any
2509 // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
2510 // the module.
2511 if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
Jason Molenda5635f772013-03-21 03:36:01 +00002512 {
Jason Molendaa18f7072015-08-15 01:21:01 +00002513 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindEHFrame, true);
Jason Molenda5635f772013-03-21 03:36:01 +00002514 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
2515 eh_frame.GetFunctionAddressAndSizeVector (functions);
2516 addr_t text_base_addr = text_section_sp->GetFileAddress();
2517 size_t count = functions.GetSize();
2518 for (size_t i = 0; i < count; ++i)
2519 {
2520 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
2521 if (func)
2522 {
2523 FunctionStarts::Entry function_start_entry;
2524 function_start_entry.addr = func->base - text_base_addr;
2525 function_starts.Append(function_start_entry);
2526 }
2527 }
2528 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002529 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002530
Greg Claytonc7bece562013-01-25 18:06:21 +00002531 const size_t function_starts_count = function_starts.GetSize();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002532
Saleem Abdulrasoolb5c128b2014-07-23 01:53:52 +00002533 const user_id_t TEXT_eh_frame_sectID =
2534 eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
2535 : static_cast<user_id_t>(NO_SECT);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002536
Greg Claytonc7bece562013-01-25 18:06:21 +00002537 lldb::offset_t nlist_data_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002538
2539 uint32_t N_SO_index = UINT32_MAX;
2540
2541 MachSymtabSectionInfo section_info (section_list);
2542 std::vector<uint32_t> N_FUN_indexes;
2543 std::vector<uint32_t> N_NSYM_indexes;
2544 std::vector<uint32_t> N_INCL_indexes;
2545 std::vector<uint32_t> N_BRAC_indexes;
2546 std::vector<uint32_t> N_COMM_indexes;
Greg Claytond81088c2014-01-16 01:38:29 +00002547 typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002548 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
Greg Claytondacc4a92013-05-14 22:19:37 +00002549 typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002550 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2551 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
Greg Claytondacc4a92013-05-14 22:19:37 +00002552 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002553 // Any symbols that get merged into another will get an entry
2554 // in this map so we know
2555 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2556 uint32_t nlist_idx = 0;
2557 Symbol *symbol_ptr = NULL;
2558
2559 uint32_t sym_idx = 0;
Jason Molendaa5609c82012-06-21 01:51:02 +00002560 Symbol *sym = NULL;
Greg Claytonc7bece562013-01-25 18:06:21 +00002561 size_t num_syms = 0;
Greg Clayton4c82d422012-05-18 23:20:01 +00002562 std::string memory_symbol_name;
Jason Molendaa5609c82012-06-21 01:51:02 +00002563 uint32_t unmapped_local_symbols_found = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002564
Jim Inghamea3ac272014-01-10 22:55:37 +00002565 std::vector<TrieEntryWithOffset> trie_entries;
2566 std::set<lldb::addr_t> resolver_addresses;
2567
2568 if (dyld_trie_data.GetByteSize() > 0)
2569 {
2570 std::vector<llvm::StringRef> nameSlices;
2571 ParseTrieEntries (dyld_trie_data,
2572 0,
Greg Claytonb887da12015-07-16 19:50:57 +00002573 is_arm,
Jim Inghamea3ac272014-01-10 22:55:37 +00002574 nameSlices,
2575 resolver_addresses,
2576 trie_entries);
2577
2578 ConstString text_segment_name ("__TEXT");
2579 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2580 if (text_segment_sp)
2581 {
2582 const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
2583 if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
2584 {
2585 for (auto &e : trie_entries)
2586 e.entry.address += text_segment_file_addr;
2587 }
2588 }
2589 }
2590
Greg Claytonb65c6292015-02-20 22:20:05 +00002591 typedef std::set<ConstString> IndirectSymbols;
2592 IndirectSymbols indirect_symbol_names;
2593
Todd Fiala013434e2014-07-09 01:29:05 +00002594#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa5609c82012-06-21 01:51:02 +00002595
2596 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
2597 // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
2598 // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
2599 // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
2600 // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
2601 // nlist parser to ignore all LOCAL symbols.
2602
2603 if (m_header.flags & 0x80000000u)
2604 {
2605 // Before we can start mapping the DSC, we need to make certain the target process is actually
2606 // using the cache we can find.
2607
Jason Molendaa5609c82012-06-21 01:51:02 +00002608 // Next we need to determine the correct path for the dyld shared cache.
2609
Greg Clayton7ab7f892014-05-29 21:33:45 +00002610 ArchSpec header_arch;
2611 GetArchitecture(header_arch);
Jason Molendaa5609c82012-06-21 01:51:02 +00002612 char dsc_path[PATH_MAX];
2613
2614 snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
Jason Molenda4e7511e2013-03-06 23:19:17 +00002615 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
2616 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
Jason Molendaa5609c82012-06-21 01:51:02 +00002617 header_arch.GetArchitectureName());
2618
2619 FileSpec dsc_filespec(dsc_path, false);
2620
2621 // We need definitions of two structures in the on-disk DSC, copy them here manually
Jason Molendad63d3c72013-04-16 00:18:44 +00002622 struct lldb_copy_dyld_cache_header_v0
Greg Clayton946f8902012-09-05 22:30:51 +00002623 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002624 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2625 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2626 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
Jason Molenda4e7511e2013-03-06 23:19:17 +00002627 uint32_t imagesOffset;
2628 uint32_t imagesCount;
2629 uint64_t dyldBaseAddress;
2630 uint64_t codeSignatureOffset;
2631 uint64_t codeSignatureSize;
2632 uint64_t slideInfoOffset;
2633 uint64_t slideInfoSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002634 uint64_t localSymbolsOffset; // file offset of where local symbols are stored
2635 uint64_t localSymbolsSize; // size of local symbols information
2636 };
Eugene Zelenko8157a882015-10-23 16:56:07 +00002637
Jason Molendad63d3c72013-04-16 00:18:44 +00002638 struct lldb_copy_dyld_cache_header_v1
2639 {
2640 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
2641 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
2642 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
2643 uint32_t imagesOffset;
2644 uint32_t imagesCount;
2645 uint64_t dyldBaseAddress;
2646 uint64_t codeSignatureOffset;
2647 uint64_t codeSignatureSize;
2648 uint64_t slideInfoOffset;
2649 uint64_t slideInfoSize;
Jason Molenda4e7511e2013-03-06 23:19:17 +00002650 uint64_t localSymbolsOffset;
2651 uint64_t localSymbolsSize;
Jason Molendad63d3c72013-04-16 00:18:44 +00002652 uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later
Greg Clayton946f8902012-09-05 22:30:51 +00002653 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002654
Jason Molendad63d3c72013-04-16 00:18:44 +00002655 struct lldb_copy_dyld_cache_mapping_info
2656 {
2657 uint64_t address;
2658 uint64_t size;
2659 uint64_t fileOffset;
2660 uint32_t maxProt;
2661 uint32_t initProt;
2662 };
Jason Molenda255f9bb2013-03-06 23:17:36 +00002663
Greg Clayton946f8902012-09-05 22:30:51 +00002664 struct lldb_copy_dyld_cache_local_symbols_info
2665 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002666 uint32_t nlistOffset;
2667 uint32_t nlistCount;
2668 uint32_t stringsOffset;
2669 uint32_t stringsSize;
2670 uint32_t entriesOffset;
2671 uint32_t entriesCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002672 };
Eugene Zelenko8157a882015-10-23 16:56:07 +00002673
Greg Clayton946f8902012-09-05 22:30:51 +00002674 struct lldb_copy_dyld_cache_local_symbols_entry
2675 {
Jason Molendad63d3c72013-04-16 00:18:44 +00002676 uint32_t dylibOffset;
2677 uint32_t nlistStartIndex;
2678 uint32_t nlistCount;
Greg Clayton946f8902012-09-05 22:30:51 +00002679 };
Jason Molendaa5609c82012-06-21 01:51:02 +00002680
Jason Molendaf8130862012-06-22 03:28:35 +00002681 /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
2682 The dyld_cache_local_symbols_info structure gives us three things:
2683 1. The start and count of the nlist records in the dyld_shared_cache file
2684 2. The start and size of the strings for these nlist records
2685 3. The start and count of dyld_cache_local_symbols_entry entries
2686
2687 There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
2688 The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
Jason Molenda4e7511e2013-03-06 23:19:17 +00002689 The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
Jason Molendaf8130862012-06-22 03:28:35 +00002690 and the count of how many nlist records there are for this dylib/framework.
2691 */
2692
Jason Molendaa5609c82012-06-21 01:51:02 +00002693 // Process the dsc header to find the unmapped symbols
2694 //
2695 // Save some VM space, do not map the entire cache in one shot.
2696
Jason Molenda255f9bb2013-03-06 23:17:36 +00002697 DataBufferSP dsc_data_sp;
Greg Clayton736888c2015-02-23 23:47:09 +00002698 dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
Jason Molenda255f9bb2013-03-06 23:17:36 +00002699
2700 if (dsc_data_sp)
Jason Molendaa5609c82012-06-21 01:51:02 +00002701 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002702 DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002703
Jason Molenda255f9bb2013-03-06 23:17:36 +00002704 char version_str[17];
2705 int version = -1;
2706 lldb::offset_t offset = 0;
2707 memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16);
2708 version_str[16] = '\0';
2709 if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6]))
2710 {
2711 int v;
2712 if (::sscanf (version_str + 6, "%d", &v) == 1)
2713 {
2714 version = v;
2715 }
2716 }
2717
Jason Molenda0e0954c2013-04-16 06:24:42 +00002718 UUID dsc_uuid;
2719 if (version >= 1)
2720 {
2721 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
2722 uint8_t uuid_bytes[sizeof (uuid_t)];
2723 memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
2724 dsc_uuid.SetBytes (uuid_bytes);
2725 }
2726
2727 bool uuid_match = true;
2728 if (dsc_uuid.IsValid() && process)
2729 {
2730 UUID shared_cache_uuid(GetProcessSharedCacheUUID(process));
2731
2732 if (shared_cache_uuid.IsValid() && dsc_uuid != shared_cache_uuid)
2733 {
2734 // The on-disk dyld_shared_cache file is not the same as the one in this
2735 // process' memory, don't use it.
2736 uuid_match = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002737 ModuleSP module_sp (GetModule());
2738 if (module_sp)
2739 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 +00002740 }
2741 }
2742
Jason Molenda4e7511e2013-03-06 23:19:17 +00002743 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);
Jason Molenda255f9bb2013-03-06 23:17:36 +00002744
Jason Molendaa5609c82012-06-21 01:51:02 +00002745 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
2746
2747 // If the mappingOffset points to a location inside the header, we've
2748 // opened an old dyld shared cache, and should not proceed further.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002749 if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
Jason Molendaa5609c82012-06-21 01:51:02 +00002750 {
2751
Greg Clayton736888c2015-02-23 23:47:09 +00002752 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 +00002753 DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
2754 offset = 0;
2755
2756 // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
2757 // in the shared library cache need to be adjusted by an offset to match up with the
2758 // dylibOffset identifying field in the dyld_cache_local_symbol_entry's. This offset is
2759 // recorded in mapping_offset_value.
2760 const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
2761
2762 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
Jason Molendaa5609c82012-06-21 01:51:02 +00002763 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
2764 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
2765
Jason Molenda4e7511e2013-03-06 23:19:17 +00002766 if (localSymbolsOffset && localSymbolsSize)
Jason Molendaa5609c82012-06-21 01:51:02 +00002767 {
2768 // Map the local symbols
Greg Clayton736888c2015-02-23 23:47:09 +00002769 if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(localSymbolsOffset, localSymbolsSize))
Jason Molendaa5609c82012-06-21 01:51:02 +00002770 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002771 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002772
2773 offset = 0;
2774
Greg Claytonb65c6292015-02-20 22:20:05 +00002775 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
2776 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
2777 UndefinedNameToDescMap undefined_name_to_desc;
2778 SymbolIndexToName reexport_shlib_needs_fixup;
2779
2780
Jason Molendaa5609c82012-06-21 01:51:02 +00002781 // Read the local_symbols_infos struct in one shot
2782 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
2783 dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
2784
Jason Molendaa5609c82012-06-21 01:51:02 +00002785 SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
2786
Jason Molenda255f9bb2013-03-06 23:17:36 +00002787 uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00002788
2789 offset = local_symbols_info.entriesOffset;
2790 for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
2791 {
2792 struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
2793 local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
2794 local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
2795 local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
2796
Jason Molenda4e7511e2013-03-06 23:19:17 +00002797 if (header_file_offset == local_symbols_entry.dylibOffset)
Jason Molendaa5609c82012-06-21 01:51:02 +00002798 {
2799 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
2800
2801 // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
2802 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2803 num_syms = symtab->GetNumSymbols();
2804
2805 nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
2806 uint32_t string_table_offset = local_symbols_info.stringsOffset;
2807
Jason Molenda4e7511e2013-03-06 23:19:17 +00002808 for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
Jason Molendaa5609c82012-06-21 01:51:02 +00002809 {
2810 /////////////////////////////
2811 {
2812 struct nlist_64 nlist;
2813 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2814 break;
2815
2816 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
2817 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2818 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2819 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
2820 nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
2821
2822 SymbolType type = eSymbolTypeInvalid;
2823 const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
2824
2825 if (symbol_name == NULL)
2826 {
2827 // No symbol should be NULL, even the symbols with no
2828 // string values should have an offset zero which points
2829 // to an empty C-string
2830 Host::SystemLog (Host::eSystemLogError,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002831 "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 +00002832 entry_index,
2833 nlist.n_strx,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002834 module_sp->GetFileSpec().GetPath().c_str());
Jason Molendaa5609c82012-06-21 01:51:02 +00002835 continue;
2836 }
2837 if (symbol_name[0] == '\0')
2838 symbol_name = NULL;
2839
2840 const char *symbol_name_non_abi_mangled = NULL;
2841
2842 SectionSP symbol_section;
2843 uint32_t symbol_byte_size = 0;
2844 bool add_nlist = true;
Charles Davis510938e2013-08-27 05:04:57 +00002845 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002846 bool demangled_is_synthesized = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00002847 bool is_gsym = false;
Greg Clayton60038be2015-02-14 00:51:13 +00002848 bool set_value = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00002849
2850 assert (sym_idx < num_syms);
2851
2852 sym[sym_idx].SetDebug (is_debug);
2853
2854 if (is_debug)
2855 {
2856 switch (nlist.n_type)
2857 {
Charles Davis510938e2013-08-27 05:04:57 +00002858 case N_GSYM:
2859 // global symbol: name,,NO_SECT,type,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002860 // Sometimes the N_GSYM value contains the address.
2861
2862 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
2863 // have the same address, but we want to ensure that we always find only the real symbol,
2864 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
2865 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
2866 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
2867 // same address.
2868
Greg Clayton1e28adf2015-02-25 17:25:02 +00002869 is_gsym = true;
2870 sym[sym_idx].SetExternal(true);
2871
2872 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
2873 {
2874 llvm::StringRef symbol_name_ref(symbol_name);
2875 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
2876 {
2877 symbol_name_non_abi_mangled = symbol_name + 1;
2878 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2879 type = eSymbolTypeObjCClass;
2880 demangled_is_synthesized = true;
2881
2882 }
2883 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
2884 {
2885 symbol_name_non_abi_mangled = symbol_name + 1;
2886 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2887 type = eSymbolTypeObjCMetaClass;
2888 demangled_is_synthesized = true;
2889 }
2890 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
2891 {
2892 symbol_name_non_abi_mangled = symbol_name + 1;
2893 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2894 type = eSymbolTypeObjCIVar;
2895 demangled_is_synthesized = true;
2896 }
2897 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002898 else
2899 {
Jason Molendaa5609c82012-06-21 01:51:02 +00002900 if (nlist.n_value != 0)
2901 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2902 type = eSymbolTypeData;
2903 }
2904 break;
2905
Charles Davis510938e2013-08-27 05:04:57 +00002906 case N_FNAME:
2907 // procedure name (f77 kludge): name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002908 type = eSymbolTypeCompiler;
2909 break;
2910
Charles Davis510938e2013-08-27 05:04:57 +00002911 case N_FUN:
2912 // procedure: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002913 if (symbol_name)
2914 {
2915 type = eSymbolTypeCode;
2916 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2917
Greg Claytond81088c2014-01-16 01:38:29 +00002918 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002919 // We use the current number of symbols in the symbol table in lieu of
2920 // using nlist_idx in case we ever start trimming entries out
2921 N_FUN_indexes.push_back(sym_idx);
2922 }
2923 else
2924 {
2925 type = eSymbolTypeCompiler;
2926
2927 if ( !N_FUN_indexes.empty() )
2928 {
2929 // Copy the size of the function into the original STAB entry so we don't have
2930 // to hunt for it later
2931 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
2932 N_FUN_indexes.pop_back();
2933 // We don't really need the end function STAB as it contains the size which
2934 // we already placed with the original symbol, so don't add it if we want a
2935 // minimal symbol table
Greg Clayton3046e662013-07-10 01:23:25 +00002936 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002937 }
2938 }
2939 break;
2940
Charles Davis510938e2013-08-27 05:04:57 +00002941 case N_STSYM:
2942 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00002943 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002944 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2945 type = eSymbolTypeData;
2946 break;
2947
Charles Davis510938e2013-08-27 05:04:57 +00002948 case N_LCSYM:
2949 // .lcomm symbol: name,,n_sect,type,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002950 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2951 type = eSymbolTypeCommonBlock;
2952 break;
2953
Charles Davis510938e2013-08-27 05:04:57 +00002954 case N_BNSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002955 // We use the current number of symbols in the symbol table in lieu of
2956 // using nlist_idx in case we ever start trimming entries out
Greg Clayton3046e662013-07-10 01:23:25 +00002957 // Skip these if we want minimal symbol tables
2958 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002959 break;
2960
Charles Davis510938e2013-08-27 05:04:57 +00002961 case N_ENSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002962 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
2963 // so that we can always skip the entire symbol if we need to navigate
2964 // more quickly at the source level when parsing STABS
Greg Clayton3046e662013-07-10 01:23:25 +00002965 // Skip these if we want minimal symbol tables
2966 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002967 break;
2968
Charles Davis510938e2013-08-27 05:04:57 +00002969 case N_OPT:
2970 // emitted with gcc2_compiled and in gcc source
Jason Molendaa5609c82012-06-21 01:51:02 +00002971 type = eSymbolTypeCompiler;
2972 break;
2973
Charles Davis510938e2013-08-27 05:04:57 +00002974 case N_RSYM:
2975 // register sym: name,,NO_SECT,type,register
Jason Molendaa5609c82012-06-21 01:51:02 +00002976 type = eSymbolTypeVariable;
2977 break;
2978
Charles Davis510938e2013-08-27 05:04:57 +00002979 case N_SLINE:
2980 // src line: 0,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002981 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2982 type = eSymbolTypeLineEntry;
2983 break;
2984
Charles Davis510938e2013-08-27 05:04:57 +00002985 case N_SSYM:
2986 // structure elt: name,,NO_SECT,type,struct_offset
Jason Molendaa5609c82012-06-21 01:51:02 +00002987 type = eSymbolTypeVariableType;
2988 break;
2989
Charles Davis510938e2013-08-27 05:04:57 +00002990 case N_SO:
2991 // source file name
Jason Molendaa5609c82012-06-21 01:51:02 +00002992 type = eSymbolTypeSourceFile;
2993 if (symbol_name == NULL)
2994 {
Greg Clayton3046e662013-07-10 01:23:25 +00002995 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002996 if (N_SO_index != UINT32_MAX)
2997 {
2998 // Set the size of the N_SO to the terminating index of this N_SO
2999 // so that we can always skip the entire N_SO if we need to navigate
3000 // more quickly at the source level when parsing STABS
3001 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
Greg Clayton3046e662013-07-10 01:23:25 +00003002 symbol_ptr->SetByteSize(sym_idx);
Jason Molendaa5609c82012-06-21 01:51:02 +00003003 symbol_ptr->SetSizeIsSibling(true);
3004 }
3005 N_NSYM_indexes.clear();
3006 N_INCL_indexes.clear();
3007 N_BRAC_indexes.clear();
3008 N_COMM_indexes.clear();
3009 N_FUN_indexes.clear();
3010 N_SO_index = UINT32_MAX;
3011 }
3012 else
3013 {
3014 // We use the current number of symbols in the symbol table in lieu of
3015 // using nlist_idx in case we ever start trimming entries out
3016 const bool N_SO_has_full_path = symbol_name[0] == '/';
3017 if (N_SO_has_full_path)
3018 {
Greg Clayton3046e662013-07-10 01:23:25 +00003019 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00003020 {
3021 // We have two consecutive N_SO entries where the first contains a directory
3022 // and the second contains a full path.
Jason Molendad9d5cf52012-07-20 03:35:44 +00003023 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00003024 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3025 add_nlist = false;
3026 }
3027 else
3028 {
3029 // This is the first entry in a N_SO that contains a directory or
3030 // a full path to the source file
3031 N_SO_index = sym_idx;
3032 }
3033 }
Greg Clayton3046e662013-07-10 01:23:25 +00003034 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00003035 {
3036 // This is usually the second N_SO entry that contains just the filename,
3037 // so here we combine it with the first one if we are minimizing the symbol table
3038 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
3039 if (so_path && so_path[0])
3040 {
3041 std::string full_so_path (so_path);
Greg Clayton0662d962012-09-07 20:29:13 +00003042 const size_t double_slash_pos = full_so_path.find("//");
3043 if (double_slash_pos != std::string::npos)
3044 {
3045 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003046 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Clayton0662d962012-09-07 20:29:13 +00003047 // and the second is the directory for the source file so you end up with
3048 // a path that looks like "/tmp/src//tmp/src/"
3049 FileSpec so_dir(so_path, false);
3050 if (!so_dir.Exists())
3051 {
3052 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3053 if (so_dir.Exists())
3054 {
3055 // Trim off the incorrect path
3056 full_so_path.erase(0, double_slash_pos + 1);
3057 }
3058 }
3059 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003060 if (*full_so_path.rbegin() != '/')
3061 full_so_path += '/';
3062 full_so_path += symbol_name;
Jason Molendad9d5cf52012-07-20 03:35:44 +00003063 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00003064 add_nlist = false;
3065 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3066 }
3067 }
Greg Clayton946f8902012-09-05 22:30:51 +00003068 else
3069 {
3070 // This could be a relative path to a N_SO
3071 N_SO_index = sym_idx;
3072 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003073 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003074 break;
3075
Charles Davis510938e2013-08-27 05:04:57 +00003076 case N_OSO:
3077 // object file name: name,,0,0,st_mtime
Jason Molendaa5609c82012-06-21 01:51:02 +00003078 type = eSymbolTypeObjectFile;
3079 break;
3080
Charles Davis510938e2013-08-27 05:04:57 +00003081 case N_LSYM:
3082 // local sym: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003083 type = eSymbolTypeLocal;
3084 break;
3085
3086 //----------------------------------------------------------------------
3087 // INCL scopes
3088 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003089 case N_BINCL:
3090 // include file beginning: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003091 // We use the current number of symbols in the symbol table in lieu of
3092 // using nlist_idx in case we ever start trimming entries out
3093 N_INCL_indexes.push_back(sym_idx);
3094 type = eSymbolTypeScopeBegin;
3095 break;
3096
Charles Davis510938e2013-08-27 05:04:57 +00003097 case N_EINCL:
3098 // include file end: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003099 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3100 // so that we can always skip the entire symbol if we need to navigate
3101 // more quickly at the source level when parsing STABS
3102 if ( !N_INCL_indexes.empty() )
3103 {
3104 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3105 symbol_ptr->SetByteSize(sym_idx + 1);
3106 symbol_ptr->SetSizeIsSibling(true);
3107 N_INCL_indexes.pop_back();
3108 }
3109 type = eSymbolTypeScopeEnd;
3110 break;
3111
Charles Davis510938e2013-08-27 05:04:57 +00003112 case N_SOL:
3113 // #included file name: name,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003114 type = eSymbolTypeHeaderFile;
3115
3116 // We currently don't use the header files on darwin
Greg Clayton3046e662013-07-10 01:23:25 +00003117 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00003118 break;
3119
Charles Davis510938e2013-08-27 05:04:57 +00003120 case N_PARAMS:
3121 // compiler parameters: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003122 type = eSymbolTypeCompiler;
3123 break;
3124
Charles Davis510938e2013-08-27 05:04:57 +00003125 case N_VERSION:
3126 // compiler version: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003127 type = eSymbolTypeCompiler;
3128 break;
3129
Charles Davis510938e2013-08-27 05:04:57 +00003130 case N_OLEVEL:
3131 // compiler -O level: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003132 type = eSymbolTypeCompiler;
3133 break;
3134
Charles Davis510938e2013-08-27 05:04:57 +00003135 case N_PSYM:
3136 // parameter: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003137 type = eSymbolTypeVariable;
3138 break;
3139
Charles Davis510938e2013-08-27 05:04:57 +00003140 case N_ENTRY:
3141 // alternate entry: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003142 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3143 type = eSymbolTypeLineEntry;
3144 break;
3145
3146 //----------------------------------------------------------------------
3147 // Left and Right Braces
3148 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003149 case N_LBRAC:
3150 // left bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003151 // We use the current number of symbols in the symbol table in lieu of
3152 // using nlist_idx in case we ever start trimming entries out
3153 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3154 N_BRAC_indexes.push_back(sym_idx);
3155 type = eSymbolTypeScopeBegin;
3156 break;
3157
Charles Davis510938e2013-08-27 05:04:57 +00003158 case N_RBRAC:
3159 // right bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003160 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
3161 // so that we can always skip the entire symbol if we need to navigate
3162 // more quickly at the source level when parsing STABS
3163 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3164 if ( !N_BRAC_indexes.empty() )
3165 {
3166 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
3167 symbol_ptr->SetByteSize(sym_idx + 1);
3168 symbol_ptr->SetSizeIsSibling(true);
3169 N_BRAC_indexes.pop_back();
3170 }
3171 type = eSymbolTypeScopeEnd;
3172 break;
3173
Charles Davis510938e2013-08-27 05:04:57 +00003174 case N_EXCL:
3175 // deleted include file: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003176 type = eSymbolTypeHeaderFile;
3177 break;
3178
3179 //----------------------------------------------------------------------
3180 // COMM scopes
3181 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003182 case N_BCOMM:
3183 // begin common: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003184 // We use the current number of symbols in the symbol table in lieu of
3185 // using nlist_idx in case we ever start trimming entries out
3186 type = eSymbolTypeScopeBegin;
3187 N_COMM_indexes.push_back(sym_idx);
3188 break;
3189
Charles Davis510938e2013-08-27 05:04:57 +00003190 case N_ECOML:
3191 // end common (local name): 0,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003192 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3193 // Fall through
3194
Charles Davis510938e2013-08-27 05:04:57 +00003195 case N_ECOMM:
3196 // end common: name,,n_sect,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003197 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
3198 // so that we can always skip the entire symbol if we need to navigate
3199 // more quickly at the source level when parsing STABS
3200 if ( !N_COMM_indexes.empty() )
3201 {
3202 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
3203 symbol_ptr->SetByteSize(sym_idx + 1);
3204 symbol_ptr->SetSizeIsSibling(true);
3205 N_COMM_indexes.pop_back();
3206 }
3207 type = eSymbolTypeScopeEnd;
3208 break;
3209
Charles Davis510938e2013-08-27 05:04:57 +00003210 case N_LENG:
3211 // second stab entry with length information
Jason Molendaa5609c82012-06-21 01:51:02 +00003212 type = eSymbolTypeAdditional;
3213 break;
3214
3215 default: break;
3216 }
3217 }
3218 else
3219 {
Charles Davis510938e2013-08-27 05:04:57 +00003220 //uint8_t n_pext = N_PEXT & nlist.n_type;
3221 uint8_t n_type = N_TYPE & nlist.n_type;
3222 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Jason Molendaa5609c82012-06-21 01:51:02 +00003223
3224 switch (n_type)
3225 {
Greg Clayton60038be2015-02-14 00:51:13 +00003226 case N_INDR:
3227 {
3228 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3229 if (reexport_name_cstr && reexport_name_cstr[0])
3230 {
3231 type = eSymbolTypeReExported;
3232 ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
3233 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3234 set_value = false;
3235 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3236 indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3237 }
3238 else
3239 type = eSymbolTypeUndefined;
3240 }
3241 break;
3242
Charles Davis510938e2013-08-27 05:04:57 +00003243 case N_UNDF:
Greg Clayton786ad182015-03-03 01:40:46 +00003244 if (symbol_name && symbol_name[0])
Greg Clayton60038be2015-02-14 00:51:13 +00003245 {
3246 ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
3247 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3248 }
3249 // Fall through
3250 case N_PBUD:
Jason Molendaa5609c82012-06-21 01:51:02 +00003251 type = eSymbolTypeUndefined;
3252 break;
3253
Charles Davis510938e2013-08-27 05:04:57 +00003254 case N_ABS:
Jason Molendaa5609c82012-06-21 01:51:02 +00003255 type = eSymbolTypeAbsolute;
3256 break;
3257
Charles Davis510938e2013-08-27 05:04:57 +00003258 case N_SECT:
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003259 {
3260 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00003261
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003262 if (symbol_section == NULL)
Jason Molendaa5609c82012-06-21 01:51:02 +00003263 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003264 // TODO: warn about this?
3265 add_nlist = false;
3266 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003267 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003268
3269 if (TEXT_eh_frame_sectID == nlist.n_sect)
Jason Molendaa5609c82012-06-21 01:51:02 +00003270 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003271 type = eSymbolTypeException;
3272 }
3273 else
3274 {
Charles Davis510938e2013-08-27 05:04:57 +00003275 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003276
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003277 switch (section_type)
Jason Molendaa5609c82012-06-21 01:51:02 +00003278 {
Charles Davis510938e2013-08-27 05:04:57 +00003279 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
3280 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
3281 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
3282 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
3283 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
3284 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
3285 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
3286 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
3287 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00003288 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
3289 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
3290 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
3291 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00003292 default:
3293 switch (symbol_section->GetType())
3294 {
3295 case lldb::eSectionTypeCode:
3296 type = eSymbolTypeCode;
3297 break;
3298 case eSectionTypeData:
3299 case eSectionTypeDataCString: // Inlined C string data
3300 case eSectionTypeDataCStringPointers: // Pointers to C string data
3301 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
3302 case eSectionTypeData4:
3303 case eSectionTypeData8:
3304 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00003305 type = eSymbolTypeData;
3306 break;
3307 default:
3308 break;
3309 }
3310 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003311 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003312
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003313 if (type == eSymbolTypeInvalid)
3314 {
3315 const char *symbol_sect_name = symbol_section->GetName().AsCString();
3316 if (symbol_section->IsDescendant (text_section_sp.get()))
3317 {
Charles Davis510938e2013-08-27 05:04:57 +00003318 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3319 S_ATTR_SELF_MODIFYING_CODE |
3320 S_ATTR_SOME_INSTRUCTIONS))
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003321 type = eSymbolTypeData;
3322 else
3323 type = eSymbolTypeCode;
3324 }
Greg Claytona381e102015-07-27 23:21:05 +00003325 else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3326 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
3327 symbol_section->IsDescendant(data_const_section_sp.get()))
Jason Molendaa5609c82012-06-21 01:51:02 +00003328 {
3329 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
3330 {
3331 type = eSymbolTypeRuntime;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003332
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003333 if (symbol_name &&
3334 symbol_name[0] == '_' &&
3335 symbol_name[1] == 'O' &&
Jason Molendaa5609c82012-06-21 01:51:02 +00003336 symbol_name[2] == 'B')
3337 {
3338 llvm::StringRef symbol_name_ref(symbol_name);
Jason Molendaa5609c82012-06-21 01:51:02 +00003339 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3340 {
3341 symbol_name_non_abi_mangled = symbol_name + 1;
3342 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3343 type = eSymbolTypeObjCClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003344 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003345 }
3346 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3347 {
3348 symbol_name_non_abi_mangled = symbol_name + 1;
3349 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3350 type = eSymbolTypeObjCMetaClass;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003351 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003352 }
3353 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3354 {
3355 symbol_name_non_abi_mangled = symbol_name + 1;
3356 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3357 type = eSymbolTypeObjCIVar;
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003358 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003359 }
3360 }
3361 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003362 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
Jason Molendaa5609c82012-06-21 01:51:02 +00003363 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003364 type = eSymbolTypeException;
Jason Molendaa5609c82012-06-21 01:51:02 +00003365 }
3366 else
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003367 {
3368 type = eSymbolTypeData;
3369 }
3370 }
3371 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
3372 {
3373 type = eSymbolTypeTrampoline;
3374 }
3375 else if (symbol_section->IsDescendant(objc_section_sp.get()))
3376 {
3377 type = eSymbolTypeRuntime;
3378 if (symbol_name && symbol_name[0] == '.')
3379 {
3380 llvm::StringRef symbol_name_ref(symbol_name);
3381 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
3382 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
Jason Molendaa5609c82012-06-21 01:51:02 +00003383 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003384 symbol_name_non_abi_mangled = symbol_name;
3385 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
3386 type = eSymbolTypeObjCClass;
3387 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003388 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003389 }
3390 }
3391 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003392 }
3393 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003394 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003395 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003396 }
3397
3398 if (add_nlist)
3399 {
3400 uint64_t symbol_value = nlist.n_value;
Jason Molendaa5609c82012-06-21 01:51:02 +00003401 if (symbol_name_non_abi_mangled)
3402 {
Jason Molendad9d5cf52012-07-20 03:35:44 +00003403 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
3404 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Jason Molendaa5609c82012-06-21 01:51:02 +00003405 }
3406 else
3407 {
Greg Clayton3046e662013-07-10 01:23:25 +00003408 bool symbol_name_is_mangled = false;
3409
Jason Molendaa5609c82012-06-21 01:51:02 +00003410 if (symbol_name && symbol_name[0] == '_')
3411 {
3412 symbol_name_is_mangled = symbol_name[1] == '_';
3413 symbol_name++; // Skip the leading underscore
3414 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003415
Jason Molendaa5609c82012-06-21 01:51:02 +00003416 if (symbol_name)
3417 {
Greg Claytondacc4a92013-05-14 22:19:37 +00003418 ConstString const_symbol_name(symbol_name);
Greg Claytondacc4a92013-05-14 22:19:37 +00003419 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Clayton3046e662013-07-10 01:23:25 +00003420 if (is_gsym && is_debug)
Greg Clayton14cd13c2015-07-01 23:29:06 +00003421 {
3422 const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
3423 if (gsym_name)
3424 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3425 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003426 }
3427 }
3428 if (symbol_section)
3429 {
3430 const addr_t section_file_addr = symbol_section->GetFileAddress();
3431 if (symbol_byte_size == 0 && function_starts_count > 0)
3432 {
3433 addr_t symbol_lookup_file_addr = nlist.n_value;
3434 // Do an exact address match for non-ARM addresses, else get the closest since
3435 // the symbol might be a thumb symbol which has an address with bit zero set
3436 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
3437 if (is_arm && func_start_entry)
3438 {
3439 // Verify that the function start address is the symbol address (ARM)
3440 // or the symbol address + 1 (thumb)
3441 if (func_start_entry->addr != symbol_lookup_file_addr &&
3442 func_start_entry->addr != (symbol_lookup_file_addr + 1))
3443 {
3444 // Not the right entry, NULL it out...
3445 func_start_entry = NULL;
3446 }
3447 }
3448 if (func_start_entry)
3449 {
3450 func_start_entry->data = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003451
Jason Molendaa5609c82012-06-21 01:51:02 +00003452 addr_t symbol_file_addr = func_start_entry->addr;
3453 uint32_t symbol_flags = 0;
3454 if (is_arm)
3455 {
3456 if (symbol_file_addr & 1)
3457 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Greg Claytonb887da12015-07-16 19:50:57 +00003458 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Jason Molendaa5609c82012-06-21 01:51:02 +00003459 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003460
Jason Molendaa5609c82012-06-21 01:51:02 +00003461 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3462 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3463 if (next_func_start_entry)
3464 {
3465 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3466 // Be sure the clear the Thumb address bit when we calculate the size
3467 // from the current and next address
3468 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00003469 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Jason Molendaa5609c82012-06-21 01:51:02 +00003470 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
3471 }
3472 else
3473 {
3474 symbol_byte_size = section_end_file_addr - symbol_file_addr;
3475 }
3476 }
3477 }
3478 symbol_value -= section_file_addr;
3479 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003480
Greg Claytondacc4a92013-05-14 22:19:37 +00003481 if (is_debug == false)
3482 {
3483 if (type == eSymbolTypeCode)
3484 {
3485 // See if we can find a N_FUN entry for any code symbols.
3486 // If we do find a match, and the name matches, then we
3487 // can merge the two into just the function symbol to avoid
3488 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003489 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3490 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3491 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003492 {
Greg Claytond81088c2014-01-16 01:38:29 +00003493 bool found_it = false;
3494 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003495 {
Greg Claytond81088c2014-01-16 01:38:29 +00003496 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3497 {
3498 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3499 // We just need the flags from the linker symbol, so put these flags
3500 // into the N_FUN flags to avoid duplicate symbols in the symbol table
3501 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3502 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3503 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
3504 sym[pos->second].SetType (eSymbolTypeResolver);
3505 sym[sym_idx].Clear();
3506 found_it = true;
3507 break;
3508 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003509 }
Greg Claytond81088c2014-01-16 01:38:29 +00003510 if (found_it)
3511 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003512 }
Jim Inghamea3ac272014-01-10 22:55:37 +00003513 else
3514 {
Greg Claytond81088c2014-01-16 01:38:29 +00003515 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00003516 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00003517 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003518 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00003519 else if (type == eSymbolTypeData ||
3520 type == eSymbolTypeObjCClass ||
3521 type == eSymbolTypeObjCMetaClass ||
3522 type == eSymbolTypeObjCIVar )
Greg Claytondacc4a92013-05-14 22:19:37 +00003523 {
3524 // See if we can find a N_STSYM entry for any data symbols.
3525 // If we do find a match, and the name matches, then we
3526 // can merge the two into just the Static symbol to avoid
3527 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003528 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3529 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
3530 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003531 {
Greg Claytond81088c2014-01-16 01:38:29 +00003532 bool found_it = false;
3533 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003534 {
Greg Claytond81088c2014-01-16 01:38:29 +00003535 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3536 {
3537 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3538 // We just need the flags from the linker symbol, so put these flags
3539 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3540 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3541 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3542 sym[sym_idx].Clear();
3543 found_it = true;
3544 break;
3545 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003546 }
Greg Claytond81088c2014-01-16 01:38:29 +00003547 if (found_it)
3548 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003549 }
3550 else
3551 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00003552 const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
3553 if (gsym_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003554 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00003555 // Combine N_GSYM stab entries with the non stab symbol
3556 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
3557 if (pos != N_GSYM_name_to_sym_idx.end())
3558 {
3559 const uint32_t GSYM_sym_idx = pos->second;
3560 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
3561 // Copy the address, because often the N_GSYM address has an invalid address of zero
3562 // when the global is a common symbol
3563 sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
3564 sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
3565 // We just need the flags from the linker symbol, so put these flags
3566 // into the N_GSYM flags to avoid duplicate symbols in the symbol table
3567 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3568 sym[sym_idx].Clear();
3569 continue;
3570 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003571 }
3572 }
3573 }
3574 }
3575
Jason Molendaa5609c82012-06-21 01:51:02 +00003576 sym[sym_idx].SetID (nlist_idx);
3577 sym[sym_idx].SetType (type);
Greg Clayton60038be2015-02-14 00:51:13 +00003578 if (set_value)
3579 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00003580 sym[sym_idx].GetAddressRef().SetSection (symbol_section);
3581 sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
Greg Clayton60038be2015-02-14 00:51:13 +00003582 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003583 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003584
Jason Molendaa5609c82012-06-21 01:51:02 +00003585 if (symbol_byte_size > 0)
3586 sym[sym_idx].SetByteSize(symbol_byte_size);
3587
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003588 if (demangled_is_synthesized)
3589 sym[sym_idx].SetDemangledNameIsSynthesized(true);
Jason Molendaa5609c82012-06-21 01:51:02 +00003590 ++sym_idx;
3591 }
3592 else
3593 {
3594 sym[sym_idx].Clear();
3595 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003596
Jason Molendaa5609c82012-06-21 01:51:02 +00003597 }
3598 /////////////////////////////
3599 }
3600 break; // No more entries to consider
3601 }
3602 }
Greg Clayton60038be2015-02-14 00:51:13 +00003603
3604 for (const auto &pos :reexport_shlib_needs_fixup)
3605 {
3606 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3607 if (undef_pos != undefined_name_to_desc.end())
3608 {
3609 const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3610 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
3611 sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
3612 }
3613 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003614 }
3615 }
3616 }
3617 }
3618 }
3619
3620 // Must reset this in case it was mutated above!
3621 nlist_data_offset = 0;
3622#endif
Jim Inghamea3ac272014-01-10 22:55:37 +00003623
Greg Claytonfd814c52013-08-13 01:42:25 +00003624 if (nlist_data.GetByteSize() > 0)
Jason Molendaa5609c82012-06-21 01:51:02 +00003625 {
Jason Molendaa5609c82012-06-21 01:51:02 +00003626
Greg Claytonfd814c52013-08-13 01:42:25 +00003627 // If the sym array was not created while parsing the DSC unmapped
3628 // symbols, create it now.
3629 if (sym == NULL)
Greg Clayton4c82d422012-05-18 23:20:01 +00003630 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003631 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3632 num_syms = symtab->GetNumSymbols();
3633 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003634
Greg Claytonfd814c52013-08-13 01:42:25 +00003635 if (unmapped_local_symbols_found)
3636 {
3637 assert(m_dysymtab.ilocalsym == 0);
3638 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3639 nlist_idx = m_dysymtab.nlocalsym;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003640 }
Greg Claytondebb8812012-05-25 17:04:00 +00003641 else
3642 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003643 nlist_idx = 0;
Greg Claytondebb8812012-05-25 17:04:00 +00003644 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003645
Greg Clayton60038be2015-02-14 00:51:13 +00003646 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
3647 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
3648 UndefinedNameToDescMap undefined_name_to_desc;
3649 SymbolIndexToName reexport_shlib_needs_fixup;
Greg Claytonfd814c52013-08-13 01:42:25 +00003650 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003651 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003652 struct nlist_64 nlist;
3653 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
3654 break;
3655
3656 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
3657 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
3658 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
3659 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
3660 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
3661
3662 SymbolType type = eSymbolTypeInvalid;
3663 const char *symbol_name = NULL;
3664
3665 if (have_strtab_data)
Greg Clayton77ccca72011-12-30 00:32:24 +00003666 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003667 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003668
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003669 if (symbol_name == NULL)
3670 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003671 // No symbol should be NULL, even the symbols with no
3672 // string values should have an offset zero which points
3673 // to an empty C-string
3674 Host::SystemLog (Host::eSystemLogError,
3675 "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
3676 nlist_idx,
3677 nlist.n_strx,
3678 module_sp->GetFileSpec().GetPath().c_str());
3679 continue;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003680 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003681 if (symbol_name[0] == '\0')
3682 symbol_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003683 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003684 else
3685 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003686 const addr_t str_addr = strtab_addr + nlist.n_strx;
3687 Error str_error;
3688 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
3689 symbol_name = memory_symbol_name.c_str();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003690 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003691 const char *symbol_name_non_abi_mangled = NULL;
3692
3693 SectionSP symbol_section;
3694 lldb::addr_t symbol_byte_size = 0;
3695 bool add_nlist = true;
3696 bool is_gsym = false;
Charles Davis510938e2013-08-27 05:04:57 +00003697 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00003698 bool demangled_is_synthesized = false;
Greg Clayton60038be2015-02-14 00:51:13 +00003699 bool set_value = true;
Greg Claytonfd814c52013-08-13 01:42:25 +00003700 assert (sym_idx < num_syms);
3701
3702 sym[sym_idx].SetDebug (is_debug);
3703
3704 if (is_debug)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003705 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003706 switch (nlist.n_type)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003707 {
Charles Davis510938e2013-08-27 05:04:57 +00003708 case N_GSYM:
3709 // global symbol: name,,NO_SECT,type,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003710 // Sometimes the N_GSYM value contains the address.
Jason Molenda4e7511e2013-03-06 23:19:17 +00003711
Greg Claytonfd814c52013-08-13 01:42:25 +00003712 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
3713 // have the same address, but we want to ensure that we always find only the real symbol,
3714 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
3715 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
3716 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
3717 // same address.
Greg Clayton1e28adf2015-02-25 17:25:02 +00003718 is_gsym = true;
3719 sym[sym_idx].SetExternal(true);
Greg Clayton29e08cb2012-03-14 01:53:24 +00003720
Greg Clayton1e28adf2015-02-25 17:25:02 +00003721 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
3722 {
3723 llvm::StringRef symbol_name_ref(symbol_name);
3724 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3725 {
3726 symbol_name_non_abi_mangled = symbol_name + 1;
3727 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3728 type = eSymbolTypeObjCClass;
3729 demangled_is_synthesized = true;
3730
3731 }
3732 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3733 {
3734 symbol_name_non_abi_mangled = symbol_name + 1;
3735 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3736 type = eSymbolTypeObjCMetaClass;
3737 demangled_is_synthesized = true;
3738 }
3739 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3740 {
3741 symbol_name_non_abi_mangled = symbol_name + 1;
3742 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3743 type = eSymbolTypeObjCIVar;
3744 demangled_is_synthesized = true;
3745 }
3746 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003747 else
3748 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003749 if (nlist.n_value != 0)
3750 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3751 type = eSymbolTypeData;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003752 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003753 break;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003754
Charles Davis510938e2013-08-27 05:04:57 +00003755 case N_FNAME:
3756 // procedure name (f77 kludge): name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003757 type = eSymbolTypeCompiler;
3758 break;
3759
Charles Davis510938e2013-08-27 05:04:57 +00003760 case N_FUN:
3761 // procedure: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003762 if (symbol_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003763 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003764 type = eSymbolTypeCode;
3765 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3766
Greg Claytond81088c2014-01-16 01:38:29 +00003767 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003768 // We use the current number of symbols in the symbol table in lieu of
3769 // using nlist_idx in case we ever start trimming entries out
3770 N_FUN_indexes.push_back(sym_idx);
Greg Claytondacc4a92013-05-14 22:19:37 +00003771 }
3772 else
3773 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003774 type = eSymbolTypeCompiler;
3775
3776 if ( !N_FUN_indexes.empty() )
Greg Claytondacc4a92013-05-14 22:19:37 +00003777 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003778 // Copy the size of the function into the original STAB entry so we don't have
3779 // to hunt for it later
3780 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
3781 N_FUN_indexes.pop_back();
3782 // We don't really need the end function STAB as it contains the size which
3783 // we already placed with the original symbol, so don't add it if we want a
3784 // minimal symbol table
3785 add_nlist = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00003786 }
3787 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003788 break;
3789
Charles Davis510938e2013-08-27 05:04:57 +00003790 case N_STSYM:
3791 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00003792 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003793 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3794 type = eSymbolTypeData;
3795 break;
3796
Charles Davis510938e2013-08-27 05:04:57 +00003797 case N_LCSYM:
3798 // .lcomm symbol: name,,n_sect,type,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003799 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3800 type = eSymbolTypeCommonBlock;
3801 break;
3802
Charles Davis510938e2013-08-27 05:04:57 +00003803 case N_BNSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003804 // We use the current number of symbols in the symbol table in lieu of
3805 // using nlist_idx in case we ever start trimming entries out
3806 // Skip these if we want minimal symbol tables
3807 add_nlist = false;
3808 break;
3809
Charles Davis510938e2013-08-27 05:04:57 +00003810 case N_ENSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003811 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
3812 // so that we can always skip the entire symbol if we need to navigate
3813 // more quickly at the source level when parsing STABS
3814 // Skip these if we want minimal symbol tables
3815 add_nlist = false;
3816 break;
3817
3818
Charles Davis510938e2013-08-27 05:04:57 +00003819 case N_OPT:
3820 // emitted with gcc2_compiled and in gcc source
Greg Claytonfd814c52013-08-13 01:42:25 +00003821 type = eSymbolTypeCompiler;
3822 break;
3823
Charles Davis510938e2013-08-27 05:04:57 +00003824 case N_RSYM:
3825 // register sym: name,,NO_SECT,type,register
Greg Claytonfd814c52013-08-13 01:42:25 +00003826 type = eSymbolTypeVariable;
3827 break;
3828
Charles Davis510938e2013-08-27 05:04:57 +00003829 case N_SLINE:
3830 // src line: 0,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003831 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3832 type = eSymbolTypeLineEntry;
3833 break;
3834
Charles Davis510938e2013-08-27 05:04:57 +00003835 case N_SSYM:
3836 // structure elt: name,,NO_SECT,type,struct_offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003837 type = eSymbolTypeVariableType;
3838 break;
3839
Charles Davis510938e2013-08-27 05:04:57 +00003840 case N_SO:
3841 // source file name
Greg Claytonfd814c52013-08-13 01:42:25 +00003842 type = eSymbolTypeSourceFile;
3843 if (symbol_name == NULL)
3844 {
3845 add_nlist = false;
3846 if (N_SO_index != UINT32_MAX)
3847 {
3848 // Set the size of the N_SO to the terminating index of this N_SO
3849 // so that we can always skip the entire N_SO if we need to navigate
3850 // more quickly at the source level when parsing STABS
3851 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
3852 symbol_ptr->SetByteSize(sym_idx);
3853 symbol_ptr->SetSizeIsSibling(true);
3854 }
3855 N_NSYM_indexes.clear();
3856 N_INCL_indexes.clear();
3857 N_BRAC_indexes.clear();
3858 N_COMM_indexes.clear();
3859 N_FUN_indexes.clear();
3860 N_SO_index = UINT32_MAX;
3861 }
3862 else
3863 {
3864 // We use the current number of symbols in the symbol table in lieu of
3865 // using nlist_idx in case we ever start trimming entries out
3866 const bool N_SO_has_full_path = symbol_name[0] == '/';
3867 if (N_SO_has_full_path)
3868 {
3869 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3870 {
3871 // We have two consecutive N_SO entries where the first contains a directory
3872 // and the second contains a full path.
3873 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
3874 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3875 add_nlist = false;
3876 }
3877 else
3878 {
3879 // This is the first entry in a N_SO that contains a directory or
3880 // a full path to the source file
3881 N_SO_index = sym_idx;
3882 }
3883 }
3884 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3885 {
3886 // This is usually the second N_SO entry that contains just the filename,
3887 // so here we combine it with the first one if we are minimizing the symbol table
Greg Claytonddaf6a72015-07-08 22:32:23 +00003888 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString();
Greg Claytonfd814c52013-08-13 01:42:25 +00003889 if (so_path && so_path[0])
3890 {
3891 std::string full_so_path (so_path);
3892 const size_t double_slash_pos = full_so_path.find("//");
3893 if (double_slash_pos != std::string::npos)
3894 {
3895 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003896 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Claytonfd814c52013-08-13 01:42:25 +00003897 // and the second is the directory for the source file so you end up with
3898 // a path that looks like "/tmp/src//tmp/src/"
3899 FileSpec so_dir(so_path, false);
3900 if (!so_dir.Exists())
3901 {
3902 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3903 if (so_dir.Exists())
3904 {
3905 // Trim off the incorrect path
3906 full_so_path.erase(0, double_slash_pos + 1);
3907 }
3908 }
3909 }
3910 if (*full_so_path.rbegin() != '/')
3911 full_so_path += '/';
3912 full_so_path += symbol_name;
3913 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
3914 add_nlist = false;
3915 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3916 }
3917 }
3918 else
3919 {
3920 // This could be a relative path to a N_SO
3921 N_SO_index = sym_idx;
3922 }
3923 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003924 break;
3925
Charles Davis510938e2013-08-27 05:04:57 +00003926 case N_OSO:
3927 // object file name: name,,0,0,st_mtime
Greg Claytonfd814c52013-08-13 01:42:25 +00003928 type = eSymbolTypeObjectFile;
3929 break;
3930
Charles Davis510938e2013-08-27 05:04:57 +00003931 case N_LSYM:
3932 // local sym: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003933 type = eSymbolTypeLocal;
3934 break;
3935
3936 //----------------------------------------------------------------------
3937 // INCL scopes
3938 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003939 case N_BINCL:
3940 // include file beginning: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00003941 // We use the current number of symbols in the symbol table in lieu of
3942 // using nlist_idx in case we ever start trimming entries out
3943 N_INCL_indexes.push_back(sym_idx);
3944 type = eSymbolTypeScopeBegin;
3945 break;
3946
Charles Davis510938e2013-08-27 05:04:57 +00003947 case N_EINCL:
3948 // include file end: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003949 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3950 // so that we can always skip the entire symbol if we need to navigate
3951 // more quickly at the source level when parsing STABS
3952 if ( !N_INCL_indexes.empty() )
3953 {
3954 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3955 symbol_ptr->SetByteSize(sym_idx + 1);
3956 symbol_ptr->SetSizeIsSibling(true);
3957 N_INCL_indexes.pop_back();
3958 }
3959 type = eSymbolTypeScopeEnd;
3960 break;
3961
Charles Davis510938e2013-08-27 05:04:57 +00003962 case N_SOL:
3963 // #included file name: name,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003964 type = eSymbolTypeHeaderFile;
3965
3966 // We currently don't use the header files on darwin
3967 add_nlist = false;
3968 break;
3969
Charles Davis510938e2013-08-27 05:04:57 +00003970 case N_PARAMS:
3971 // compiler parameters: 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_VERSION:
3976 // compiler version: 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_OLEVEL:
3981 // compiler -O level: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003982 type = eSymbolTypeCompiler;
3983 break;
3984
Charles Davis510938e2013-08-27 05:04:57 +00003985 case N_PSYM:
3986 // parameter: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003987 type = eSymbolTypeVariable;
3988 break;
3989
Charles Davis510938e2013-08-27 05:04:57 +00003990 case N_ENTRY:
3991 // alternate entry: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003992 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3993 type = eSymbolTypeLineEntry;
3994 break;
3995
3996 //----------------------------------------------------------------------
3997 // Left and Right Braces
3998 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003999 case N_LBRAC:
4000 // left bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004001 // We use the current number of symbols in the symbol table in lieu of
4002 // using nlist_idx in case we ever start trimming entries out
4003 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4004 N_BRAC_indexes.push_back(sym_idx);
4005 type = eSymbolTypeScopeBegin;
4006 break;
4007
Charles Davis510938e2013-08-27 05:04:57 +00004008 case N_RBRAC:
4009 // right bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004010 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
4011 // so that we can always skip the entire symbol if we need to navigate
4012 // more quickly at the source level when parsing STABS
4013 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4014 if ( !N_BRAC_indexes.empty() )
4015 {
4016 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
4017 symbol_ptr->SetByteSize(sym_idx + 1);
4018 symbol_ptr->SetSizeIsSibling(true);
4019 N_BRAC_indexes.pop_back();
4020 }
4021 type = eSymbolTypeScopeEnd;
4022 break;
4023
Charles Davis510938e2013-08-27 05:04:57 +00004024 case N_EXCL:
4025 // deleted include file: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00004026 type = eSymbolTypeHeaderFile;
4027 break;
4028
4029 //----------------------------------------------------------------------
4030 // COMM scopes
4031 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00004032 case N_BCOMM:
4033 // begin common: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004034 // We use the current number of symbols in the symbol table in lieu of
4035 // using nlist_idx in case we ever start trimming entries out
4036 type = eSymbolTypeScopeBegin;
4037 N_COMM_indexes.push_back(sym_idx);
4038 break;
4039
Charles Davis510938e2013-08-27 05:04:57 +00004040 case N_ECOML:
4041 // end common (local name): 0,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004042 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4043 // Fall through
4044
Charles Davis510938e2013-08-27 05:04:57 +00004045 case N_ECOMM:
4046 // end common: name,,n_sect,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004047 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
4048 // so that we can always skip the entire symbol if we need to navigate
4049 // more quickly at the source level when parsing STABS
4050 if ( !N_COMM_indexes.empty() )
4051 {
4052 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
4053 symbol_ptr->SetByteSize(sym_idx + 1);
4054 symbol_ptr->SetSizeIsSibling(true);
4055 N_COMM_indexes.pop_back();
4056 }
4057 type = eSymbolTypeScopeEnd;
4058 break;
4059
Charles Davis510938e2013-08-27 05:04:57 +00004060 case N_LENG:
4061 // second stab entry with length information
Greg Claytonfd814c52013-08-13 01:42:25 +00004062 type = eSymbolTypeAdditional;
4063 break;
4064
4065 default: break;
4066 }
4067 }
4068 else
4069 {
Charles Davis510938e2013-08-27 05:04:57 +00004070 //uint8_t n_pext = N_PEXT & nlist.n_type;
4071 uint8_t n_type = N_TYPE & nlist.n_type;
4072 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00004073
4074 switch (n_type)
4075 {
Greg Clayton60038be2015-02-14 00:51:13 +00004076 case N_INDR:
4077 {
4078 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4079 if (reexport_name_cstr && reexport_name_cstr[0])
4080 {
4081 type = eSymbolTypeReExported;
4082 ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
4083 sym[sym_idx].SetReExportedSymbolName(reexport_name);
4084 set_value = false;
4085 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4086 indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
4087 }
4088 else
4089 type = eSymbolTypeUndefined;
4090 }
4091 break;
4092
Charles Davis510938e2013-08-27 05:04:57 +00004093 case N_UNDF:
Greg Clayton786ad182015-03-03 01:40:46 +00004094 if (symbol_name && symbol_name[0])
Greg Clayton60038be2015-02-14 00:51:13 +00004095 {
4096 ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
4097 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4098 }
4099 // Fall through
4100 case N_PBUD:
Greg Claytonfd814c52013-08-13 01:42:25 +00004101 type = eSymbolTypeUndefined;
4102 break;
4103
Charles Davis510938e2013-08-27 05:04:57 +00004104 case N_ABS:
Greg Claytonfd814c52013-08-13 01:42:25 +00004105 type = eSymbolTypeAbsolute;
4106 break;
4107
Charles Davis510938e2013-08-27 05:04:57 +00004108 case N_SECT:
Greg Claytonfd814c52013-08-13 01:42:25 +00004109 {
4110 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4111
4112 if (!symbol_section)
4113 {
4114 // TODO: warn about this?
4115 add_nlist = false;
4116 break;
4117 }
4118
4119 if (TEXT_eh_frame_sectID == nlist.n_sect)
4120 {
4121 type = eSymbolTypeException;
4122 }
4123 else
4124 {
Charles Davis510938e2013-08-27 05:04:57 +00004125 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Greg Claytonfd814c52013-08-13 01:42:25 +00004126
4127 switch (section_type)
4128 {
Charles Davis510938e2013-08-27 05:04:57 +00004129 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
4130 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
4131 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
4132 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
4133 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
4134 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
4135 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
4136 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
4137 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00004138 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
4139 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
4140 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
4141 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00004142 default:
4143 switch (symbol_section->GetType())
4144 {
4145 case lldb::eSectionTypeCode:
4146 type = eSymbolTypeCode;
4147 break;
4148 case eSectionTypeData:
4149 case eSectionTypeDataCString: // Inlined C string data
4150 case eSectionTypeDataCStringPointers: // Pointers to C string data
4151 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
4152 case eSectionTypeData4:
4153 case eSectionTypeData8:
4154 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00004155 type = eSymbolTypeData;
4156 break;
4157 default:
4158 break;
4159 }
4160 break;
Greg Claytonfd814c52013-08-13 01:42:25 +00004161 }
4162
4163 if (type == eSymbolTypeInvalid)
4164 {
4165 const char *symbol_sect_name = symbol_section->GetName().AsCString();
4166 if (symbol_section->IsDescendant (text_section_sp.get()))
4167 {
Charles Davis510938e2013-08-27 05:04:57 +00004168 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4169 S_ATTR_SELF_MODIFYING_CODE |
4170 S_ATTR_SOME_INSTRUCTIONS))
Greg Claytonfd814c52013-08-13 01:42:25 +00004171 type = eSymbolTypeData;
4172 else
4173 type = eSymbolTypeCode;
4174 }
4175 else
Greg Claytona381e102015-07-27 23:21:05 +00004176 if (symbol_section->IsDescendant(data_section_sp.get()) ||
4177 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
4178 symbol_section->IsDescendant(data_const_section_sp.get()))
Greg Claytonfd814c52013-08-13 01:42:25 +00004179 {
4180 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
4181 {
4182 type = eSymbolTypeRuntime;
4183
4184 if (symbol_name &&
4185 symbol_name[0] == '_' &&
4186 symbol_name[1] == 'O' &&
4187 symbol_name[2] == 'B')
4188 {
4189 llvm::StringRef symbol_name_ref(symbol_name);
Greg Claytonfd814c52013-08-13 01:42:25 +00004190 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
4191 {
4192 symbol_name_non_abi_mangled = symbol_name + 1;
4193 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
4194 type = eSymbolTypeObjCClass;
4195 demangled_is_synthesized = true;
4196 }
4197 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
4198 {
4199 symbol_name_non_abi_mangled = symbol_name + 1;
4200 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
4201 type = eSymbolTypeObjCMetaClass;
4202 demangled_is_synthesized = true;
4203 }
4204 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
4205 {
4206 symbol_name_non_abi_mangled = symbol_name + 1;
4207 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
4208 type = eSymbolTypeObjCIVar;
4209 demangled_is_synthesized = true;
4210 }
4211 }
4212 }
4213 else
4214 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
4215 {
4216 type = eSymbolTypeException;
4217 }
4218 else
4219 {
4220 type = eSymbolTypeData;
4221 }
4222 }
4223 else
4224 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
4225 {
4226 type = eSymbolTypeTrampoline;
4227 }
4228 else
4229 if (symbol_section->IsDescendant(objc_section_sp.get()))
4230 {
4231 type = eSymbolTypeRuntime;
4232 if (symbol_name && symbol_name[0] == '.')
4233 {
4234 llvm::StringRef symbol_name_ref(symbol_name);
4235 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
4236 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
4237 {
4238 symbol_name_non_abi_mangled = symbol_name;
4239 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4240 type = eSymbolTypeObjCClass;
4241 demangled_is_synthesized = true;
4242 }
4243 }
4244 }
4245 }
4246 }
4247 }
4248 break;
Greg Claytondacc4a92013-05-14 22:19:37 +00004249 }
4250 }
4251
Greg Claytonfd814c52013-08-13 01:42:25 +00004252 if (add_nlist)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004253 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004254 uint64_t symbol_value = nlist.n_value;
4255
4256 if (symbol_name_non_abi_mangled)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004257 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004258 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
4259 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
4260 }
4261 else
4262 {
4263 bool symbol_name_is_mangled = false;
4264
4265 if (symbol_name && symbol_name[0] == '_')
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004266 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004267 symbol_name_is_mangled = symbol_name[1] == '_';
4268 symbol_name++; // Skip the leading underscore
4269 }
4270
4271 if (symbol_name)
4272 {
4273 ConstString const_symbol_name(symbol_name);
4274 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Claytonfd814c52013-08-13 01:42:25 +00004275 }
4276 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004277
4278 if (is_gsym)
Greg Clayton14cd13c2015-07-01 23:29:06 +00004279 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004280 const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
Greg Clayton14cd13c2015-07-01 23:29:06 +00004281 if (gsym_name)
4282 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4283 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004284
Greg Claytonfd814c52013-08-13 01:42:25 +00004285 if (symbol_section)
4286 {
4287 const addr_t section_file_addr = symbol_section->GetFileAddress();
4288 if (symbol_byte_size == 0 && function_starts_count > 0)
4289 {
4290 addr_t symbol_lookup_file_addr = nlist.n_value;
4291 // Do an exact address match for non-ARM addresses, else get the closest since
4292 // the symbol might be a thumb symbol which has an address with bit zero set
4293 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
4294 if (is_arm && func_start_entry)
4295 {
4296 // Verify that the function start address is the symbol address (ARM)
4297 // or the symbol address + 1 (thumb)
4298 if (func_start_entry->addr != symbol_lookup_file_addr &&
4299 func_start_entry->addr != (symbol_lookup_file_addr + 1))
4300 {
4301 // Not the right entry, NULL it out...
4302 func_start_entry = NULL;
4303 }
4304 }
4305 if (func_start_entry)
4306 {
4307 func_start_entry->data = true;
4308
4309 addr_t symbol_file_addr = func_start_entry->addr;
4310 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004311 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Claytonfd814c52013-08-13 01:42:25 +00004312
4313 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4314 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4315 if (next_func_start_entry)
4316 {
4317 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4318 // Be sure the clear the Thumb address bit when we calculate the size
4319 // from the current and next address
4320 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004321 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Claytonfd814c52013-08-13 01:42:25 +00004322 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
4323 }
4324 else
4325 {
4326 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4327 }
4328 }
4329 }
4330 symbol_value -= section_file_addr;
4331 }
4332
4333 if (is_debug == false)
4334 {
4335 if (type == eSymbolTypeCode)
4336 {
4337 // See if we can find a N_FUN entry for any code symbols.
4338 // If we do find a match, and the name matches, then we
4339 // can merge the two into just the function symbol to avoid
4340 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004341 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4342 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4343 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004344 {
Greg Claytond81088c2014-01-16 01:38:29 +00004345 bool found_it = false;
4346 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004347 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004348 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 +00004349 {
4350 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4351 // We just need the flags from the linker symbol, so put these flags
4352 // into the N_FUN flags to avoid duplicate symbols in the symbol table
4353 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4354 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4355 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
4356 sym[pos->second].SetType (eSymbolTypeResolver);
4357 sym[sym_idx].Clear();
4358 found_it = true;
4359 break;
4360 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004361 }
Greg Claytond81088c2014-01-16 01:38:29 +00004362 if (found_it)
4363 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004364 }
Jim Inghamea3ac272014-01-10 22:55:37 +00004365 else
4366 {
4367 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00004368 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00004369 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004370 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004371 else if (type == eSymbolTypeData ||
4372 type == eSymbolTypeObjCClass ||
4373 type == eSymbolTypeObjCMetaClass ||
4374 type == eSymbolTypeObjCIVar )
Greg Claytonfd814c52013-08-13 01:42:25 +00004375 {
4376 // See if we can find a N_STSYM entry for any data symbols.
4377 // If we do find a match, and the name matches, then we
4378 // can merge the two into just the Static symbol to avoid
4379 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004380 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4381 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4382 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004383 {
Greg Claytond81088c2014-01-16 01:38:29 +00004384 bool found_it = false;
4385 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004386 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004387 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 +00004388 {
4389 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4390 // We just need the flags from the linker symbol, so put these flags
4391 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
4392 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4393 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4394 sym[sym_idx].Clear();
4395 found_it = true;
4396 break;
4397 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004398 }
Greg Claytond81088c2014-01-16 01:38:29 +00004399 if (found_it)
4400 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004401 }
4402 else
4403 {
4404 // Combine N_GSYM stab entries with the non stab symbol
Greg Claytonddaf6a72015-07-08 22:32:23 +00004405 const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
Greg Clayton14cd13c2015-07-01 23:29:06 +00004406 if (gsym_name)
Greg Claytonfd814c52013-08-13 01:42:25 +00004407 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00004408 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
4409 if (pos != N_GSYM_name_to_sym_idx.end())
4410 {
4411 const uint32_t GSYM_sym_idx = pos->second;
4412 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4413 // Copy the address, because often the N_GSYM address has an invalid address of zero
4414 // when the global is a common symbol
4415 sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
4416 sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
4417 // We just need the flags from the linker symbol, so put these flags
4418 // into the N_GSYM flags to avoid duplicate symbols in the symbol table
4419 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4420 sym[sym_idx].Clear();
4421 continue;
4422 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004423 }
4424 }
4425 }
4426 }
4427
4428 sym[sym_idx].SetID (nlist_idx);
4429 sym[sym_idx].SetType (type);
Greg Clayton60038be2015-02-14 00:51:13 +00004430 if (set_value)
4431 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004432 sym[sym_idx].GetAddressRef().SetSection (symbol_section);
4433 sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
Greg Clayton60038be2015-02-14 00:51:13 +00004434 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004435 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4436
4437 if (symbol_byte_size > 0)
4438 sym[sym_idx].SetByteSize(symbol_byte_size);
4439
4440 if (demangled_is_synthesized)
4441 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4442
4443 ++sym_idx;
4444 }
4445 else
4446 {
4447 sym[sym_idx].Clear();
4448 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004449 }
Greg Clayton60038be2015-02-14 00:51:13 +00004450
4451 for (const auto &pos :reexport_shlib_needs_fixup)
4452 {
4453 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4454 if (undef_pos != undefined_name_to_desc.end())
4455 {
4456 const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4457 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4458 sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
4459 }
4460 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004461 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004462
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004463 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4464
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004465 if (function_starts_count > 0)
4466 {
4467 char synthetic_function_symbol[PATH_MAX];
4468 uint32_t num_synthetic_function_symbols = 0;
4469 for (i=0; i<function_starts_count; ++i)
4470 {
4471 if (function_starts.GetEntryRef (i).data == false)
4472 ++num_synthetic_function_symbols;
4473 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004474
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004475 if (num_synthetic_function_symbols > 0)
4476 {
4477 if (num_syms < sym_idx + num_synthetic_function_symbols)
4478 {
4479 num_syms = sym_idx + num_synthetic_function_symbols;
4480 sym = symtab->Resize (num_syms);
4481 }
4482 uint32_t synthetic_function_symbol_idx = 0;
4483 for (i=0; i<function_starts_count; ++i)
4484 {
4485 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
4486 if (func_start_entry->data == false)
4487 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004488 addr_t symbol_file_addr = func_start_entry->addr;
4489 uint32_t symbol_flags = 0;
4490 if (is_arm)
4491 {
4492 if (symbol_file_addr & 1)
4493 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Greg Claytonb887da12015-07-16 19:50:57 +00004494 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004495 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004496 Address symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004497 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004498 {
4499 SectionSP symbol_section (symbol_addr.GetSection());
4500 uint32_t symbol_byte_size = 0;
4501 if (symbol_section)
4502 {
4503 const addr_t section_file_addr = symbol_section->GetFileAddress();
4504 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4505 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4506 if (next_func_start_entry)
4507 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004508 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4509 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004510 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004511 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 +00004512 }
4513 else
4514 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004515 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004516 }
4517 snprintf (synthetic_function_symbol,
4518 sizeof(synthetic_function_symbol),
4519 "___lldb_unnamed_function%u$$%s",
4520 ++synthetic_function_symbol_idx,
4521 module_sp->GetFileSpec().GetFilename().GetCString());
4522 sym[sym_idx].SetID (synthetic_sym_id++);
Greg Clayton037520e2012-07-18 23:18:10 +00004523 sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004524 sym[sym_idx].SetType (eSymbolTypeCode);
4525 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004526 sym[sym_idx].GetAddressRef() = symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004527 if (symbol_flags)
4528 sym[sym_idx].SetFlags (symbol_flags);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004529 if (symbol_byte_size)
4530 sym[sym_idx].SetByteSize (symbol_byte_size);
4531 ++sym_idx;
4532 }
4533 }
4534 }
4535 }
4536 }
4537 }
4538
4539 // Trim our symbols down to just what we ended up with after
4540 // removing any symbols.
4541 if (sym_idx < num_syms)
4542 {
4543 num_syms = sym_idx;
4544 sym = symtab->Resize (num_syms);
4545 }
4546
4547 // Now synthesize indirect symbols
4548 if (m_dysymtab.nindirectsyms != 0)
4549 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004550 if (indirect_symbol_index_data.GetByteSize())
4551 {
4552 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
4553
4554 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
4555 {
Charles Davis510938e2013-08-27 05:04:57 +00004556 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004557 {
4558 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4559 if (symbol_stub_byte_size == 0)
4560 continue;
4561
4562 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4563
4564 if (num_symbol_stubs == 0)
4565 continue;
4566
4567 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
4568 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
4569 {
4570 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
4571 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 +00004572 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004573 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
4574 {
4575 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
Charles Davis510938e2013-08-27 05:04:57 +00004576 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004577 continue;
4578
4579 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
4580 Symbol *stub_symbol = NULL;
4581 if (index_pos != end_index_pos)
4582 {
4583 // We have a remapping from the original nlist index to
4584 // a current symbol index, so just look this up by index
4585 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
4586 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004587 else
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004588 {
4589 // We need to lookup a symbol using the original nlist
Jason Molenda4e7511e2013-03-06 23:19:17 +00004590 // symbol index since this index is coming from the
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004591 // S_SYMBOL_STUBS
4592 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
4593 }
4594
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004595 if (stub_symbol)
4596 {
4597 Address so_addr(symbol_stub_addr, section_list);
4598
4599 if (stub_symbol->GetType() == eSymbolTypeUndefined)
4600 {
4601 // Change the external symbol into a trampoline that makes sense
4602 // These symbols were N_UNDF N_EXT, and are useless to us, so we
4603 // can re-use them so we don't have to make up a synthetic symbol
4604 // for no good reason.
Greg Clayton9191db42013-10-21 18:40:51 +00004605 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4606 stub_symbol->SetType (eSymbolTypeTrampoline);
4607 else
4608 stub_symbol->SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004609 stub_symbol->SetExternal (false);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004610 stub_symbol->GetAddressRef() = so_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004611 stub_symbol->SetByteSize (symbol_stub_byte_size);
4612 }
4613 else
4614 {
4615 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda0a287e02012-04-24 02:09:58 +00004616 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004617 if (sym_idx >= num_syms)
Jason Molenda0a287e02012-04-24 02:09:58 +00004618 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004619 sym = symtab->Resize (++num_syms);
Jason Molenda0a287e02012-04-24 02:09:58 +00004620 stub_symbol = NULL; // this pointer no longer valid
4621 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004622 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda0a287e02012-04-24 02:09:58 +00004623 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton9191db42013-10-21 18:40:51 +00004624 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4625 sym[sym_idx].SetType (eSymbolTypeTrampoline);
4626 else
4627 sym[sym_idx].SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004628 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004629 sym[sym_idx].GetAddressRef() = so_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004630 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
4631 ++sym_idx;
4632 }
4633 }
Greg Clayton3f839a32012-09-05 01:38:55 +00004634 else
4635 {
4636 if (log)
4637 log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
4638 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004639 }
4640 }
4641 }
4642 }
4643 }
4644 }
Greg Clayton9191db42013-10-21 18:40:51 +00004645
Greg Clayton9191db42013-10-21 18:40:51 +00004646 if (!trie_entries.empty())
4647 {
4648 for (const auto &e : trie_entries)
4649 {
4650 if (e.entry.import_name)
4651 {
Greg Clayton60038be2015-02-14 00:51:13 +00004652 // Only add indirect symbols from the Trie entries if we
4653 // didn't have a N_INDR nlist entry for this already
4654 if (indirect_symbol_names.find(e.entry.name) == indirect_symbol_names.end())
Greg Clayton9191db42013-10-21 18:40:51 +00004655 {
Greg Clayton60038be2015-02-14 00:51:13 +00004656 // Make a synthetic symbol to describe re-exported symbol.
4657 if (sym_idx >= num_syms)
4658 sym = symtab->Resize (++num_syms);
4659 sym[sym_idx].SetID (synthetic_sym_id++);
4660 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4661 sym[sym_idx].SetType (eSymbolTypeReExported);
4662 sym[sym_idx].SetIsSynthetic (true);
4663 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4664 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
4665 {
4666 sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
4667 }
4668 ++sym_idx;
Greg Clayton9191db42013-10-21 18:40:51 +00004669 }
Greg Clayton9191db42013-10-21 18:40:51 +00004670 }
4671 }
4672 }
Eugene Zelenko8157a882015-10-23 16:56:07 +00004673
Greg Clayton3046e662013-07-10 01:23:25 +00004674// StreamFile s(stdout, false);
4675// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
4676// symtab->Dump(&s, NULL, eSortOrderNone);
4677 // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
4678 symtab->CalculateSymbolSizes();
4679
4680// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
4681// symtab->Dump(&s, NULL, eSortOrderNone);
4682
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004683 return symtab->GetNumSymbols();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004684 }
4685 return 0;
4686}
4687
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004688void
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 +00004760bool
4761ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header,
4762 const lldb_private::DataExtractor &data,
4763 lldb::offset_t lc_offset,
4764 ArchSpec &arch)
4765{
4766 arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype);
4767
4768 if (arch.IsValid())
4769 {
4770 llvm::Triple &triple = arch.GetTriple();
Greg Claytona3706882015-10-28 23:26:59 +00004771
4772 // Set OS to an unspecified unknown or a "*" so it can match any OS
4773 triple.setOS(llvm::Triple::UnknownOS);
4774 triple.setOSName(llvm::StringRef());
4775
Greg Clayton7ab7f892014-05-29 21:33:45 +00004776 if (header.filetype == MH_PRELOAD)
4777 {
Greg Claytona3706882015-10-28 23:26:59 +00004778 // Set vendor to an unspecified unknown or a "*" so it can match any vendor
4779 triple.setVendor(llvm::Triple::UnknownVendor);
4780 triple.setVendorName(llvm::StringRef());
Greg Clayton7ab7f892014-05-29 21:33:45 +00004781 return true;
4782 }
4783 else
4784 {
4785 struct load_command load_cmd;
Greg Claytona3706882015-10-28 23:26:59 +00004786
Greg Clayton7ab7f892014-05-29 21:33:45 +00004787 lldb::offset_t offset = lc_offset;
4788 for (uint32_t i=0; i<header.ncmds; ++i)
4789 {
4790 const lldb::offset_t cmd_offset = offset;
4791 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4792 break;
4793
4794 switch (load_cmd.cmd)
4795 {
4796 case LC_VERSION_MIN_IPHONEOS:
4797 triple.setOS (llvm::Triple::IOS);
4798 return true;
4799
4800 case LC_VERSION_MIN_MACOSX:
4801 triple.setOS (llvm::Triple::MacOSX);
4802 return true;
4803
4804 default:
4805 break;
4806 }
4807
4808 offset = cmd_offset + load_cmd.cmdsize;
4809 }
4810
Greg Claytona3706882015-10-28 23:26:59 +00004811 if (header.filetype != MH_KEXT_BUNDLE)
4812 {
4813 // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT
4814 // so lets not say our Vendor is Apple, leave it as an unspecified unknown
4815 triple.setVendor(llvm::Triple::UnknownVendor);
4816 triple.setVendorName(llvm::StringRef());
4817 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00004818 }
4819 }
4820 return arch.IsValid();
4821}
4822
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004823bool
Greg Clayton60830262011-02-04 18:53:10 +00004824ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004825{
Greg Claytona1743492012-03-13 23:14:29 +00004826 ModuleSP module_sp(GetModule());
4827 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004828 {
Greg Claytona1743492012-03-13 23:14:29 +00004829 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Claytonc7bece562013-01-25 18:06:21 +00004830 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +00004831 return GetUUID (m_header, m_data, offset, *uuid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004832 }
4833 return false;
4834}
4835
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004836uint32_t
4837ObjectFileMachO::GetDependentModules (FileSpecList& files)
4838{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004839 uint32_t count = 0;
Greg Claytona1743492012-03-13 23:14:29 +00004840 ModuleSP module_sp(GetModule());
4841 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004842 {
Greg Claytona1743492012-03-13 23:14:29 +00004843 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4844 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004845 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Clayton5a271952015-06-02 22:43:29 +00004846 std::vector<std::string> rpath_paths;
4847 std::vector<std::string> rpath_relative_paths;
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004848 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 +00004849 uint32_t i;
4850 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004851 {
Greg Claytona1743492012-03-13 23:14:29 +00004852 const uint32_t cmd_offset = offset;
4853 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4854 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004855
Greg Claytona1743492012-03-13 23:14:29 +00004856 switch (load_cmd.cmd)
4857 {
Greg Clayton5a271952015-06-02 22:43:29 +00004858 case LC_RPATH:
Charles Davis510938e2013-08-27 05:04:57 +00004859 case LC_LOAD_DYLIB:
4860 case LC_LOAD_WEAK_DYLIB:
4861 case LC_REEXPORT_DYLIB:
4862 case LC_LOAD_DYLINKER:
4863 case LC_LOADFVMLIB:
4864 case LC_LOAD_UPWARD_DYLIB:
Greg Claytona1743492012-03-13 23:14:29 +00004865 {
4866 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
4867 const char *path = m_data.PeekCStr(name_offset);
Greg Clayton5a271952015-06-02 22:43:29 +00004868 if (path)
Greg Claytona1743492012-03-13 23:14:29 +00004869 {
Greg Clayton5a271952015-06-02 22:43:29 +00004870 if (load_cmd.cmd == LC_RPATH)
4871 rpath_paths.push_back(path);
4872 else
4873 {
4874 if (path[0] == '@')
4875 {
4876 if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
4877 rpath_relative_paths.push_back(path + strlen("@rpath"));
4878 }
4879 else
4880 {
4881 FileSpec file_spec(path, resolve_path);
4882 if (files.AppendIfUnique(file_spec))
4883 count++;
4884 }
4885 }
Greg Claytona1743492012-03-13 23:14:29 +00004886 }
4887 }
4888 break;
4889
4890 default:
4891 break;
4892 }
4893 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004894 }
Greg Clayton5a271952015-06-02 22:43:29 +00004895
4896 if (!rpath_paths.empty())
4897 {
4898 // Fixup all LC_RPATH values to be absolute paths
4899 FileSpec this_file_spec(m_file);
4900 this_file_spec.ResolvePath();
4901 std::string loader_path("@loader_path");
4902 std::string executable_path("@executable_path");
4903 for (auto &rpath : rpath_paths)
4904 {
4905 if (rpath.find(loader_path) == 0)
4906 {
4907 rpath.erase(0, loader_path.size());
4908 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
4909 }
4910 else if (rpath.find(executable_path) == 0)
4911 {
4912 rpath.erase(0, executable_path.size());
4913 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
4914 }
4915 }
4916
4917 for (const auto &rpath_relative_path : rpath_relative_paths)
4918 {
4919 for (const auto &rpath : rpath_paths)
4920 {
4921 std::string path = rpath;
4922 path += rpath_relative_path;
4923 // It is OK to resolve this path because we must find a file on
4924 // disk for us to accept it anyway if it is rpath relative.
4925 FileSpec file_spec(path, true);
4926 // Remove any redundant parts of the path (like "../foo") since
4927 // LC_RPATH values often contain "..".
4928 file_spec.NormalizePath ();
4929 if (file_spec.Exists() && files.AppendIfUnique(file_spec))
4930 {
4931 count++;
4932 break;
4933 }
4934 }
4935 }
4936 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004937 }
4938 return count;
4939}
4940
Jim Ingham672e6f52011-03-07 23:44:08 +00004941lldb_private::Address
Jason Molenda4e7511e2013-03-06 23:19:17 +00004942ObjectFileMachO::GetEntryPointAddress ()
Jim Ingham672e6f52011-03-07 23:44:08 +00004943{
4944 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
4945 // is initialized to an invalid address, so we can just return that.
4946 // 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 +00004947
Jim Ingham672e6f52011-03-07 23:44:08 +00004948 if (!IsExecutable() || m_entry_point_address.IsValid())
4949 return m_entry_point_address;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004950
4951 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
Jim Ingham672e6f52011-03-07 23:44:08 +00004952 // /usr/include/mach-o.h, but it is basically:
4953 //
4954 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
4955 // uint32_t count - this is the count of longs in the thread state data
4956 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
4957 // <repeat this trio>
Jason Molenda4e7511e2013-03-06 23:19:17 +00004958 //
Jim Ingham672e6f52011-03-07 23:44:08 +00004959 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
4960 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
4961 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
4962 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
4963 //
4964 // For now we hard-code the offsets and flavors we need:
4965 //
4966 //
4967
Greg Claytona1743492012-03-13 23:14:29 +00004968 ModuleSP module_sp(GetModule());
4969 if (module_sp)
Jim Ingham672e6f52011-03-07 23:44:08 +00004970 {
Greg Claytona1743492012-03-13 23:14:29 +00004971 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4972 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004973 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00004974 uint32_t i;
4975 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
4976 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +00004977
Greg Claytona1743492012-03-13 23:14:29 +00004978 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham672e6f52011-03-07 23:44:08 +00004979 {
Greg Claytonc7bece562013-01-25 18:06:21 +00004980 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00004981 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4982 break;
4983
4984 switch (load_cmd.cmd)
Jim Ingham672e6f52011-03-07 23:44:08 +00004985 {
Charles Davis510938e2013-08-27 05:04:57 +00004986 case LC_UNIXTHREAD:
4987 case LC_THREAD:
Jim Ingham672e6f52011-03-07 23:44:08 +00004988 {
Greg Claytona1743492012-03-13 23:14:29 +00004989 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham672e6f52011-03-07 23:44:08 +00004990 {
Greg Claytona1743492012-03-13 23:14:29 +00004991 uint32_t flavor = m_data.GetU32(&offset);
4992 uint32_t count = m_data.GetU32(&offset);
4993 if (count == 0)
4994 {
4995 // We've gotten off somehow, log and exit;
4996 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00004997 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004998
Greg Claytona1743492012-03-13 23:14:29 +00004999 switch (m_header.cputype)
5000 {
Charles Davis510938e2013-08-27 05:04:57 +00005001 case llvm::MachO::CPU_TYPE_ARM:
Greg Claytona1743492012-03-13 23:14:29 +00005002 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
5003 {
5004 offset += 60; // This is the offset of pc in the GPR thread state data structure.
5005 start_address = m_data.GetU32(&offset);
5006 done = true;
5007 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005008 break;
Jason Molendaa3329782014-03-29 18:54:20 +00005009 case llvm::MachO::CPU_TYPE_ARM64:
5010 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
5011 {
5012 offset += 256; // This is the offset of pc in the GPR thread state data structure.
5013 start_address = m_data.GetU64(&offset);
5014 done = true;
5015 }
5016 break;
Charles Davis510938e2013-08-27 05:04:57 +00005017 case llvm::MachO::CPU_TYPE_I386:
Greg Claytona1743492012-03-13 23:14:29 +00005018 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
5019 {
5020 offset += 40; // This is the offset of eip in the GPR thread state data structure.
5021 start_address = m_data.GetU32(&offset);
5022 done = true;
5023 }
5024 break;
Charles Davis510938e2013-08-27 05:04:57 +00005025 case llvm::MachO::CPU_TYPE_X86_64:
Greg Claytona1743492012-03-13 23:14:29 +00005026 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
5027 {
5028 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
5029 start_address = m_data.GetU64(&offset);
5030 done = true;
5031 }
5032 break;
5033 default:
5034 return m_entry_point_address;
5035 }
5036 // Haven't found the GPR flavor yet, skip over the data for this flavor:
5037 if (done)
5038 break;
5039 offset += count * 4;
5040 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005041 }
Greg Claytona1743492012-03-13 23:14:29 +00005042 break;
Charles Davis510938e2013-08-27 05:04:57 +00005043 case LC_MAIN:
Sean Callanan226b70c2012-03-08 02:39:03 +00005044 {
Greg Claytona1743492012-03-13 23:14:29 +00005045 ConstString text_segment_name ("__TEXT");
5046 uint64_t entryoffset = m_data.GetU64(&offset);
5047 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
5048 if (text_segment_sp)
5049 {
5050 done = true;
5051 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5052 }
Sean Callanan226b70c2012-03-08 02:39:03 +00005053 }
Greg Claytona1743492012-03-13 23:14:29 +00005054
5055 default:
5056 break;
Sean Callanan226b70c2012-03-08 02:39:03 +00005057 }
Greg Claytona1743492012-03-13 23:14:29 +00005058 if (done)
5059 break;
Jim Ingham672e6f52011-03-07 23:44:08 +00005060
Greg Claytona1743492012-03-13 23:14:29 +00005061 // Go to the next load command:
5062 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham672e6f52011-03-07 23:44:08 +00005063 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005064
Greg Claytona1743492012-03-13 23:14:29 +00005065 if (start_address != LLDB_INVALID_ADDRESS)
Greg Claytone72dfb32012-02-24 01:59:29 +00005066 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00005067 // We got the start address from the load commands, so now resolve that address in the sections
Greg Claytona1743492012-03-13 23:14:29 +00005068 // of this ObjectFile:
5069 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Claytone72dfb32012-02-24 01:59:29 +00005070 {
Greg Claytona1743492012-03-13 23:14:29 +00005071 m_entry_point_address.Clear();
5072 }
5073 }
5074 else
5075 {
5076 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
5077 // "start" symbol in the main executable.
Jason Molenda4e7511e2013-03-06 23:19:17 +00005078
Greg Claytona1743492012-03-13 23:14:29 +00005079 ModuleSP module_sp (GetModule());
Jason Molenda4e7511e2013-03-06 23:19:17 +00005080
Greg Claytona1743492012-03-13 23:14:29 +00005081 if (module_sp)
5082 {
5083 SymbolContextList contexts;
5084 SymbolContext context;
5085 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
5086 {
5087 if (contexts.GetContextAtIndex(0, context))
5088 m_entry_point_address = context.symbol->GetAddress();
5089 }
Greg Claytone72dfb32012-02-24 01:59:29 +00005090 }
5091 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005092 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005093
Jim Ingham672e6f52011-03-07 23:44:08 +00005094 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00005095}
5096
Greg Claytonc9660542012-02-05 02:38:54 +00005097lldb_private::Address
5098ObjectFileMachO::GetHeaderAddress ()
5099{
5100 lldb_private::Address header_addr;
5101 SectionList *section_list = GetSectionList();
5102 if (section_list)
5103 {
5104 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
5105 if (text_segment_sp)
5106 {
Greg Claytone72dfb32012-02-24 01:59:29 +00005107 header_addr.SetSection (text_segment_sp);
Greg Claytonc9660542012-02-05 02:38:54 +00005108 header_addr.SetOffset (0);
5109 }
5110 }
5111 return header_addr;
5112}
5113
Greg Claytonc3776bf2012-02-09 06:16:32 +00005114uint32_t
5115ObjectFileMachO::GetNumThreadContexts ()
5116{
Greg Claytona1743492012-03-13 23:14:29 +00005117 ModuleSP module_sp(GetModule());
5118 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005119 {
Greg Claytona1743492012-03-13 23:14:29 +00005120 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5121 if (!m_thread_context_offsets_valid)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005122 {
Greg Claytona1743492012-03-13 23:14:29 +00005123 m_thread_context_offsets_valid = true;
Greg Claytonc7bece562013-01-25 18:06:21 +00005124 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005125 FileRangeArray::Entry file_range;
5126 thread_command thread_cmd;
5127 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005128 {
Greg Claytona1743492012-03-13 23:14:29 +00005129 const uint32_t cmd_offset = offset;
5130 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
5131 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005132
Charles Davis510938e2013-08-27 05:04:57 +00005133 if (thread_cmd.cmd == LC_THREAD)
Greg Claytona1743492012-03-13 23:14:29 +00005134 {
5135 file_range.SetRangeBase (offset);
5136 file_range.SetByteSize (thread_cmd.cmdsize - 8);
5137 m_thread_context_offsets.Append (file_range);
5138 }
5139 offset = cmd_offset + thread_cmd.cmdsize;
Greg Claytonc3776bf2012-02-09 06:16:32 +00005140 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00005141 }
5142 }
5143 return m_thread_context_offsets.GetSize();
5144}
5145
5146lldb::RegisterContextSP
5147ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
5148{
Greg Claytonc3776bf2012-02-09 06:16:32 +00005149 lldb::RegisterContextSP reg_ctx_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +00005150
Greg Claytona1743492012-03-13 23:14:29 +00005151 ModuleSP module_sp(GetModule());
5152 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005153 {
Greg Claytona1743492012-03-13 23:14:29 +00005154 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5155 if (!m_thread_context_offsets_valid)
5156 GetNumThreadContexts ();
5157
5158 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
Jim Ingham28eb5712012-10-12 17:34:26 +00005159 if (thread_context_file_range)
Greg Claytona1743492012-03-13 23:14:29 +00005160 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00005161
5162 DataExtractor data (m_data,
5163 thread_context_file_range->GetRangeBase(),
Jim Ingham28eb5712012-10-12 17:34:26 +00005164 thread_context_file_range->GetByteSize());
5165
5166 switch (m_header.cputype)
5167 {
Jason Molendaa3329782014-03-29 18:54:20 +00005168 case llvm::MachO::CPU_TYPE_ARM64:
5169 reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
5170 break;
5171
Charles Davis510938e2013-08-27 05:04:57 +00005172 case llvm::MachO::CPU_TYPE_ARM:
Jim Ingham28eb5712012-10-12 17:34:26 +00005173 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
5174 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005175
Charles Davis510938e2013-08-27 05:04:57 +00005176 case llvm::MachO::CPU_TYPE_I386:
Jim Ingham28eb5712012-10-12 17:34:26 +00005177 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
5178 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005179
Charles Davis510938e2013-08-27 05:04:57 +00005180 case llvm::MachO::CPU_TYPE_X86_64:
Jim Ingham28eb5712012-10-12 17:34:26 +00005181 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
5182 break;
5183 }
Greg Claytona1743492012-03-13 23:14:29 +00005184 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00005185 }
5186 return reg_ctx_sp;
5187}
5188
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005189ObjectFile::Type
5190ObjectFileMachO::CalculateType()
5191{
5192 switch (m_header.filetype)
5193 {
Charles Davis510938e2013-08-27 05:04:57 +00005194 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005195 if (GetAddressByteSize () == 4)
5196 {
5197 // 32 bit kexts are just object files, but they do have a valid
5198 // UUID load command.
5199 UUID uuid;
5200 if (GetUUID(&uuid))
5201 {
5202 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00005203 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005204 // "OSKextGetCurrentIdentifier" as this is required of kexts
5205 if (m_strata == eStrataInvalid)
5206 m_strata = eStrataKernel;
5207 return eTypeSharedLibrary;
5208 }
5209 }
5210 return eTypeObjectFile;
5211
Charles Davis510938e2013-08-27 05:04:57 +00005212 case MH_EXECUTE: return eTypeExecutable; // 0x2u
5213 case MH_FVMLIB: return eTypeSharedLibrary; // 0x3u
5214 case MH_CORE: return eTypeCoreFile; // 0x4u
5215 case MH_PRELOAD: return eTypeSharedLibrary; // 0x5u
5216 case MH_DYLIB: return eTypeSharedLibrary; // 0x6u
5217 case MH_DYLINKER: return eTypeDynamicLinker; // 0x7u
5218 case MH_BUNDLE: return eTypeSharedLibrary; // 0x8u
5219 case MH_DYLIB_STUB: return eTypeStubLibrary; // 0x9u
5220 case MH_DSYM: return eTypeDebugInfo; // 0xAu
5221 case MH_KEXT_BUNDLE: return eTypeSharedLibrary; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005222 default:
5223 break;
5224 }
5225 return eTypeUnknown;
5226}
5227
5228ObjectFile::Strata
5229ObjectFileMachO::CalculateStrata()
5230{
5231 switch (m_header.filetype)
5232 {
Charles Davis510938e2013-08-27 05:04:57 +00005233 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005234 {
5235 // 32 bit kexts are just object files, but they do have a valid
5236 // UUID load command.
5237 UUID uuid;
5238 if (GetUUID(&uuid))
5239 {
5240 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00005241 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005242 // "OSKextGetCurrentIdentifier" as this is required of kexts
5243 if (m_type == eTypeInvalid)
5244 m_type = eTypeSharedLibrary;
5245
5246 return eStrataKernel;
5247 }
5248 }
5249 return eStrataUnknown;
5250
Charles Davis510938e2013-08-27 05:04:57 +00005251 case MH_EXECUTE: // 0x2u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005252 // Check for the MH_DYLDLINK bit in the flags
Charles Davis510938e2013-08-27 05:04:57 +00005253 if (m_header.flags & MH_DYLDLINK)
Sean Callanan49bce8e2012-02-10 20:22:35 +00005254 {
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005255 return eStrataUser;
Sean Callanan49bce8e2012-02-10 20:22:35 +00005256 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005257 else
Sean Callanan49bce8e2012-02-10 20:22:35 +00005258 {
5259 SectionList *section_list = GetSectionList();
5260 if (section_list)
5261 {
5262 static ConstString g_kld_section_name ("__KLD");
5263 if (section_list->FindSectionByName(g_kld_section_name))
5264 return eStrataKernel;
5265 }
5266 }
5267 return eStrataRawImage;
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005268
Charles Davis510938e2013-08-27 05:04:57 +00005269 case MH_FVMLIB: return eStrataUser; // 0x3u
5270 case MH_CORE: return eStrataUnknown; // 0x4u
5271 case MH_PRELOAD: return eStrataRawImage; // 0x5u
5272 case MH_DYLIB: return eStrataUser; // 0x6u
5273 case MH_DYLINKER: return eStrataUser; // 0x7u
5274 case MH_BUNDLE: return eStrataUser; // 0x8u
5275 case MH_DYLIB_STUB: return eStrataUser; // 0x9u
5276 case MH_DSYM: return eStrataUnknown; // 0xAu
5277 case MH_KEXT_BUNDLE: return eStrataKernel; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005278 default:
5279 break;
5280 }
5281 return eStrataUnknown;
5282}
5283
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
Jason Molenda0e0954c2013-04-16 06:24:42 +00005351UUID
5352ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
5353{
5354 UUID uuid;
5355 if (process)
5356 {
5357 addr_t all_image_infos = process->GetImageInfoAddress();
5358
5359 // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
5360 // or it may be the address of the dyld_all_image_infos structure (want). The first four
5361 // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
5362 // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
5363
5364 Error err;
5365 uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00005366 if (version_or_magic != static_cast<uint32_t>(-1)
Charles Davis510938e2013-08-27 05:04:57 +00005367 && version_or_magic != MH_MAGIC
5368 && version_or_magic != MH_CIGAM
5369 && version_or_magic != MH_MAGIC_64
5370 && version_or_magic != MH_CIGAM_64
Jason Molenda0e0954c2013-04-16 06:24:42 +00005371 && version_or_magic >= 13)
5372 {
5373 addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
5374 int wordsize = process->GetAddressByteSize();
5375 if (wordsize == 8)
5376 {
5377 sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
5378 }
5379 if (wordsize == 4)
5380 {
5381 sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
5382 }
5383 if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
5384 {
5385 uuid_t shared_cache_uuid;
5386 if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
5387 {
5388 uuid.SetBytes (shared_cache_uuid);
5389 }
5390 }
5391 }
5392 }
5393 return uuid;
5394}
5395
5396UUID
5397ObjectFileMachO::GetLLDBSharedCacheUUID ()
5398{
5399 UUID uuid;
Todd Fiala013434e2014-07-09 01:29:05 +00005400#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +00005401 uint8_t *(*dyld_get_all_image_infos)(void);
5402 dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
5403 if (dyld_get_all_image_infos)
5404 {
5405 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5406 if (dyld_all_image_infos_address)
5407 {
Jason Molendac9cb7d22013-04-16 21:42:58 +00005408 uint32_t *version = (uint32_t*) dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5409 if (*version >= 13)
Jason Molenda0e0954c2013-04-16 06:24:42 +00005410 {
Jason Molendaa3329782014-03-29 18:54:20 +00005411 uuid_t *sharedCacheUUID_address = 0;
5412 int wordsize = sizeof (uint8_t *);
5413 if (wordsize == 8)
5414 {
5415 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
5416 }
5417 else
5418 {
5419 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84); // sharedCacheUUID <mach-o/dyld_images.h>
5420 }
Jason Molenda0e0954c2013-04-16 06:24:42 +00005421 uuid.SetBytes (sharedCacheUUID_address);
5422 }
5423 }
5424 }
5425#endif
5426 return uuid;
5427}
5428
Greg Clayton9b234982013-10-24 22:54:08 +00005429uint32_t
5430ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
5431{
5432 if (m_min_os_versions.empty())
5433 {
5434 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5435 bool success = false;
5436 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5437 {
5438 const lldb::offset_t load_cmd_offset = offset;
5439
5440 version_min_command lc;
5441 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5442 break;
5443 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5444 {
5445 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5446 {
5447 const uint32_t xxxx = lc.version >> 16;
5448 const uint32_t yy = (lc.version >> 8) & 0xffu;
5449 const uint32_t zz = lc.version & 0xffu;
5450 if (xxxx)
5451 {
5452 m_min_os_versions.push_back(xxxx);
Greg Clayton8031d282015-02-04 00:40:25 +00005453 m_min_os_versions.push_back(yy);
5454 m_min_os_versions.push_back(zz);
Greg Clayton9b234982013-10-24 22:54:08 +00005455 }
5456 success = true;
5457 }
5458 }
5459 offset = load_cmd_offset + lc.cmdsize;
5460 }
5461
5462 if (success == false)
5463 {
5464 // Push an invalid value so we don't keep trying to
5465 m_min_os_versions.push_back(UINT32_MAX);
5466 }
5467 }
5468
5469 if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
5470 {
5471 if (versions != NULL && num_versions > 0)
5472 {
5473 for (size_t i=0; i<num_versions; ++i)
5474 {
5475 if (i < m_min_os_versions.size())
5476 versions[i] = m_min_os_versions[i];
5477 else
5478 versions[i] = 0;
5479 }
5480 }
5481 return m_min_os_versions.size();
5482 }
5483 // Call the superclasses version that will empty out the data
5484 return ObjectFile::GetMinimumOSVersion (versions, num_versions);
5485}
5486
5487uint32_t
5488ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions)
5489{
5490 if (m_sdk_versions.empty())
5491 {
5492 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5493 bool success = false;
5494 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5495 {
5496 const lldb::offset_t load_cmd_offset = offset;
5497
5498 version_min_command lc;
5499 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5500 break;
5501 if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
5502 {
5503 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5504 {
Todd Fialaebecb382014-09-04 19:31:52 +00005505 const uint32_t xxxx = lc.sdk >> 16;
5506 const uint32_t yy = (lc.sdk >> 8) & 0xffu;
5507 const uint32_t zz = lc.sdk & 0xffu;
Greg Clayton9b234982013-10-24 22:54:08 +00005508 if (xxxx)
5509 {
5510 m_sdk_versions.push_back(xxxx);
Greg Clayton8031d282015-02-04 00:40:25 +00005511 m_sdk_versions.push_back(yy);
5512 m_sdk_versions.push_back(zz);
Greg Clayton9b234982013-10-24 22:54:08 +00005513 }
5514 success = true;
5515 }
5516 }
5517 offset = load_cmd_offset + lc.cmdsize;
5518 }
5519
5520 if (success == false)
5521 {
5522 // Push an invalid value so we don't keep trying to
5523 m_sdk_versions.push_back(UINT32_MAX);
5524 }
5525 }
5526
5527 if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
5528 {
5529 if (versions != NULL && num_versions > 0)
5530 {
5531 for (size_t i=0; i<num_versions; ++i)
5532 {
5533 if (i < m_sdk_versions.size())
5534 versions[i] = m_sdk_versions[i];
5535 else
5536 versions[i] = 0;
5537 }
5538 }
5539 return m_sdk_versions.size();
5540 }
5541 // Call the superclasses version that will empty out the data
5542 return ObjectFile::GetSDKVersion (versions, num_versions);
5543}
5544
Greg Clayton08928f32015-02-05 02:01:34 +00005545bool
5546ObjectFileMachO::GetIsDynamicLinkEditor()
5547{
5548 return m_header.filetype == llvm::MachO::MH_DYLINKER;
5549}
5550
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005551//------------------------------------------------------------------
5552// PluginInterface protocol
5553//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00005554lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005555ObjectFileMachO::GetPluginName()
5556{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005557 return GetPluginNameStatic();
5558}
5559
5560uint32_t
5561ObjectFileMachO::GetPluginVersion()
5562{
5563 return 1;
5564}
5565
Greg Clayton07347372015-06-08 21:53:11 +00005566Section *
5567ObjectFileMachO::GetMachHeaderSection()
5568{
5569 // Find the first address of the mach header which is the first non-zero
5570 // file sized section whose file offset is zero. This is the base file address
5571 // of the mach-o file which can be subtracted from the vmaddr of the other
5572 // segments found in memory and added to the load address
5573 ModuleSP module_sp = GetModule();
5574 if (module_sp)
5575 {
5576 SectionList *section_list = GetSectionList ();
5577 if (section_list)
5578 {
5579 lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
5580 const size_t num_sections = section_list->GetSize();
5581
5582 for (size_t sect_idx = 0;
5583 sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
5584 ++sect_idx)
5585 {
5586 Section *section = section_list->GetSectionAtIndex (sect_idx).get();
5587 if (section &&
5588 section->GetFileSize() > 0 &&
5589 section->GetFileOffset() == 0 &&
5590 section->IsThreadSpecific() == false &&
5591 module_sp.get() == section->GetModule().get())
5592 {
5593 return section;
5594 }
5595 }
5596 }
5597 }
5598 return nullptr;
5599}
5600
5601lldb::addr_t
5602ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const Section *mach_header_section, const Section *section)
5603{
5604 ModuleSP module_sp = GetModule();
5605 if (module_sp && mach_header_section && section && mach_header_load_address != LLDB_INVALID_ADDRESS)
5606 {
5607 lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
5608 if (mach_header_file_addr != LLDB_INVALID_ADDRESS)
5609 {
5610 if (section &&
5611 section->GetFileSize() > 0 &&
5612 section->IsThreadSpecific() == false &&
5613 module_sp.get() == section->GetModule().get())
5614 {
5615 // Ignore __LINKEDIT and __DWARF segments
5616 if (section->GetName() == GetSegmentNameLINKEDIT())
5617 {
5618 // Only map __LINKEDIT if we have an in memory image and this isn't
5619 // a kernel binary like a kext or mach_kernel.
5620 const bool is_memory_image = (bool)m_process_wp.lock();
5621 const Strata strata = GetStrata();
5622 if (is_memory_image == false || strata == eStrataKernel)
5623 return LLDB_INVALID_ADDRESS;
5624 }
5625 return section->GetFileAddress() - mach_header_file_addr + mach_header_load_address;
5626 }
5627 }
5628 }
5629 return LLDB_INVALID_ADDRESS;
5630}
5631
Greg Clayton7524e092014-02-06 20:10:16 +00005632bool
Greg Clayton751caf62014-02-07 22:54:47 +00005633ObjectFileMachO::SetLoadAddress (Target &target,
5634 lldb::addr_t value,
5635 bool value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005636{
Greg Clayton7524e092014-02-06 20:10:16 +00005637 ModuleSP module_sp = GetModule();
5638 if (module_sp)
5639 {
5640 size_t num_loaded_sections = 0;
5641 SectionList *section_list = GetSectionList ();
5642 if (section_list)
5643 {
Greg Clayton7524e092014-02-06 20:10:16 +00005644 const size_t num_sections = section_list->GetSize();
5645
Greg Clayton751caf62014-02-07 22:54:47 +00005646 if (value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005647 {
Greg Clayton751caf62014-02-07 22:54:47 +00005648 // "value" is an offset to apply to each top level segment
Greg Clayton7524e092014-02-06 20:10:16 +00005649 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5650 {
5651 // Iterate through the object file sections to find all
5652 // of the sections that size on disk (to avoid __PAGEZERO)
5653 // and load them
5654 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton751caf62014-02-07 22:54:47 +00005655 if (section_sp &&
5656 section_sp->GetFileSize() > 0 &&
5657 section_sp->IsThreadSpecific() == false &&
5658 module_sp.get() == section_sp->GetModule().get())
Greg Clayton7524e092014-02-06 20:10:16 +00005659 {
Greg Clayton751caf62014-02-07 22:54:47 +00005660 // Ignore __LINKEDIT and __DWARF segments
Greg Clayton07347372015-06-08 21:53:11 +00005661 if (section_sp->GetName() == GetSegmentNameLINKEDIT())
Greg Clayton751caf62014-02-07 22:54:47 +00005662 {
5663 // Only map __LINKEDIT if we have an in memory image and this isn't
5664 // a kernel binary like a kext or mach_kernel.
Greg Clayton07347372015-06-08 21:53:11 +00005665 const bool is_memory_image = (bool)m_process_wp.lock();
5666 const Strata strata = GetStrata();
Greg Clayton751caf62014-02-07 22:54:47 +00005667 if (is_memory_image == false || strata == eStrataKernel)
5668 continue;
5669 }
5670 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
Greg Clayton7524e092014-02-06 20:10:16 +00005671 ++num_loaded_sections;
5672 }
5673 }
5674 }
Greg Clayton751caf62014-02-07 22:54:47 +00005675 else
5676 {
5677 // "value" is the new base address of the mach_header, adjust each
5678 // section accordingly
5679
Greg Clayton07347372015-06-08 21:53:11 +00005680 Section *mach_header_section = GetMachHeaderSection();
5681 if (mach_header_section)
Greg Clayton751caf62014-02-07 22:54:47 +00005682 {
5683 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5684 {
Greg Clayton751caf62014-02-07 22:54:47 +00005685 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton07347372015-06-08 21:53:11 +00005686
5687 lldb::addr_t section_load_addr = CalculateSectionLoadAddressForMemoryImage(value, mach_header_section, section_sp.get());
5688 if (section_load_addr != LLDB_INVALID_ADDRESS)
Greg Clayton751caf62014-02-07 22:54:47 +00005689 {
Greg Clayton07347372015-06-08 21:53:11 +00005690 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_load_addr))
Greg Clayton751caf62014-02-07 22:54:47 +00005691 ++num_loaded_sections;
5692 }
5693 }
5694 }
5695 }
Greg Clayton7524e092014-02-06 20:10:16 +00005696 }
Greg Clayton7524e092014-02-06 20:10:16 +00005697 return num_loaded_sections > 0;
5698 }
Jason Molenda5cf1e232014-10-16 07:41:32 +00005699 return false;
Greg Clayton7524e092014-02-06 20:10:16 +00005700}
5701
Greg Claytona2715cf2014-06-13 00:54:12 +00005702bool
5703ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp,
5704 const FileSpec &outfile,
5705 Error &error)
5706{
5707 if (process_sp)
5708 {
5709 Target &target = process_sp->GetTarget();
5710 const ArchSpec target_arch = target.GetArchitecture();
5711 const llvm::Triple &target_triple = target_arch.GetTriple();
5712 if (target_triple.getVendor() == llvm::Triple::Apple &&
5713 (target_triple.getOS() == llvm::Triple::MacOSX ||
5714 target_triple.getOS() == llvm::Triple::IOS))
5715 {
5716 bool make_core = false;
5717 switch (target_arch.GetMachine())
5718 {
Jason Molenda16dc86d2015-06-25 23:58:25 +00005719 case llvm::Triple::aarch64:
Jason Molenda4b0c1182014-11-12 02:39:14 +00005720 case llvm::Triple::arm:
Jason Molenda6d9fe8c2015-08-21 00:13:37 +00005721 case llvm::Triple::thumb:
Greg Claytona2715cf2014-06-13 00:54:12 +00005722 case llvm::Triple::x86:
5723 case llvm::Triple::x86_64:
5724 make_core = true;
5725 break;
5726 default:
5727 error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str());
5728 break;
5729 }
5730
5731 if (make_core)
5732 {
5733 std::vector<segment_command_64> segment_load_commands;
Saleem Abdulrasool3924d752014-06-13 03:30:39 +00005734// uint32_t range_info_idx = 0;
Greg Claytona2715cf2014-06-13 00:54:12 +00005735 MemoryRegionInfo range_info;
5736 Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
Jason Molendad20359d2014-11-11 10:59:15 +00005737 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
5738 const ByteOrder byte_order = target_arch.GetByteOrder();
Greg Claytona2715cf2014-06-13 00:54:12 +00005739 if (range_error.Success())
5740 {
5741 while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS)
5742 {
5743 const addr_t addr = range_info.GetRange().GetRangeBase();
5744 const addr_t size = range_info.GetRange().GetByteSize();
5745
5746 if (size == 0)
5747 break;
5748
5749 // Calculate correct protections
5750 uint32_t prot = 0;
5751 if (range_info.GetReadable() == MemoryRegionInfo::eYes)
5752 prot |= VM_PROT_READ;
5753 if (range_info.GetWritable() == MemoryRegionInfo::eYes)
5754 prot |= VM_PROT_WRITE;
5755 if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
5756 prot |= VM_PROT_EXECUTE;
5757
5758// printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n",
5759// range_info_idx,
5760// addr,
5761// size,
5762// (prot & VM_PROT_READ ) ? 'r' : '-',
5763// (prot & VM_PROT_WRITE ) ? 'w' : '-',
5764// (prot & VM_PROT_EXECUTE) ? 'x' : '-');
5765
5766 if (prot != 0)
5767 {
Jason Molendad20359d2014-11-11 10:59:15 +00005768 uint32_t cmd_type = LC_SEGMENT_64;
5769 uint32_t segment_size = sizeof (segment_command_64);
5770 if (addr_byte_size == 4)
5771 {
5772 cmd_type = LC_SEGMENT;
5773 segment_size = sizeof (segment_command);
5774 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005775 segment_command_64 segment = {
Jason Molendad20359d2014-11-11 10:59:15 +00005776 cmd_type, // uint32_t cmd;
5777 segment_size, // uint32_t cmdsize;
Greg Claytona2715cf2014-06-13 00:54:12 +00005778 {0}, // char segname[16];
Jason Molendad20359d2014-11-11 10:59:15 +00005779 addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
5780 size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
5781 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
5782 size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
Greg Claytona2715cf2014-06-13 00:54:12 +00005783 prot, // uint32_t maxprot;
5784 prot, // uint32_t initprot;
5785 0, // uint32_t nsects;
5786 0 }; // uint32_t flags;
5787 segment_load_commands.push_back(segment);
5788 }
5789 else
5790 {
5791 // No protections and a size of 1 used to be returned from old
5792 // debugservers when we asked about a region that was past the
5793 // last memory region and it indicates the end...
5794 if (size == 1)
5795 break;
5796 }
5797
5798 range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info);
5799 if (range_error.Fail())
5800 break;
5801 }
5802
Greg Claytona2715cf2014-06-13 00:54:12 +00005803 StreamString buffer (Stream::eBinary,
5804 addr_byte_size,
5805 byte_order);
5806
5807 mach_header_64 mach_header;
Jason Molendad20359d2014-11-11 10:59:15 +00005808 if (addr_byte_size == 8)
5809 {
5810 mach_header.magic = MH_MAGIC_64;
5811 }
5812 else
5813 {
5814 mach_header.magic = MH_MAGIC;
5815 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005816 mach_header.cputype = target_arch.GetMachOCPUType();
5817 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
5818 mach_header.filetype = MH_CORE;
5819 mach_header.ncmds = segment_load_commands.size();
5820 mach_header.flags = 0;
5821 mach_header.reserved = 0;
5822 ThreadList &thread_list = process_sp->GetThreadList();
5823 const uint32_t num_threads = thread_list.GetSize();
5824
5825 // Make an array of LC_THREAD data items. Each one contains
5826 // the contents of the LC_THREAD load command. The data doesn't
5827 // contain the load command + load command size, we will
5828 // add the load command and load command size as we emit the data.
5829 std::vector<StreamString> LC_THREAD_datas(num_threads);
5830 for (auto &LC_THREAD_data : LC_THREAD_datas)
5831 {
5832 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
5833 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
5834 LC_THREAD_data.SetByteOrder(byte_order);
5835 }
5836 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
5837 {
5838 ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx));
5839 if (thread_sp)
5840 {
5841 switch (mach_header.cputype)
5842 {
Jason Molenda22952582014-11-12 01:11:36 +00005843 case llvm::MachO::CPU_TYPE_ARM64:
5844 RegisterContextDarwin_arm64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005845 break;
Jason Molenda22952582014-11-12 01:11:36 +00005846
5847 case llvm::MachO::CPU_TYPE_ARM:
5848 RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5849 break;
5850
Greg Claytona2715cf2014-06-13 00:54:12 +00005851 case llvm::MachO::CPU_TYPE_I386:
Jason Molendad20359d2014-11-11 10:59:15 +00005852 RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005853 break;
5854
5855 case llvm::MachO::CPU_TYPE_X86_64:
5856 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5857 break;
5858 }
5859
5860 }
5861 }
5862
5863 // The size of the load command is the size of the segments...
Jason Molendad20359d2014-11-11 10:59:15 +00005864 if (addr_byte_size == 8)
5865 {
5866 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64);
5867 }
5868 else
5869 {
5870 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command);
5871 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005872
5873 // and the size of all LC_THREAD load command
5874 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5875 {
Greg Claytone37df2e2014-09-16 20:50:29 +00005876 ++mach_header.ncmds;
Greg Claytona2715cf2014-06-13 00:54:12 +00005877 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
5878 }
5879
5880 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",
5881 mach_header.magic,
5882 mach_header.cputype,
5883 mach_header.cpusubtype,
5884 mach_header.filetype,
5885 mach_header.ncmds,
5886 mach_header.sizeofcmds,
5887 mach_header.flags,
5888 mach_header.reserved);
5889
5890 // Write the mach header
5891 buffer.PutHex32(mach_header.magic);
5892 buffer.PutHex32(mach_header.cputype);
5893 buffer.PutHex32(mach_header.cpusubtype);
5894 buffer.PutHex32(mach_header.filetype);
5895 buffer.PutHex32(mach_header.ncmds);
5896 buffer.PutHex32(mach_header.sizeofcmds);
5897 buffer.PutHex32(mach_header.flags);
Jason Molendad20359d2014-11-11 10:59:15 +00005898 if (addr_byte_size == 8)
5899 {
5900 buffer.PutHex32(mach_header.reserved);
5901 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005902
5903 // Skip the mach header and all load commands and align to the next
5904 // 0x1000 byte boundary
5905 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
5906 if (file_offset & 0x00000fff)
5907 {
5908 file_offset += 0x00001000ull;
5909 file_offset &= (~0x00001000ull + 1);
5910 }
5911
5912 for (auto &segment : segment_load_commands)
5913 {
5914 segment.fileoff = file_offset;
5915 file_offset += segment.filesize;
5916 }
5917
5918 // Write out all of the LC_THREAD load commands
5919 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5920 {
5921 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
5922 buffer.PutHex32(LC_THREAD);
5923 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
5924 buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size);
5925 }
5926
5927 // Write out all of the segment load commands
5928 for (const auto &segment : segment_load_commands)
5929 {
5930 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",
5931 segment.cmd,
5932 segment.cmdsize,
5933 segment.vmaddr,
5934 segment.vmaddr + segment.vmsize,
5935 segment.fileoff,
5936 segment.filesize,
5937 segment.maxprot,
5938 segment.initprot,
5939 segment.nsects,
5940 segment.flags);
5941
5942 buffer.PutHex32(segment.cmd);
5943 buffer.PutHex32(segment.cmdsize);
5944 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
Jason Molendad20359d2014-11-11 10:59:15 +00005945 if (addr_byte_size == 8)
5946 {
5947 buffer.PutHex64(segment.vmaddr);
5948 buffer.PutHex64(segment.vmsize);
5949 buffer.PutHex64(segment.fileoff);
5950 buffer.PutHex64(segment.filesize);
5951 }
5952 else
5953 {
5954 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
5955 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
5956 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
5957 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
5958 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005959 buffer.PutHex32(segment.maxprot);
5960 buffer.PutHex32(segment.initprot);
5961 buffer.PutHex32(segment.nsects);
5962 buffer.PutHex32(segment.flags);
5963 }
5964
5965 File core_file;
5966 std::string core_file_path(outfile.GetPath());
5967 error = core_file.Open(core_file_path.c_str(),
5968 File::eOpenOptionWrite |
5969 File::eOpenOptionTruncate |
5970 File::eOpenOptionCanCreate);
5971 if (error.Success())
5972 {
5973 // Read 1 page at a time
5974 uint8_t bytes[0x1000];
5975 // Write the mach header and load commands out to the core file
5976 size_t bytes_written = buffer.GetString().size();
5977 error = core_file.Write(buffer.GetString().data(), bytes_written);
5978 if (error.Success())
5979 {
5980 // Now write the file data for all memory segments in the process
5981 for (const auto &segment : segment_load_commands)
5982 {
David Majnemerb98a5e02014-07-24 00:24:12 +00005983 if (core_file.SeekFromStart(segment.fileoff) == -1)
Greg Claytona2715cf2014-06-13 00:54:12 +00005984 {
5985 error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str());
5986 break;
5987 }
5988
Jason Molendad20359d2014-11-11 10:59:15 +00005989 printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr);
Greg Claytona2715cf2014-06-13 00:54:12 +00005990 addr_t bytes_left = segment.vmsize;
5991 addr_t addr = segment.vmaddr;
5992 Error memory_read_error;
5993 while (bytes_left > 0 && error.Success())
5994 {
5995 const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
5996 const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error);
5997 if (bytes_read == bytes_to_read)
5998 {
5999 size_t bytes_written = bytes_read;
6000 error = core_file.Write(bytes, bytes_written);
6001 bytes_left -= bytes_read;
6002 addr += bytes_read;
6003 }
6004 else
6005 {
6006 // Some pages within regions are not readable, those
6007 // should be zero filled
6008 memset (bytes, 0, bytes_to_read);
6009 size_t bytes_written = bytes_to_read;
6010 error = core_file.Write(bytes, bytes_written);
6011 bytes_left -= bytes_to_read;
6012 addr += bytes_to_read;
6013 }
6014 }
6015 }
6016 }
6017 }
6018 }
6019 else
6020 {
6021 error.SetErrorString("process doesn't support getting memory region info");
6022 }
6023 }
6024 return true; // This is the right plug to handle saving core files for this process
6025 }
6026 }
6027 return false;
6028}