blob: 0720c5e8cc95a8f79e175b0a3bc4b2e7c0a01a8a [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 Molenda649a6072015-11-10 05:21:54 +000065// Some structure definitions needed for parsing the dyld shared cache files
66// found on iOS devices.
67
68struct lldb_copy_dyld_cache_header_v1
69{
70 char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
71 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
72 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
73 uint32_t imagesOffset;
74 uint32_t imagesCount;
75 uint64_t dyldBaseAddress;
76 uint64_t codeSignatureOffset;
77 uint64_t codeSignatureSize;
78 uint64_t slideInfoOffset;
79 uint64_t slideInfoSize;
80 uint64_t localSymbolsOffset;
81 uint64_t localSymbolsSize;
82 uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later
83};
84
85struct lldb_copy_dyld_cache_mapping_info
86{
87 uint64_t address;
88 uint64_t size;
89 uint64_t fileOffset;
90 uint32_t maxProt;
91 uint32_t initProt;
92};
93
94struct lldb_copy_dyld_cache_local_symbols_info
95{
96 uint32_t nlistOffset;
97 uint32_t nlistCount;
98 uint32_t stringsOffset;
99 uint32_t stringsSize;
100 uint32_t entriesOffset;
101 uint32_t entriesCount;
102};
103struct lldb_copy_dyld_cache_local_symbols_entry
104{
105 uint32_t dylibOffset;
106 uint32_t nlistStartIndex;
107 uint32_t nlistCount;
108};
109
110
Jason Molenda4e7511e2013-03-06 23:19:17 +0000111class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
Greg Claytonc3776bf2012-02-09 06:16:32 +0000112{
113public:
114 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
115 RegisterContextDarwin_x86_64 (thread, 0)
116 {
117 SetRegisterDataFrom_LC_THREAD (data);
118 }
119
Eugene Zelenko8157a882015-10-23 16:56:07 +0000120 void
121 InvalidateAllRegisters() override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000122 {
123 // Do nothing... registers are always valid...
124 }
125
126 void
127 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
128 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000129 lldb::offset_t offset = 0;
Greg Claytonc3776bf2012-02-09 06:16:32 +0000130 SetError (GPRRegSet, Read, -1);
131 SetError (FPURegSet, Read, -1);
132 SetError (EXCRegSet, Read, -1);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000133 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000134
Greg Claytonc859e2d2012-02-13 23:10:39 +0000135 while (!done)
Greg Claytonc3776bf2012-02-09 06:16:32 +0000136 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000137 int flavor = data.GetU32 (&offset);
138 if (flavor == 0)
139 done = true;
140 else
Greg Claytonc3776bf2012-02-09 06:16:32 +0000141 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000142 uint32_t i;
143 uint32_t count = data.GetU32 (&offset);
144 switch (flavor)
145 {
146 case GPRRegSet:
147 for (i=0; i<count; ++i)
148 (&gpr.rax)[i] = data.GetU64(&offset);
149 SetError (GPRRegSet, Read, 0);
150 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000151
Greg Claytonc859e2d2012-02-13 23:10:39 +0000152 break;
153 case FPURegSet:
154 // TODO: fill in FPU regs....
155 //SetError (FPURegSet, Read, -1);
156 done = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000157
Greg Claytonc859e2d2012-02-13 23:10:39 +0000158 break;
159 case EXCRegSet:
160 exc.trapno = data.GetU32(&offset);
161 exc.err = data.GetU32(&offset);
162 exc.faultvaddr = data.GetU64(&offset);
163 SetError (EXCRegSet, Read, 0);
164 done = true;
165 break;
166 case 7:
167 case 8:
168 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000169 // fancy flavors that encapsulate of the above
170 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000171 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000172
Greg Claytonc859e2d2012-02-13 23:10:39 +0000173 default:
174 done = true;
175 break;
176 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000177 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000178 }
179 }
Jason Molendad20359d2014-11-11 10:59:15 +0000180
Greg Claytona2715cf2014-06-13 00:54:12 +0000181 static size_t
182 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
183 {
184 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
185 if (reg_info == NULL)
186 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
187 if (reg_info)
188 {
189 lldb_private::RegisterValue reg_value;
190 if (reg_ctx->ReadRegister(reg_info, reg_value))
191 {
192 if (reg_info->byte_size >= reg_byte_size)
193 data.Write(reg_value.GetBytes(), reg_byte_size);
194 else
195 {
196 data.Write(reg_value.GetBytes(), reg_info->byte_size);
197 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
198 data.PutChar(0);
199 }
200 return reg_byte_size;
201 }
202 }
203 // Just write zeros if all else fails
204 for (size_t i=0; i<reg_byte_size; ++ i)
205 data.PutChar(0);
206 return reg_byte_size;
207 }
Jason Molendad20359d2014-11-11 10:59:15 +0000208
Greg Claytona2715cf2014-06-13 00:54:12 +0000209 static bool
210 Create_LC_THREAD (Thread *thread, Stream &data)
211 {
212 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
213 if (reg_ctx_sp)
214 {
215 RegisterContext *reg_ctx = reg_ctx_sp.get();
216
217 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000218 data.PutHex32 (GPRWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000219 WriteRegister (reg_ctx, "rax", NULL, 8, data);
220 WriteRegister (reg_ctx, "rbx", NULL, 8, data);
221 WriteRegister (reg_ctx, "rcx", NULL, 8, data);
222 WriteRegister (reg_ctx, "rdx", NULL, 8, data);
223 WriteRegister (reg_ctx, "rdi", NULL, 8, data);
224 WriteRegister (reg_ctx, "rsi", NULL, 8, data);
225 WriteRegister (reg_ctx, "rbp", NULL, 8, data);
226 WriteRegister (reg_ctx, "rsp", NULL, 8, data);
227 WriteRegister (reg_ctx, "r8", NULL, 8, data);
228 WriteRegister (reg_ctx, "r9", NULL, 8, data);
229 WriteRegister (reg_ctx, "r10", NULL, 8, data);
230 WriteRegister (reg_ctx, "r11", NULL, 8, data);
231 WriteRegister (reg_ctx, "r12", NULL, 8, data);
232 WriteRegister (reg_ctx, "r13", NULL, 8, data);
233 WriteRegister (reg_ctx, "r14", NULL, 8, data);
234 WriteRegister (reg_ctx, "r15", NULL, 8, data);
235 WriteRegister (reg_ctx, "rip", NULL, 8, data);
236 WriteRegister (reg_ctx, "rflags", NULL, 8, data);
237 WriteRegister (reg_ctx, "cs", NULL, 8, data);
238 WriteRegister (reg_ctx, "fs", NULL, 8, data);
239 WriteRegister (reg_ctx, "gs", NULL, 8, data);
240
241// // Write out the FPU registers
242// const size_t fpu_byte_size = sizeof(FPU);
243// size_t bytes_written = 0;
244// data.PutHex32 (FPURegSet);
245// data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
246// bytes_written += data.PutHex32(0); // uint32_t pad[0]
247// bytes_written += data.PutHex32(0); // uint32_t pad[1]
248// bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, data); // uint16_t fcw; // "fctrl"
249// bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, data); // uint16_t fsw; // "fstat"
250// bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, data); // uint8_t ftw; // "ftag"
251// bytes_written += data.PutHex8 (0); // uint8_t pad1;
252// bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, data); // uint16_t fop; // "fop"
253// bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, data); // uint32_t ip; // "fioff"
254// bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, data); // uint16_t cs; // "fiseg"
255// bytes_written += data.PutHex16 (0); // uint16_t pad2;
256// bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, data); // uint32_t dp; // "fooff"
257// bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, data); // uint16_t ds; // "foseg"
258// bytes_written += data.PutHex16 (0); // uint16_t pad3;
259// bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, data); // uint32_t mxcsr;
260// bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, 4, data);// uint32_t mxcsrmask;
261// bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, sizeof(MMSReg), data);
262// bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, sizeof(MMSReg), data);
263// bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, sizeof(MMSReg), data);
264// bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, sizeof(MMSReg), data);
265// bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, sizeof(MMSReg), data);
266// bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, sizeof(MMSReg), data);
267// bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, sizeof(MMSReg), data);
268// bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, sizeof(MMSReg), data);
269// bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, sizeof(XMMReg), data);
270// bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, sizeof(XMMReg), data);
271// bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, sizeof(XMMReg), data);
272// bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, sizeof(XMMReg), data);
273// bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, sizeof(XMMReg), data);
274// bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, sizeof(XMMReg), data);
275// bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, sizeof(XMMReg), data);
276// bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, sizeof(XMMReg), data);
277// bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, sizeof(XMMReg), data);
278// bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, sizeof(XMMReg), data);
279// bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, sizeof(XMMReg), data);
280// bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, sizeof(XMMReg), data);
281// bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, sizeof(XMMReg), data);
282// bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, sizeof(XMMReg), data);
283// bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, sizeof(XMMReg), data);
284// bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, sizeof(XMMReg), data);
285//
286// // Fill rest with zeros
287// for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ i)
288// data.PutChar(0);
289
290 // Write out the EXC registers
291 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000292 data.PutHex32 (EXCWordCount);
Greg Claytona2715cf2014-06-13 00:54:12 +0000293 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
294 WriteRegister (reg_ctx, "err", NULL, 4, data);
295 WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data);
296 return true;
297 }
298 return false;
299 }
300
Greg Claytonc859e2d2012-02-13 23:10:39 +0000301protected:
Eugene Zelenko8157a882015-10-23 16:56:07 +0000302 int
303 DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000304 {
305 return 0;
306 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000307
Eugene Zelenko8157a882015-10-23 16:56:07 +0000308 int
309 DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000310 {
311 return 0;
312 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000313
Eugene Zelenko8157a882015-10-23 16:56:07 +0000314 int
315 DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000316 {
317 return 0;
318 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000319
Eugene Zelenko8157a882015-10-23 16:56:07 +0000320 int
321 DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000322 {
323 return 0;
324 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000325
Eugene Zelenko8157a882015-10-23 16:56:07 +0000326 int
327 DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000328 {
329 return 0;
330 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000331
Eugene Zelenko8157a882015-10-23 16:56:07 +0000332 int
333 DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000334 {
335 return 0;
336 }
337};
Greg Claytonc3776bf2012-02-09 06:16:32 +0000338
Jason Molenda4e7511e2013-03-06 23:19:17 +0000339class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
Greg Claytonc859e2d2012-02-13 23:10:39 +0000340{
341public:
342 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
343 RegisterContextDarwin_i386 (thread, 0)
344 {
345 SetRegisterDataFrom_LC_THREAD (data);
346 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000347
Eugene Zelenko8157a882015-10-23 16:56:07 +0000348 void
349 InvalidateAllRegisters() override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000350 {
351 // Do nothing... registers are always valid...
352 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000353
Greg Claytonc859e2d2012-02-13 23:10:39 +0000354 void
355 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
356 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000357 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000358 SetError (GPRRegSet, Read, -1);
359 SetError (FPURegSet, Read, -1);
360 SetError (EXCRegSet, Read, -1);
361 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000362
Greg Claytonc859e2d2012-02-13 23:10:39 +0000363 while (!done)
364 {
365 int flavor = data.GetU32 (&offset);
366 if (flavor == 0)
367 done = true;
368 else
Greg Claytonc3776bf2012-02-09 06:16:32 +0000369 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000370 uint32_t i;
371 uint32_t count = data.GetU32 (&offset);
372 switch (flavor)
373 {
374 case GPRRegSet:
375 for (i=0; i<count; ++i)
376 (&gpr.eax)[i] = data.GetU32(&offset);
377 SetError (GPRRegSet, Read, 0);
378 done = true;
379
380 break;
381 case FPURegSet:
382 // TODO: fill in FPU regs....
383 //SetError (FPURegSet, Read, -1);
384 done = true;
385
386 break;
387 case EXCRegSet:
388 exc.trapno = data.GetU32(&offset);
389 exc.err = data.GetU32(&offset);
390 exc.faultvaddr = data.GetU32(&offset);
391 SetError (EXCRegSet, Read, 0);
392 done = true;
393 break;
394 case 7:
395 case 8:
396 case 9:
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000397 // fancy flavors that encapsulate of the above
398 // flavors...
Greg Claytonc859e2d2012-02-13 23:10:39 +0000399 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +0000400
Greg Claytonc859e2d2012-02-13 23:10:39 +0000401 default:
402 done = true;
403 break;
404 }
Greg Claytonc3776bf2012-02-09 06:16:32 +0000405 }
406 }
407 }
Jason Molendad20359d2014-11-11 10:59:15 +0000408
409 static size_t
410 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
411 {
412 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
413 if (reg_info == NULL)
414 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
415 if (reg_info)
416 {
417 lldb_private::RegisterValue reg_value;
418 if (reg_ctx->ReadRegister(reg_info, reg_value))
419 {
420 if (reg_info->byte_size >= reg_byte_size)
421 data.Write(reg_value.GetBytes(), reg_byte_size);
422 else
423 {
424 data.Write(reg_value.GetBytes(), reg_info->byte_size);
425 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
426 data.PutChar(0);
427 }
428 return reg_byte_size;
429 }
430 }
431 // Just write zeros if all else fails
432 for (size_t i=0; i<reg_byte_size; ++ i)
433 data.PutChar(0);
434 return reg_byte_size;
435 }
436
437 static bool
438 Create_LC_THREAD (Thread *thread, Stream &data)
439 {
440 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
441 if (reg_ctx_sp)
442 {
443 RegisterContext *reg_ctx = reg_ctx_sp.get();
444
445 data.PutHex32 (GPRRegSet); // Flavor
Jason Molenda22952582014-11-12 01:11:36 +0000446 data.PutHex32 (GPRWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000447 WriteRegister (reg_ctx, "eax", NULL, 4, data);
448 WriteRegister (reg_ctx, "ebx", NULL, 4, data);
449 WriteRegister (reg_ctx, "ecx", NULL, 4, data);
450 WriteRegister (reg_ctx, "edx", NULL, 4, data);
451 WriteRegister (reg_ctx, "edi", NULL, 4, data);
452 WriteRegister (reg_ctx, "esi", NULL, 4, data);
453 WriteRegister (reg_ctx, "ebp", NULL, 4, data);
454 WriteRegister (reg_ctx, "esp", NULL, 4, data);
455 WriteRegister (reg_ctx, "ss", NULL, 4, data);
456 WriteRegister (reg_ctx, "eflags", NULL, 4, data);
457 WriteRegister (reg_ctx, "eip", NULL, 4, data);
458 WriteRegister (reg_ctx, "cs", NULL, 4, data);
459 WriteRegister (reg_ctx, "ds", NULL, 4, data);
460 WriteRegister (reg_ctx, "es", NULL, 4, data);
461 WriteRegister (reg_ctx, "fs", NULL, 4, data);
462 WriteRegister (reg_ctx, "gs", NULL, 4, data);
463
464 // Write out the EXC registers
465 data.PutHex32 (EXCRegSet);
Jason Molenda22952582014-11-12 01:11:36 +0000466 data.PutHex32 (EXCWordCount);
Jason Molendad20359d2014-11-11 10:59:15 +0000467 WriteRegister (reg_ctx, "trapno", NULL, 4, data);
468 WriteRegister (reg_ctx, "err", NULL, 4, data);
Jason Molenda22952582014-11-12 01:11:36 +0000469 WriteRegister (reg_ctx, "faultvaddr", NULL, 4, data);
Jason Molendad20359d2014-11-11 10:59:15 +0000470 return true;
471 }
472 return false;
473 }
474
Greg Claytonc3776bf2012-02-09 06:16:32 +0000475protected:
Eugene Zelenko8157a882015-10-23 16:56:07 +0000476 int
477 DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000478 {
479 return 0;
480 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000481
Eugene Zelenko8157a882015-10-23 16:56:07 +0000482 int
483 DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000484 {
485 return 0;
486 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000487
Eugene Zelenko8157a882015-10-23 16:56:07 +0000488 int
489 DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000490 {
491 return 0;
492 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000493
Eugene Zelenko8157a882015-10-23 16:56:07 +0000494 int
495 DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000496 {
497 return 0;
498 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000499
Eugene Zelenko8157a882015-10-23 16:56:07 +0000500 int
501 DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000502 {
503 return 0;
504 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000505
Eugene Zelenko8157a882015-10-23 16:56:07 +0000506 int
507 DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
Greg Claytonc3776bf2012-02-09 06:16:32 +0000508 {
509 return 0;
510 }
511};
512
Jason Molenda4e7511e2013-03-06 23:19:17 +0000513class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
Greg Claytonc859e2d2012-02-13 23:10:39 +0000514{
515public:
516 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
Greg Claytonc2807462012-10-30 23:57:32 +0000517 RegisterContextDarwin_arm (thread, 0)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000518 {
519 SetRegisterDataFrom_LC_THREAD (data);
520 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000521
Eugene Zelenko8157a882015-10-23 16:56:07 +0000522 void
523 InvalidateAllRegisters() override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000524 {
525 // Do nothing... registers are always valid...
526 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000527
Greg Claytonc859e2d2012-02-13 23:10:39 +0000528 void
529 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
530 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000531 lldb::offset_t offset = 0;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000532 SetError (GPRRegSet, Read, -1);
533 SetError (FPURegSet, Read, -1);
534 SetError (EXCRegSet, Read, -1);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000535 bool done = false;
536
537 while (!done)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000538 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000539 int flavor = data.GetU32 (&offset);
540 uint32_t count = data.GetU32 (&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000541 lldb::offset_t next_thread_state = offset + (count * 4);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000542 switch (flavor)
543 {
544 case GPRRegSet:
545 for (uint32_t i=0; i<count; ++i)
Jason Molendaddf91772013-05-14 04:50:47 +0000546 {
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000547 gpr.r[i] = data.GetU32(&offset);
Jason Molendaddf91772013-05-14 04:50:47 +0000548 }
549
550 // Note that gpr.cpsr is also copied by the above loop; this loop technically extends
551 // one element past the end of the gpr.r[] array.
552
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000553 SetError (GPRRegSet, Read, 0);
Jason Molendaddf91772013-05-14 04:50:47 +0000554 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000555 break;
556
557 case FPURegSet:
558 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000559 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0];
560 const int fpu_reg_buf_size = sizeof (fpu.floats);
561 if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000562 {
Jason Molenda663d2e12013-05-14 03:52:22 +0000563 offset += fpu_reg_buf_size;
564 fpu.fpscr = data.GetU32(&offset);
565 SetError (FPURegSet, Read, 0);
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000566 }
Jason Molenda663d2e12013-05-14 03:52:22 +0000567 else
568 {
569 done = true;
570 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000571 }
Jason Molendaddf91772013-05-14 04:50:47 +0000572 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000573 break;
574
575 case EXCRegSet:
Jason Molendaddf91772013-05-14 04:50:47 +0000576 if (count == 3)
577 {
578 exc.exception = data.GetU32(&offset);
579 exc.fsr = data.GetU32(&offset);
580 exc.far = data.GetU32(&offset);
581 SetError (EXCRegSet, Read, 0);
582 }
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000583 done = true;
Jason Molendaddf91772013-05-14 04:50:47 +0000584 offset = next_thread_state;
Jason Molenda2e7236fa2013-05-14 03:25:58 +0000585 break;
586
587 // Unknown register set flavor, stop trying to parse.
588 default:
589 done = true;
590 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000591 }
592 }
Jason Molenda22952582014-11-12 01:11:36 +0000593
594 static size_t
595 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
596 {
597 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
598 if (reg_info == NULL)
599 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
600 if (reg_info)
601 {
602 lldb_private::RegisterValue reg_value;
603 if (reg_ctx->ReadRegister(reg_info, reg_value))
604 {
605 if (reg_info->byte_size >= reg_byte_size)
606 data.Write(reg_value.GetBytes(), reg_byte_size);
607 else
608 {
609 data.Write(reg_value.GetBytes(), reg_info->byte_size);
610 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
611 data.PutChar(0);
612 }
613 return reg_byte_size;
614 }
615 }
616 // Just write zeros if all else fails
617 for (size_t i=0; i<reg_byte_size; ++ i)
618 data.PutChar(0);
619 return reg_byte_size;
620 }
621
622 static bool
623 Create_LC_THREAD (Thread *thread, Stream &data)
624 {
625 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
626 if (reg_ctx_sp)
627 {
628 RegisterContext *reg_ctx = reg_ctx_sp.get();
629
630 data.PutHex32 (GPRRegSet); // Flavor
631 data.PutHex32 (GPRWordCount);
632 WriteRegister (reg_ctx, "r0", NULL, 4, data);
633 WriteRegister (reg_ctx, "r1", NULL, 4, data);
634 WriteRegister (reg_ctx, "r2", NULL, 4, data);
635 WriteRegister (reg_ctx, "r3", NULL, 4, data);
636 WriteRegister (reg_ctx, "r4", NULL, 4, data);
637 WriteRegister (reg_ctx, "r5", NULL, 4, data);
638 WriteRegister (reg_ctx, "r6", NULL, 4, data);
639 WriteRegister (reg_ctx, "r7", NULL, 4, data);
640 WriteRegister (reg_ctx, "r8", NULL, 4, data);
641 WriteRegister (reg_ctx, "r9", NULL, 4, data);
642 WriteRegister (reg_ctx, "r10", NULL, 4, data);
643 WriteRegister (reg_ctx, "r11", NULL, 4, data);
644 WriteRegister (reg_ctx, "r12", NULL, 4, data);
645 WriteRegister (reg_ctx, "sp", NULL, 4, data);
646 WriteRegister (reg_ctx, "lr", NULL, 4, data);
647 WriteRegister (reg_ctx, "pc", NULL, 4, data);
648 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
649
650 // Write out the EXC registers
651// data.PutHex32 (EXCRegSet);
652// data.PutHex32 (EXCWordCount);
653// WriteRegister (reg_ctx, "exception", NULL, 4, data);
654// WriteRegister (reg_ctx, "fsr", NULL, 4, data);
655// WriteRegister (reg_ctx, "far", NULL, 4, data);
656 return true;
657 }
658 return false;
659 }
660
Greg Claytonc859e2d2012-02-13 23:10:39 +0000661protected:
Eugene Zelenko8157a882015-10-23 16:56:07 +0000662 int
663 DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000664 {
Jason Molendaddf91772013-05-14 04:50:47 +0000665 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000666 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000667
Eugene Zelenko8157a882015-10-23 16:56:07 +0000668 int
669 DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000670 {
Jason Molendaddf91772013-05-14 04:50:47 +0000671 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000672 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000673
Eugene Zelenko8157a882015-10-23 16:56:07 +0000674 int
675 DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000676 {
Jason Molendaddf91772013-05-14 04:50:47 +0000677 return -1;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000678 }
Greg Claytonc2807462012-10-30 23:57:32 +0000679
Eugene Zelenko8157a882015-10-23 16:56:07 +0000680 int
681 DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
Greg Claytonc2807462012-10-30 23:57:32 +0000682 {
683 return -1;
684 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000685
Eugene Zelenko8157a882015-10-23 16:56:07 +0000686 int
687 DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000688 {
689 return 0;
690 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000691
Eugene Zelenko8157a882015-10-23 16:56:07 +0000692 int
693 DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000694 {
695 return 0;
696 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000697
Eugene Zelenko8157a882015-10-23 16:56:07 +0000698 int
699 DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
Greg Claytonc859e2d2012-02-13 23:10:39 +0000700 {
701 return 0;
702 }
Jason Molenda4e7511e2013-03-06 23:19:17 +0000703
Eugene Zelenko8157a882015-10-23 16:56:07 +0000704 int
705 DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
Greg Claytonc2807462012-10-30 23:57:32 +0000706 {
707 return -1;
708 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000709};
710
Jason Molendaa3329782014-03-29 18:54:20 +0000711class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
712{
713public:
714 RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
715 RegisterContextDarwin_arm64 (thread, 0)
716 {
717 SetRegisterDataFrom_LC_THREAD (data);
718 }
719
Eugene Zelenko8157a882015-10-23 16:56:07 +0000720 void
721 InvalidateAllRegisters() override
Jason Molendaa3329782014-03-29 18:54:20 +0000722 {
723 // Do nothing... registers are always valid...
724 }
725
726 void
727 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
728 {
729 lldb::offset_t offset = 0;
730 SetError (GPRRegSet, Read, -1);
731 SetError (FPURegSet, Read, -1);
732 SetError (EXCRegSet, Read, -1);
733 bool done = false;
734 while (!done)
735 {
736 int flavor = data.GetU32 (&offset);
737 uint32_t count = data.GetU32 (&offset);
738 lldb::offset_t next_thread_state = offset + (count * 4);
739 switch (flavor)
740 {
741 case GPRRegSet:
742 // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
743 if (count >= (33 * 2) + 1)
744 {
745 for (uint32_t i=0; i<33; ++i)
746 gpr.x[i] = data.GetU64(&offset);
747 gpr.cpsr = data.GetU32(&offset);
748 SetError (GPRRegSet, Read, 0);
749 }
750 offset = next_thread_state;
751 break;
752 case FPURegSet:
753 {
754 uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
755 const int fpu_reg_buf_size = sizeof (fpu);
756 if (fpu_reg_buf_size == count
757 && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
758 {
759 SetError (FPURegSet, Read, 0);
760 }
761 else
762 {
763 done = true;
764 }
765 }
766 offset = next_thread_state;
767 break;
768 case EXCRegSet:
769 if (count == 4)
770 {
771 exc.far = data.GetU64(&offset);
772 exc.esr = data.GetU32(&offset);
773 exc.exception = data.GetU32(&offset);
774 SetError (EXCRegSet, Read, 0);
775 }
776 offset = next_thread_state;
777 break;
778 default:
779 done = true;
780 break;
781 }
782 }
783 }
Jason Molenda22952582014-11-12 01:11:36 +0000784
785 static size_t
786 WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
787 {
788 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
789 if (reg_info == NULL)
790 reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
791 if (reg_info)
792 {
793 lldb_private::RegisterValue reg_value;
794 if (reg_ctx->ReadRegister(reg_info, reg_value))
795 {
796 if (reg_info->byte_size >= reg_byte_size)
797 data.Write(reg_value.GetBytes(), reg_byte_size);
798 else
799 {
800 data.Write(reg_value.GetBytes(), reg_info->byte_size);
801 for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
802 data.PutChar(0);
803 }
804 return reg_byte_size;
805 }
806 }
807 // Just write zeros if all else fails
808 for (size_t i=0; i<reg_byte_size; ++ i)
809 data.PutChar(0);
810 return reg_byte_size;
811 }
812
813 static bool
814 Create_LC_THREAD (Thread *thread, Stream &data)
815 {
816 RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
817 if (reg_ctx_sp)
818 {
819 RegisterContext *reg_ctx = reg_ctx_sp.get();
820
821 data.PutHex32 (GPRRegSet); // Flavor
822 data.PutHex32 (GPRWordCount);
823 WriteRegister (reg_ctx, "x0", NULL, 8, data);
824 WriteRegister (reg_ctx, "x1", NULL, 8, data);
825 WriteRegister (reg_ctx, "x2", NULL, 8, data);
826 WriteRegister (reg_ctx, "x3", NULL, 8, data);
827 WriteRegister (reg_ctx, "x4", NULL, 8, data);
828 WriteRegister (reg_ctx, "x5", NULL, 8, data);
829 WriteRegister (reg_ctx, "x6", NULL, 8, data);
830 WriteRegister (reg_ctx, "x7", NULL, 8, data);
831 WriteRegister (reg_ctx, "x8", NULL, 8, data);
832 WriteRegister (reg_ctx, "x9", NULL, 8, data);
833 WriteRegister (reg_ctx, "x10", NULL, 8, data);
834 WriteRegister (reg_ctx, "x11", NULL, 8, data);
835 WriteRegister (reg_ctx, "x12", NULL, 8, data);
836 WriteRegister (reg_ctx, "x13", NULL, 8, data);
837 WriteRegister (reg_ctx, "x14", NULL, 8, data);
838 WriteRegister (reg_ctx, "x15", NULL, 8, data);
839 WriteRegister (reg_ctx, "x16", NULL, 8, data);
840 WriteRegister (reg_ctx, "x17", NULL, 8, data);
841 WriteRegister (reg_ctx, "x18", NULL, 8, data);
842 WriteRegister (reg_ctx, "x19", NULL, 8, data);
843 WriteRegister (reg_ctx, "x20", NULL, 8, data);
844 WriteRegister (reg_ctx, "x21", NULL, 8, data);
845 WriteRegister (reg_ctx, "x22", NULL, 8, data);
846 WriteRegister (reg_ctx, "x23", NULL, 8, data);
847 WriteRegister (reg_ctx, "x24", NULL, 8, data);
848 WriteRegister (reg_ctx, "x25", NULL, 8, data);
849 WriteRegister (reg_ctx, "x26", NULL, 8, data);
850 WriteRegister (reg_ctx, "x27", NULL, 8, data);
851 WriteRegister (reg_ctx, "x28", NULL, 8, data);
852 WriteRegister (reg_ctx, "fp", NULL, 8, data);
853 WriteRegister (reg_ctx, "lr", NULL, 8, data);
854 WriteRegister (reg_ctx, "sp", NULL, 8, data);
855 WriteRegister (reg_ctx, "pc", NULL, 8, data);
856 WriteRegister (reg_ctx, "cpsr", NULL, 4, data);
857
858 // Write out the EXC registers
859// data.PutHex32 (EXCRegSet);
860// data.PutHex32 (EXCWordCount);
861// WriteRegister (reg_ctx, "far", NULL, 8, data);
862// WriteRegister (reg_ctx, "esr", NULL, 4, data);
863// WriteRegister (reg_ctx, "exception", NULL, 4, data);
864 return true;
865 }
866 return false;
867 }
868
Jason Molendaa3329782014-03-29 18:54:20 +0000869protected:
Eugene Zelenko8157a882015-10-23 16:56:07 +0000870 int
871 DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
Jason Molendaa3329782014-03-29 18:54:20 +0000872 {
873 return -1;
874 }
875
Eugene Zelenko8157a882015-10-23 16:56:07 +0000876 int
877 DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
Jason Molendaa3329782014-03-29 18:54:20 +0000878 {
879 return -1;
880 }
881
Eugene Zelenko8157a882015-10-23 16:56:07 +0000882 int
883 DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
Jason Molendaa3329782014-03-29 18:54:20 +0000884 {
885 return -1;
886 }
887
Eugene Zelenko8157a882015-10-23 16:56:07 +0000888 int
889 DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
Jason Molendaa3329782014-03-29 18:54:20 +0000890 {
891 return -1;
892 }
893
Eugene Zelenko8157a882015-10-23 16:56:07 +0000894 int
895 DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
Jason Molendaa3329782014-03-29 18:54:20 +0000896 {
897 return 0;
898 }
899
Eugene Zelenko8157a882015-10-23 16:56:07 +0000900 int
901 DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
Jason Molendaa3329782014-03-29 18:54:20 +0000902 {
903 return 0;
904 }
905
Eugene Zelenko8157a882015-10-23 16:56:07 +0000906 int
907 DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
Jason Molendaa3329782014-03-29 18:54:20 +0000908 {
909 return 0;
910 }
911
Eugene Zelenko8157a882015-10-23 16:56:07 +0000912 int
913 DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
Jason Molendaa3329782014-03-29 18:54:20 +0000914 {
915 return -1;
916 }
917};
918
Greg Clayton9aae0a12013-05-15 19:52:08 +0000919static uint32_t
920MachHeaderSizeFromMagic(uint32_t magic)
921{
922 switch (magic)
923 {
Charles Davis510938e2013-08-27 05:04:57 +0000924 case MH_MAGIC:
925 case MH_CIGAM:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000926 return sizeof(struct mach_header);
927
Charles Davis510938e2013-08-27 05:04:57 +0000928 case MH_MAGIC_64:
929 case MH_CIGAM_64:
Greg Clayton9aae0a12013-05-15 19:52:08 +0000930 return sizeof(struct mach_header_64);
931 break;
932
933 default:
934 break;
935 }
936 return 0;
937}
938
Greg Claytonded470d2011-03-19 01:12:21 +0000939#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000940
941void
942ObjectFileMachO::Initialize()
943{
944 PluginManager::RegisterPlugin (GetPluginNameStatic(),
945 GetPluginDescriptionStatic(),
Greg Claytonc9660542012-02-05 02:38:54 +0000946 CreateInstance,
Greg Claytonf4d6de62013-04-24 22:29:28 +0000947 CreateMemoryInstance,
Greg Claytona2715cf2014-06-13 00:54:12 +0000948 GetModuleSpecifications,
949 SaveCore);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950}
951
952void
953ObjectFileMachO::Terminate()
954{
955 PluginManager::UnregisterPlugin (CreateInstance);
956}
957
Greg Clayton57abc5d2013-05-10 21:47:16 +0000958lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000959ObjectFileMachO::GetPluginNameStatic()
960{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000961 static ConstString g_name("mach-o");
962 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000963}
964
965const char *
966ObjectFileMachO::GetPluginDescriptionStatic()
967{
968 return "Mach-o object file reader (32 and 64 bit)";
969}
970
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000971ObjectFile *
Greg Clayton5ce9c562013-02-06 17:22:03 +0000972ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
973 DataBufferSP& data_sp,
974 lldb::offset_t data_offset,
975 const FileSpec* file,
976 lldb::offset_t file_offset,
977 lldb::offset_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000978{
Greg Clayton5ce9c562013-02-06 17:22:03 +0000979 if (!data_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000980 {
Greg Clayton736888c2015-02-23 23:47:09 +0000981 data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
Greg Clayton5ce9c562013-02-06 17:22:03 +0000982 data_offset = 0;
983 }
984
985 if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
986 {
987 // Update the data to contain the entire file if it doesn't already
988 if (data_sp->GetByteSize() < length)
989 {
Greg Clayton736888c2015-02-23 23:47:09 +0000990 data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length);
Greg Clayton5ce9c562013-02-06 17:22:03 +0000991 data_offset = 0;
992 }
Greg Clayton7b0992d2013-04-18 22:45:39 +0000993 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 +0000994 if (objfile_ap.get() && objfile_ap->ParseHeader())
995 return objfile_ap.release();
996 }
997 return NULL;
998}
999
Greg Claytonc9660542012-02-05 02:38:54 +00001000ObjectFile *
Jason Molenda4e7511e2013-03-06 23:19:17 +00001001ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
1002 DataBufferSP& data_sp,
1003 const ProcessSP &process_sp,
Greg Claytonc9660542012-02-05 02:38:54 +00001004 lldb::addr_t header_addr)
1005{
1006 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
1007 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001008 std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonc9660542012-02-05 02:38:54 +00001009 if (objfile_ap.get() && objfile_ap->ParseHeader())
1010 return objfile_ap.release();
1011 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001012 return NULL;
Greg Claytonc9660542012-02-05 02:38:54 +00001013}
1014
Greg Claytonf4d6de62013-04-24 22:29:28 +00001015size_t
1016ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
1017 lldb::DataBufferSP& data_sp,
1018 lldb::offset_t data_offset,
1019 lldb::offset_t file_offset,
1020 lldb::offset_t length,
1021 lldb_private::ModuleSpecList &specs)
1022{
1023 const size_t initial_count = specs.GetSize();
1024
1025 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
1026 {
1027 DataExtractor data;
1028 data.SetData(data_sp);
1029 llvm::MachO::mach_header header;
1030 if (ParseHeader (data, &data_offset, header))
1031 {
Jason Molenda48cd3332014-04-22 04:52:30 +00001032 size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
1033 if (header_and_load_cmds >= data_sp->GetByteSize())
Greg Claytonf4d6de62013-04-24 22:29:28 +00001034 {
Jason Molenda48cd3332014-04-22 04:52:30 +00001035 data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);
Greg Clayton2540a8a2013-07-12 22:07:46 +00001036 data.SetData(data_sp);
1037 data_offset = MachHeaderSizeFromMagic(header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +00001038 }
1039 if (data_sp)
1040 {
1041 ModuleSpec spec;
1042 spec.GetFileSpec() = file;
Greg Clayton7ab7f892014-05-29 21:33:45 +00001043 spec.SetObjectOffset(file_offset);
Oleksiy Vyalov63acdfd2015-03-10 01:15:28 +00001044 spec.SetObjectSize(length);
1045
Greg Clayton7ab7f892014-05-29 21:33:45 +00001046 if (GetArchitecture (header, data, data_offset, spec.GetArchitecture()))
Jason Molendab000e4d2013-08-27 02:22:06 +00001047 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001048 if (spec.GetArchitecture().IsValid())
1049 {
1050 GetUUID (header, data, data_offset, spec.GetUUID());
1051 specs.Append(spec);
1052 }
Greg Claytonf4d6de62013-04-24 22:29:28 +00001053 }
1054 }
1055 }
1056 }
1057 return specs.GetSize() - initial_count;
1058}
1059
Greg Claytonc9660542012-02-05 02:38:54 +00001060const ConstString &
1061ObjectFileMachO::GetSegmentNameTEXT()
1062{
1063 static ConstString g_segment_name_TEXT ("__TEXT");
1064 return g_segment_name_TEXT;
1065}
1066
1067const ConstString &
1068ObjectFileMachO::GetSegmentNameDATA()
1069{
1070 static ConstString g_segment_name_DATA ("__DATA");
1071 return g_segment_name_DATA;
1072}
1073
1074const ConstString &
Greg Claytona381e102015-07-27 23:21:05 +00001075ObjectFileMachO::GetSegmentNameDATA_DIRTY()
1076{
1077 static ConstString g_segment_name ("__DATA_DIRTY");
1078 return g_segment_name;
1079}
1080
1081const ConstString &
1082ObjectFileMachO::GetSegmentNameDATA_CONST()
1083{
1084 static ConstString g_segment_name ("__DATA_CONST");
1085 return g_segment_name;
1086}
1087
1088const ConstString &
Greg Claytonc9660542012-02-05 02:38:54 +00001089ObjectFileMachO::GetSegmentNameOBJC()
1090{
1091 static ConstString g_segment_name_OBJC ("__OBJC");
1092 return g_segment_name_OBJC;
1093}
1094
1095const ConstString &
1096ObjectFileMachO::GetSegmentNameLINKEDIT()
1097{
1098 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
1099 return g_section_name_LINKEDIT;
1100}
1101
1102const ConstString &
1103ObjectFileMachO::GetSectionNameEHFrame()
1104{
1105 static ConstString g_section_name_eh_frame ("__eh_frame");
1106 return g_section_name_eh_frame;
1107}
1108
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001109bool
Jason Molenda4e7511e2013-03-06 23:19:17 +00001110ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
1111 lldb::addr_t data_offset,
Greg Clayton44435ed2012-01-12 05:25:17 +00001112 lldb::addr_t data_length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001113{
Greg Clayton44435ed2012-01-12 05:25:17 +00001114 DataExtractor data;
1115 data.SetData (data_sp, data_offset, data_length);
Greg Claytonc7bece562013-01-25 18:06:21 +00001116 lldb::offset_t offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 uint32_t magic = data.GetU32(&offset);
1118 return MachHeaderSizeFromMagic(magic) != 0;
1119}
1120
Greg Clayton5ce9c562013-02-06 17:22:03 +00001121ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
1122 DataBufferSP& data_sp,
1123 lldb::offset_t data_offset,
1124 const FileSpec* file,
1125 lldb::offset_t file_offset,
1126 lldb::offset_t length) :
1127 ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001128 m_mach_segments(),
1129 m_mach_sections(),
1130 m_entry_point_address(),
1131 m_thread_context_offsets(),
1132 m_thread_context_offsets_valid(false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133{
Greg Clayton72b77eb2011-02-04 21:13:05 +00001134 ::memset (&m_header, 0, sizeof(m_header));
1135 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136}
1137
Greg Claytone72dfb32012-02-24 01:59:29 +00001138ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonc9660542012-02-05 02:38:54 +00001139 lldb::DataBufferSP& header_data_sp,
1140 const lldb::ProcessSP &process_sp,
1141 lldb::addr_t header_addr) :
Greg Claytone72dfb32012-02-24 01:59:29 +00001142 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonc3776bf2012-02-09 06:16:32 +00001143 m_mach_segments(),
1144 m_mach_sections(),
1145 m_entry_point_address(),
1146 m_thread_context_offsets(),
1147 m_thread_context_offsets_valid(false)
Greg Claytonc9660542012-02-05 02:38:54 +00001148{
1149 ::memset (&m_header, 0, sizeof(m_header));
1150 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1151}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152
Greg Claytonf4d6de62013-04-24 22:29:28 +00001153bool
1154ObjectFileMachO::ParseHeader (DataExtractor &data,
1155 lldb::offset_t *data_offset_ptr,
1156 llvm::MachO::mach_header &header)
1157{
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001158 data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytonf4d6de62013-04-24 22:29:28 +00001159 // Leave magic in the original byte order
1160 header.magic = data.GetU32(data_offset_ptr);
1161 bool can_parse = false;
1162 bool is_64_bit = false;
1163 switch (header.magic)
1164 {
Charles Davis510938e2013-08-27 05:04:57 +00001165 case MH_MAGIC:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001166 data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytonf4d6de62013-04-24 22:29:28 +00001167 data.SetAddressByteSize(4);
1168 can_parse = true;
1169 break;
1170
Charles Davis510938e2013-08-27 05:04:57 +00001171 case MH_MAGIC_64:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001172 data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytonf4d6de62013-04-24 22:29:28 +00001173 data.SetAddressByteSize(8);
1174 can_parse = true;
1175 is_64_bit = true;
1176 break;
1177
Charles Davis510938e2013-08-27 05:04:57 +00001178 case MH_CIGAM:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001179 data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Greg Claytonf4d6de62013-04-24 22:29:28 +00001180 data.SetAddressByteSize(4);
1181 can_parse = true;
1182 break;
1183
Charles Davis510938e2013-08-27 05:04:57 +00001184 case MH_CIGAM_64:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001185 data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Greg Claytonf4d6de62013-04-24 22:29:28 +00001186 data.SetAddressByteSize(8);
1187 is_64_bit = true;
1188 can_parse = true;
1189 break;
1190
1191 default:
1192 break;
1193 }
1194
1195 if (can_parse)
1196 {
1197 data.GetU32(data_offset_ptr, &header.cputype, 6);
1198 if (is_64_bit)
1199 *data_offset_ptr += 4;
1200 return true;
1201 }
1202 else
1203 {
1204 memset(&header, 0, sizeof(header));
1205 }
1206 return false;
1207}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001208
1209bool
1210ObjectFileMachO::ParseHeader ()
1211{
Greg Claytona1743492012-03-13 23:14:29 +00001212 ModuleSP module_sp(GetModule());
1213 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001214 {
Greg Claytona1743492012-03-13 23:14:29 +00001215 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1216 bool can_parse = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00001217 lldb::offset_t offset = 0;
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001218 m_data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001219 // Leave magic in the original byte order
1220 m_header.magic = m_data.GetU32(&offset);
1221 switch (m_header.magic)
Greg Claytonc9660542012-02-05 02:38:54 +00001222 {
Charles Davis510938e2013-08-27 05:04:57 +00001223 case MH_MAGIC:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001224 m_data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001225 m_data.SetAddressByteSize(4);
1226 can_parse = true;
1227 break;
1228
Charles Davis510938e2013-08-27 05:04:57 +00001229 case MH_MAGIC_64:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001230 m_data.SetByteOrder (endian::InlHostByteOrder());
Greg Claytona1743492012-03-13 23:14:29 +00001231 m_data.SetAddressByteSize(8);
1232 can_parse = true;
1233 break;
1234
Charles Davis510938e2013-08-27 05:04:57 +00001235 case MH_CIGAM:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001236 m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Greg Claytona1743492012-03-13 23:14:29 +00001237 m_data.SetAddressByteSize(4);
1238 can_parse = true;
1239 break;
1240
Charles Davis510938e2013-08-27 05:04:57 +00001241 case MH_CIGAM_64:
Bruce Mitchener9ccb9702015-11-07 04:40:13 +00001242 m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Greg Claytona1743492012-03-13 23:14:29 +00001243 m_data.SetAddressByteSize(8);
1244 can_parse = true;
1245 break;
1246
1247 default:
1248 break;
Greg Claytonc9660542012-02-05 02:38:54 +00001249 }
Greg Claytona1743492012-03-13 23:14:29 +00001250
1251 if (can_parse)
1252 {
1253 m_data.GetU32(&offset, &m_header.cputype, 6);
1254
Greg Clayton7ab7f892014-05-29 21:33:45 +00001255
1256 ArchSpec mach_arch;
1257
1258 if (GetArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001259 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001260 // Check if the module has a required architecture
1261 const ArchSpec &module_arch = module_sp->GetArchitecture();
1262 if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
1263 return false;
1264
1265 if (SetModulesArchitecture (mach_arch))
Greg Claytona1743492012-03-13 23:14:29 +00001266 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001267 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
1268 if (m_data.GetByteSize() < header_and_lc_size)
Greg Claytona1743492012-03-13 23:14:29 +00001269 {
Greg Clayton7ab7f892014-05-29 21:33:45 +00001270 DataBufferSP data_sp;
1271 ProcessSP process_sp (m_process_wp.lock());
1272 if (process_sp)
1273 {
1274 data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
1275 }
1276 else
1277 {
1278 // Read in all only the load command data from the file on disk
1279 data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
1280 if (data_sp->GetByteSize() != header_and_lc_size)
1281 return false;
1282 }
1283 if (data_sp)
1284 m_data.SetData (data_sp);
Greg Claytona1743492012-03-13 23:14:29 +00001285 }
Greg Claytona1743492012-03-13 23:14:29 +00001286 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00001287 return true;
Greg Claytona1743492012-03-13 23:14:29 +00001288 }
Greg Claytona1743492012-03-13 23:14:29 +00001289 }
1290 else
1291 {
1292 memset(&m_header, 0, sizeof(struct mach_header));
1293 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294 }
1295 return false;
1296}
1297
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001298ByteOrder
1299ObjectFileMachO::GetByteOrder () const
1300{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001301 return m_data.GetByteOrder ();
1302}
1303
Jim Ingham5aee1622010-08-09 23:31:02 +00001304bool
1305ObjectFileMachO::IsExecutable() const
1306{
Charles Davis510938e2013-08-27 05:04:57 +00001307 return m_header.filetype == MH_EXECUTE;
Jim Ingham5aee1622010-08-09 23:31:02 +00001308}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001309
Greg Claytonc7bece562013-01-25 18:06:21 +00001310uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001311ObjectFileMachO::GetAddressByteSize () const
1312{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001313 return m_data.GetAddressByteSize ();
1314}
1315
Greg Claytone0d378b2011-03-24 21:19:54 +00001316AddressClass
Greg Claytonded470d2011-03-19 01:12:21 +00001317ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
1318{
1319 Symtab *symtab = GetSymtab();
1320 if (symtab)
1321 {
1322 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
1323 if (symbol)
1324 {
Greg Claytone7612132012-03-07 21:03:09 +00001325 if (symbol->ValueIsAddress())
Greg Claytonded470d2011-03-19 01:12:21 +00001326 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00001327 SectionSP section_sp (symbol->GetAddressRef().GetSection());
Greg Claytone72dfb32012-02-24 01:59:29 +00001328 if (section_sp)
Greg Claytonded470d2011-03-19 01:12:21 +00001329 {
Charles Davis510938e2013-08-27 05:04:57 +00001330 const lldb::SectionType section_type = section_sp->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001331 switch (section_type)
1332 {
Jason Molendae589e7e2014-12-08 03:09:00 +00001333 case eSectionTypeInvalid:
1334 return eAddressClassUnknown;
1335
Greg Claytonded470d2011-03-19 01:12:21 +00001336 case eSectionTypeCode:
Charles Davis510938e2013-08-27 05:04:57 +00001337 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001338 {
1339 // For ARM we have a bit in the n_desc field of the symbol
1340 // that tells us ARM/Thumb which is bit 0x0008.
1341 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1342 return eAddressClassCodeAlternateISA;
1343 }
1344 return eAddressClassCode;
1345
Jason Molendae589e7e2014-12-08 03:09:00 +00001346 case eSectionTypeContainer:
1347 return eAddressClassUnknown;
1348
Greg Clayton5009f9d2011-10-27 17:55:14 +00001349 case eSectionTypeData:
1350 case eSectionTypeDataCString:
1351 case eSectionTypeDataCStringPointers:
1352 case eSectionTypeDataSymbolAddress:
1353 case eSectionTypeData4:
1354 case eSectionTypeData8:
1355 case eSectionTypeData16:
1356 case eSectionTypeDataPointers:
1357 case eSectionTypeZeroFill:
1358 case eSectionTypeDataObjCMessageRefs:
1359 case eSectionTypeDataObjCCFStrings:
Ryan Brown65d4d5c2015-09-16 21:20:44 +00001360 case eSectionTypeGoSymtab:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001361 return eAddressClassData;
Jason Molendae589e7e2014-12-08 03:09:00 +00001362
Greg Clayton5009f9d2011-10-27 17:55:14 +00001363 case eSectionTypeDebug:
1364 case eSectionTypeDWARFDebugAbbrev:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001365 case eSectionTypeDWARFDebugAddr:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001366 case eSectionTypeDWARFDebugAranges:
1367 case eSectionTypeDWARFDebugFrame:
1368 case eSectionTypeDWARFDebugInfo:
1369 case eSectionTypeDWARFDebugLine:
1370 case eSectionTypeDWARFDebugLoc:
1371 case eSectionTypeDWARFDebugMacInfo:
1372 case eSectionTypeDWARFDebugPubNames:
1373 case eSectionTypeDWARFDebugPubTypes:
1374 case eSectionTypeDWARFDebugRanges:
1375 case eSectionTypeDWARFDebugStr:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001376 case eSectionTypeDWARFDebugStrOffsets:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001377 case eSectionTypeDWARFAppleNames:
1378 case eSectionTypeDWARFAppleTypes:
1379 case eSectionTypeDWARFAppleNamespaces:
1380 case eSectionTypeDWARFAppleObjC:
1381 return eAddressClassDebug;
Jason Molendae589e7e2014-12-08 03:09:00 +00001382
1383 case eSectionTypeEHFrame:
Tamas Berghammer648f3c72015-09-30 13:50:14 +00001384 case eSectionTypeARMexidx:
1385 case eSectionTypeARMextab:
Jason Molendae589e7e2014-12-08 03:09:00 +00001386 case eSectionTypeCompactUnwind:
1387 return eAddressClassRuntime;
1388
Michael Sartaina7499c92013-07-01 19:45:50 +00001389 case eSectionTypeELFSymbolTable:
1390 case eSectionTypeELFDynamicSymbols:
1391 case eSectionTypeELFRelocationEntries:
1392 case eSectionTypeELFDynamicLinkInfo:
Jason Molendae589e7e2014-12-08 03:09:00 +00001393 case eSectionTypeOther:
1394 return eAddressClassUnknown;
Greg Claytonded470d2011-03-19 01:12:21 +00001395 }
1396 }
1397 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00001398
Greg Claytone0d378b2011-03-24 21:19:54 +00001399 const SymbolType symbol_type = symbol->GetType();
Greg Claytonded470d2011-03-19 01:12:21 +00001400 switch (symbol_type)
1401 {
1402 case eSymbolTypeAny: return eAddressClassUnknown;
1403 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Jason Molenda4e7511e2013-03-06 23:19:17 +00001404
Greg Claytonded470d2011-03-19 01:12:21 +00001405 case eSymbolTypeCode:
1406 case eSymbolTypeTrampoline:
Greg Clayton059f7242013-02-27 21:16:04 +00001407 case eSymbolTypeResolver:
Charles Davis510938e2013-08-27 05:04:57 +00001408 if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
Greg Claytonded470d2011-03-19 01:12:21 +00001409 {
1410 // For ARM we have a bit in the n_desc field of the symbol
1411 // that tells us ARM/Thumb which is bit 0x0008.
1412 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
1413 return eAddressClassCodeAlternateISA;
1414 }
1415 return eAddressClassCode;
1416
1417 case eSymbolTypeData: return eAddressClassData;
1418 case eSymbolTypeRuntime: return eAddressClassRuntime;
1419 case eSymbolTypeException: return eAddressClassRuntime;
1420 case eSymbolTypeSourceFile: return eAddressClassDebug;
1421 case eSymbolTypeHeaderFile: return eAddressClassDebug;
1422 case eSymbolTypeObjectFile: return eAddressClassDebug;
1423 case eSymbolTypeCommonBlock: return eAddressClassDebug;
1424 case eSymbolTypeBlock: return eAddressClassDebug;
1425 case eSymbolTypeLocal: return eAddressClassData;
1426 case eSymbolTypeParam: return eAddressClassData;
1427 case eSymbolTypeVariable: return eAddressClassData;
1428 case eSymbolTypeVariableType: return eAddressClassDebug;
1429 case eSymbolTypeLineEntry: return eAddressClassDebug;
1430 case eSymbolTypeLineHeader: return eAddressClassDebug;
1431 case eSymbolTypeScopeBegin: return eAddressClassDebug;
1432 case eSymbolTypeScopeEnd: return eAddressClassDebug;
1433 case eSymbolTypeAdditional: return eAddressClassUnknown;
1434 case eSymbolTypeCompiler: return eAddressClassDebug;
1435 case eSymbolTypeInstrumentation:return eAddressClassDebug;
1436 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton456809c2011-12-03 02:30:59 +00001437 case eSymbolTypeObjCClass: return eAddressClassRuntime;
1438 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
1439 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Clayton9191db42013-10-21 18:40:51 +00001440 case eSymbolTypeReExported: return eAddressClassRuntime;
Greg Claytonded470d2011-03-19 01:12:21 +00001441 }
1442 }
1443 }
1444 return eAddressClassUnknown;
1445}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001446
1447Symtab *
Greg Clayton3046e662013-07-10 01:23:25 +00001448ObjectFileMachO::GetSymtab()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001449{
Greg Claytona1743492012-03-13 23:14:29 +00001450 ModuleSP module_sp(GetModule());
1451 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001452 {
Greg Claytona1743492012-03-13 23:14:29 +00001453 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
1454 if (m_symtab_ap.get() == NULL)
1455 {
1456 m_symtab_ap.reset(new Symtab(this));
1457 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
Greg Clayton3046e662013-07-10 01:23:25 +00001458 ParseSymtab ();
Greg Claytona1743492012-03-13 23:14:29 +00001459 m_symtab_ap->Finalize ();
1460 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001461 }
1462 return m_symtab_ap.get();
1463}
1464
Greg Clayton3046e662013-07-10 01:23:25 +00001465bool
1466ObjectFileMachO::IsStripped ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001467{
Greg Clayton3046e662013-07-10 01:23:25 +00001468 if (m_dysymtab.cmd == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001469 {
Greg Clayton3046e662013-07-10 01:23:25 +00001470 ModuleSP module_sp(GetModule());
1471 if (module_sp)
Greg Claytona1743492012-03-13 23:14:29 +00001472 {
Greg Clayton3046e662013-07-10 01:23:25 +00001473 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1474 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton4d78c402012-05-25 18:09:55 +00001475 {
Greg Clayton3046e662013-07-10 01:23:25 +00001476 const lldb::offset_t load_cmd_offset = offset;
1477
1478 load_command lc;
1479 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
1480 break;
Charles Davis510938e2013-08-27 05:04:57 +00001481 if (lc.cmd == LC_DYSYMTAB)
Greg Clayton4d78c402012-05-25 18:09:55 +00001482 {
Greg Clayton3046e662013-07-10 01:23:25 +00001483 m_dysymtab.cmd = lc.cmd;
1484 m_dysymtab.cmdsize = lc.cmdsize;
1485 if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
1486 {
1487 // Clear m_dysymtab if we were unable to read all items from the load command
1488 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
1489 }
Greg Clayton4d78c402012-05-25 18:09:55 +00001490 }
Greg Clayton3046e662013-07-10 01:23:25 +00001491 offset = load_cmd_offset + lc.cmdsize;
Greg Clayton4d78c402012-05-25 18:09:55 +00001492 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001493 }
Greg Clayton1eac0c72012-04-24 03:06:13 +00001494 }
Greg Clayton3046e662013-07-10 01:23:25 +00001495 if (m_dysymtab.cmd)
Greg Clayton93e28612013-10-11 22:03:48 +00001496 return m_dysymtab.nlocalsym <= 1;
Greg Clayton3046e662013-07-10 01:23:25 +00001497 return false;
1498}
Greg Clayton1eac0c72012-04-24 03:06:13 +00001499
Greg Clayton3046e662013-07-10 01:23:25 +00001500void
1501ObjectFileMachO::CreateSections (SectionList &unified_section_list)
1502{
1503 if (!m_sections_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001504 {
Greg Clayton3046e662013-07-10 01:23:25 +00001505 m_sections_ap.reset(new SectionList());
1506
Charles Davis510938e2013-08-27 05:04:57 +00001507 const bool is_dsym = (m_header.filetype == MH_DSYM);
Greg Clayton3046e662013-07-10 01:23:25 +00001508 lldb::user_id_t segID = 0;
1509 lldb::user_id_t sectID = 0;
1510 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
1511 uint32_t i;
1512 const bool is_core = GetType() == eTypeCoreFile;
1513 //bool dump_sections = false;
1514 ModuleSP module_sp (GetModule());
1515 // First look up any LC_ENCRYPTION_INFO load commands
1516 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
1517 EncryptedFileRanges encrypted_file_ranges;
1518 encryption_info_command encryption_cmd;
1519 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001520 {
Greg Clayton3046e662013-07-10 01:23:25 +00001521 const lldb::offset_t load_cmd_offset = offset;
1522 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
1523 break;
1524
Jason Molendadfb02a92015-04-02 05:19:33 +00001525 // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
1526 // the 3 fields we care about, so treat them the same.
1527 if (encryption_cmd.cmd == LC_ENCRYPTION_INFO || encryption_cmd.cmd == LC_ENCRYPTION_INFO_64)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001528 {
Greg Clayton3046e662013-07-10 01:23:25 +00001529 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001530 {
Greg Clayton3046e662013-07-10 01:23:25 +00001531 if (encryption_cmd.cryptid != 0)
Greg Claytond37d6922013-04-16 16:51:19 +00001532 {
Greg Clayton3046e662013-07-10 01:23:25 +00001533 EncryptedFileRanges::Entry entry;
1534 entry.SetRangeBase(encryption_cmd.cryptoff);
1535 entry.SetByteSize(encryption_cmd.cryptsize);
1536 encrypted_file_ranges.Append(entry);
Jason Molendaf6ce26f2013-04-10 05:58:57 +00001537 }
1538 }
Greg Clayton3046e662013-07-10 01:23:25 +00001539 }
1540 offset = load_cmd_offset + encryption_cmd.cmdsize;
1541 }
1542
Jason Molenda05a09c62014-08-22 02:46:46 +00001543 bool section_file_addresses_changed = false;
1544
Greg Clayton3046e662013-07-10 01:23:25 +00001545 offset = MachHeaderSizeFromMagic(m_header.magic);
1546
1547 struct segment_command_64 load_cmd;
1548 for (i=0; i<m_header.ncmds; ++i)
1549 {
1550 const lldb::offset_t load_cmd_offset = offset;
1551 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1552 break;
1553
Charles Davis510938e2013-08-27 05:04:57 +00001554 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
Greg Clayton3046e662013-07-10 01:23:25 +00001555 {
1556 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001557 {
Greg Clayton3046e662013-07-10 01:23:25 +00001558 bool add_section = true;
1559 bool add_to_unified = true;
1560 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 +00001561
Greg Clayton3046e662013-07-10 01:23:25 +00001562 SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
1563 if (is_dsym && unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001564 {
Greg Clayton3046e662013-07-10 01:23:25 +00001565 if (const_segname == GetSegmentNameLINKEDIT())
1566 {
1567 // We need to keep the __LINKEDIT segment private to this object file only
1568 add_to_unified = false;
1569 }
1570 else
1571 {
1572 // This is the dSYM file and this section has already been created by
1573 // the object file, no need to create it.
1574 add_section = false;
1575 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001576 }
Greg Clayton3046e662013-07-10 01:23:25 +00001577 load_cmd.vmaddr = m_data.GetAddress(&offset);
1578 load_cmd.vmsize = m_data.GetAddress(&offset);
1579 load_cmd.fileoff = m_data.GetAddress(&offset);
1580 load_cmd.filesize = m_data.GetAddress(&offset);
1581 if (m_length != 0 && load_cmd.filesize != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001582 {
Greg Clayton3046e662013-07-10 01:23:25 +00001583 if (load_cmd.fileoff > m_length)
1584 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001585 // 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 +00001586 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001587 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001588 // is null out the SectionList vector and if a process has been set up, dump a message
1589 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001590 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001591 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 +00001592 i,
1593 lc_segment_name,
1594 load_cmd.fileoff,
1595 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001596
1597 load_cmd.fileoff = 0;
1598 load_cmd.filesize = 0;
1599 }
1600
1601 if (load_cmd.fileoff + load_cmd.filesize > m_length)
1602 {
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001603 // 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 +00001604 // a corrupt file. We don't have any way to return an error condition here (this method
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001605 // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
Greg Clayton3046e662013-07-10 01:23:25 +00001606 // is null out the SectionList vector and if a process has been set up, dump a message
1607 // to stdout. The most common case here is core file debugging with a truncated file.
Charles Davis510938e2013-08-27 05:04:57 +00001608 const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
Jason Molenda7e50d912013-09-14 05:20:02 +00001609 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 +00001610 i,
1611 lc_segment_name,
1612 load_cmd.fileoff + load_cmd.filesize,
1613 m_length);
Greg Clayton3046e662013-07-10 01:23:25 +00001614
1615 // Tuncase the length
1616 load_cmd.filesize = m_length - load_cmd.fileoff;
1617 }
1618 }
1619 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
1620 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001621
Charles Davis510938e2013-08-27 05:04:57 +00001622 const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001623
Greg Clayton3046e662013-07-10 01:23:25 +00001624 // Keep a list of mach segments around in case we need to
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001625 // get at data that isn't stored in the abstracted Sections.
Greg Clayton3046e662013-07-10 01:23:25 +00001626 m_mach_segments.push_back (load_cmd);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001627
Greg Clayton3046e662013-07-10 01:23:25 +00001628 // Use a segment ID of the segment index shifted left by 8 so they
1629 // never conflict with any of the sections.
1630 SectionSP segment_sp;
1631 if (add_section && (const_segname || is_core))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001632 {
Greg Clayton3046e662013-07-10 01:23:25 +00001633 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
1634 this, // Object file to which this sections belongs
1635 ++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
1636 const_segname, // Name of this section
1637 eSectionTypeContainer, // This section is a container of other sections.
1638 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
1639 load_cmd.vmsize, // VM size in bytes of this section
1640 load_cmd.fileoff, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001641 load_cmd.filesize, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001642 0, // Segments have no alignment information
Greg Clayton3046e662013-07-10 01:23:25 +00001643 load_cmd.flags)); // Flags for this section
Greg Clayton8d38ac42010-06-28 23:51:11 +00001644
Greg Clayton3046e662013-07-10 01:23:25 +00001645 segment_sp->SetIsEncrypted (segment_is_encrypted);
1646 m_sections_ap->AddSection(segment_sp);
1647 if (add_to_unified)
1648 unified_section_list.AddSection(segment_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001649 }
Greg Clayton3046e662013-07-10 01:23:25 +00001650 else if (unified_section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651 {
Jason Molenda20eb31b2013-08-16 03:20:42 +00001652 if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr)
1653 {
1654 // Check to see if the module was read from memory?
1655 if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid())
1656 {
1657 // We have a module that is in memory and needs to have its
1658 // file address adjusted. We need to do this because when we
1659 // load a file from memory, its addresses will be slid already,
1660 // yet the addresses in the new symbol file will still be unslid.
1661 // Since everything is stored as section offset, this shouldn't
1662 // cause any problems.
Jason Molenda5894a732013-08-17 03:39:52 +00001663
1664 // Make sure we've parsed the symbol table from the
1665 // ObjectFile before we go around changing its Sections.
1666 module_sp->GetObjectFile()->GetSymtab();
1667 // eh_frame would present the same problems but we parse that on
1668 // a per-function basis as-needed so it's more difficult to
1669 // remove its use of the Sections. Realistically, the environments
1670 // where this code path will be taken will not have eh_frame sections.
1671
Jason Molenda20eb31b2013-08-16 03:20:42 +00001672 unified_section_sp->SetFileAddress(load_cmd.vmaddr);
Jason Molenda05a09c62014-08-22 02:46:46 +00001673
1674 // Notify the module that the section addresses have been changed once
1675 // we're done so any file-address caches can be updated.
1676 section_file_addresses_changed = true;
Jason Molenda20eb31b2013-08-16 03:20:42 +00001677 }
1678 }
Greg Clayton3046e662013-07-10 01:23:25 +00001679 m_sections_ap->AddSection(unified_section_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001680 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001681
Greg Clayton3046e662013-07-10 01:23:25 +00001682 struct section_64 sect64;
1683 ::memset (&sect64, 0, sizeof(sect64));
1684 // Push a section into our mach sections for the section at
Charles Davis510938e2013-08-27 05:04:57 +00001685 // index zero (NO_SECT) if we don't have any mach sections yet...
Greg Clayton3046e662013-07-10 01:23:25 +00001686 if (m_mach_sections.empty())
1687 m_mach_sections.push_back(sect64);
1688 uint32_t segment_sect_idx;
1689 const lldb::user_id_t first_segment_sectID = sectID + 1;
1690
1691
Charles Davis510938e2013-08-27 05:04:57 +00001692 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
Greg Clayton3046e662013-07-10 01:23:25 +00001693 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001694 {
Greg Clayton3046e662013-07-10 01:23:25 +00001695 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
Greg Clayton89411422010-10-08 00:21:05 +00001696 break;
Greg Clayton3046e662013-07-10 01:23:25 +00001697 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
1698 break;
1699 sect64.addr = m_data.GetAddress(&offset);
1700 sect64.size = m_data.GetAddress(&offset);
1701
1702 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
1703 break;
1704
1705 // Keep a list of mach sections around in case we need to
1706 // get at data that isn't stored in the abstracted Sections.
1707 m_mach_sections.push_back (sect64);
1708
1709 if (add_section)
1710 {
1711 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
1712 if (!const_segname)
1713 {
1714 // We have a segment with no name so we need to conjure up
1715 // segments that correspond to the section's segname if there
1716 // isn't already such a section. If there is such a section,
1717 // we resize the section so that it spans all sections.
1718 // We also mark these sections as fake so address matches don't
1719 // hit if they land in the gaps between the child sections.
1720 const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
1721 segment_sp = unified_section_list.FindSectionByName (const_segname);
1722 if (segment_sp.get())
1723 {
1724 Section *segment = segment_sp.get();
1725 // Grow the section size as needed.
1726 const lldb::addr_t sect64_min_addr = sect64.addr;
1727 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
1728 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
1729 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
1730 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
1731 if (sect64_min_addr >= curr_seg_min_addr)
1732 {
1733 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
1734 // Only grow the section size if needed
1735 if (new_seg_byte_size > curr_seg_byte_size)
1736 segment->SetByteSize (new_seg_byte_size);
1737 }
1738 else
1739 {
1740 // We need to change the base address of the segment and
1741 // adjust the child section offsets for all existing children.
1742 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
1743 segment->Slide(slide_amount, false);
1744 segment->GetChildren().Slide(-slide_amount, false);
1745 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
1746 }
1747
1748 // Grow the section size as needed.
1749 if (sect64.offset)
1750 {
1751 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
1752 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
1753
1754 const lldb::addr_t section_min_file_offset = sect64.offset;
1755 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
1756 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
1757 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
1758 segment->SetFileOffset (new_file_offset);
1759 segment->SetFileSize (new_file_size);
1760 }
1761 }
1762 else
1763 {
1764 // Create a fake section for the section's named segment
1765 segment_sp.reset(new Section (segment_sp, // Parent section
1766 module_sp, // Module to which this section belongs
1767 this, // Object file to which this section belongs
1768 ++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
1769 const_segname, // Name of this section
1770 eSectionTypeContainer, // This section is a container of other sections.
1771 sect64.addr, // File VM address == addresses as they are found in the object file
1772 sect64.size, // VM size in bytes of this section
1773 sect64.offset, // Offset to the data for this section in the file
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00001774 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the file
Greg Clayton48672af2014-06-24 22:22:43 +00001775 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001776 load_cmd.flags)); // Flags for this section
1777 segment_sp->SetIsFake(true);
1778
1779 m_sections_ap->AddSection(segment_sp);
1780 if (add_to_unified)
1781 unified_section_list.AddSection(segment_sp);
1782 segment_sp->SetIsEncrypted (segment_is_encrypted);
1783 }
1784 }
1785 assert (segment_sp.get());
1786
Charles Davis510938e2013-08-27 05:04:57 +00001787 lldb::SectionType sect_type = eSectionTypeOther;
Greg Clayton3046e662013-07-10 01:23:25 +00001788
Greg Clayton38f9cc42014-06-16 22:53:16 +00001789 if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
1790 sect_type = eSectionTypeCode;
1791 else
Greg Clayton3046e662013-07-10 01:23:25 +00001792 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001793 uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
1794 static ConstString g_sect_name_objc_data ("__objc_data");
1795 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
1796 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
1797 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
1798 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
1799 static ConstString g_sect_name_objc_const ("__objc_const");
1800 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
1801 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton3046e662013-07-10 01:23:25 +00001802
Greg Clayton38f9cc42014-06-16 22:53:16 +00001803 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
1804 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
1805 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
1806 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
1807 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
1808 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
1809 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
1810 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
1811 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
1812 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
1813 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
1814 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
1815 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
1816 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
1817 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
1818 static ConstString g_sect_name_eh_frame ("__eh_frame");
Jason Molendae589e7e2014-12-08 03:09:00 +00001819 static ConstString g_sect_name_compact_unwind ("__unwind_info");
Greg Clayton38f9cc42014-06-16 22:53:16 +00001820 static ConstString g_sect_name_text ("__text");
1821 static ConstString g_sect_name_data ("__data");
Ryan Brown65d4d5c2015-09-16 21:20:44 +00001822 static ConstString g_sect_name_go_symtab ("__gosymtab");
Greg Clayton38f9cc42014-06-16 22:53:16 +00001823
Greg Clayton38f9cc42014-06-16 22:53:16 +00001824 if (section_name == g_sect_name_dwarf_debug_abbrev)
1825 sect_type = eSectionTypeDWARFDebugAbbrev;
1826 else if (section_name == g_sect_name_dwarf_debug_aranges)
1827 sect_type = eSectionTypeDWARFDebugAranges;
1828 else if (section_name == g_sect_name_dwarf_debug_frame)
1829 sect_type = eSectionTypeDWARFDebugFrame;
1830 else if (section_name == g_sect_name_dwarf_debug_info)
1831 sect_type = eSectionTypeDWARFDebugInfo;
1832 else if (section_name == g_sect_name_dwarf_debug_line)
1833 sect_type = eSectionTypeDWARFDebugLine;
1834 else if (section_name == g_sect_name_dwarf_debug_loc)
1835 sect_type = eSectionTypeDWARFDebugLoc;
1836 else if (section_name == g_sect_name_dwarf_debug_macinfo)
1837 sect_type = eSectionTypeDWARFDebugMacInfo;
1838 else if (section_name == g_sect_name_dwarf_debug_pubnames)
1839 sect_type = eSectionTypeDWARFDebugPubNames;
1840 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
1841 sect_type = eSectionTypeDWARFDebugPubTypes;
1842 else if (section_name == g_sect_name_dwarf_debug_ranges)
1843 sect_type = eSectionTypeDWARFDebugRanges;
1844 else if (section_name == g_sect_name_dwarf_debug_str)
1845 sect_type = eSectionTypeDWARFDebugStr;
1846 else if (section_name == g_sect_name_dwarf_apple_names)
1847 sect_type = eSectionTypeDWARFAppleNames;
1848 else if (section_name == g_sect_name_dwarf_apple_types)
1849 sect_type = eSectionTypeDWARFAppleTypes;
1850 else if (section_name == g_sect_name_dwarf_apple_namespaces)
1851 sect_type = eSectionTypeDWARFAppleNamespaces;
1852 else if (section_name == g_sect_name_dwarf_apple_objc)
1853 sect_type = eSectionTypeDWARFAppleObjC;
1854 else if (section_name == g_sect_name_objc_selrefs)
1855 sect_type = eSectionTypeDataCStringPointers;
1856 else if (section_name == g_sect_name_objc_msgrefs)
1857 sect_type = eSectionTypeDataObjCMessageRefs;
1858 else if (section_name == g_sect_name_eh_frame)
1859 sect_type = eSectionTypeEHFrame;
Jason Molendae589e7e2014-12-08 03:09:00 +00001860 else if (section_name == g_sect_name_compact_unwind)
1861 sect_type = eSectionTypeCompactUnwind;
Greg Clayton38f9cc42014-06-16 22:53:16 +00001862 else if (section_name == g_sect_name_cfstring)
1863 sect_type = eSectionTypeDataObjCCFStrings;
Ryan Brown65d4d5c2015-09-16 21:20:44 +00001864 else if (section_name == g_sect_name_go_symtab)
1865 sect_type = eSectionTypeGoSymtab;
Greg Clayton38f9cc42014-06-16 22:53:16 +00001866 else if (section_name == g_sect_name_objc_data ||
1867 section_name == g_sect_name_objc_classrefs ||
1868 section_name == g_sect_name_objc_superrefs ||
1869 section_name == g_sect_name_objc_const ||
1870 section_name == g_sect_name_objc_classlist)
Greg Clayton3046e662013-07-10 01:23:25 +00001871 {
Greg Clayton38f9cc42014-06-16 22:53:16 +00001872 sect_type = eSectionTypeDataPointers;
1873 }
1874
1875 if (sect_type == eSectionTypeOther)
1876 {
1877 switch (mach_sect_type)
1878 {
1879 // TODO: categorize sections by other flags for regular sections
1880 case S_REGULAR:
1881 if (section_name == g_sect_name_text)
1882 sect_type = eSectionTypeCode;
1883 else if (section_name == g_sect_name_data)
1884 sect_type = eSectionTypeData;
1885 else
1886 sect_type = eSectionTypeOther;
1887 break;
1888 case S_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1889 case S_CSTRING_LITERALS: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1890 case S_4BYTE_LITERALS: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1891 case S_8BYTE_LITERALS: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1892 case S_LITERAL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1893 case S_NON_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1894 case S_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1895 case S_SYMBOL_STUBS: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1896 case S_MOD_INIT_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1897 case S_MOD_TERM_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1898 case S_COALESCED: sect_type = eSectionTypeOther; break;
1899 case S_GB_ZEROFILL: sect_type = eSectionTypeZeroFill; break;
1900 case S_INTERPOSING: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1901 case S_16BYTE_LITERALS: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1902 case S_DTRACE_DOF: sect_type = eSectionTypeDebug; break;
1903 case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break;
1904 default: break;
1905 }
Greg Clayton3046e662013-07-10 01:23:25 +00001906 }
1907 }
1908
1909 SectionSP section_sp(new Section (segment_sp,
1910 module_sp,
1911 this,
1912 ++sectID,
1913 section_name,
1914 sect_type,
1915 sect64.addr - segment_sp->GetFileAddress(),
1916 sect64.size,
1917 sect64.offset,
1918 sect64.offset == 0 ? 0 : sect64.size,
Greg Clayton48672af2014-06-24 22:22:43 +00001919 sect64.align,
Greg Clayton3046e662013-07-10 01:23:25 +00001920 sect64.flags));
1921 // Set the section to be encrypted to match the segment
1922
1923 bool section_is_encrypted = false;
1924 if (!segment_is_encrypted && load_cmd.filesize != 0)
1925 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
1926
1927 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
1928 segment_sp->GetChildren().AddSection(section_sp);
1929
1930 if (segment_sp->IsFake())
1931 {
1932 segment_sp.reset();
1933 const_segname.Clear();
1934 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001935 }
1936 }
Greg Clayton3046e662013-07-10 01:23:25 +00001937 if (segment_sp && is_dsym)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001938 {
Greg Clayton3046e662013-07-10 01:23:25 +00001939 if (first_segment_sectID <= sectID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001940 {
Greg Clayton3046e662013-07-10 01:23:25 +00001941 lldb::user_id_t sect_uid;
1942 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001943 {
Greg Clayton3046e662013-07-10 01:23:25 +00001944 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1945 SectionSP next_section_sp;
1946 if (sect_uid + 1 <= sectID)
1947 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1948
1949 if (curr_section_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001950 {
Greg Clayton3046e662013-07-10 01:23:25 +00001951 if (curr_section_sp->GetByteSize() == 0)
1952 {
1953 if (next_section_sp.get() != NULL)
1954 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1955 else
1956 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1957 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001958 }
1959 }
1960 }
1961 }
1962 }
1963 }
1964 }
Charles Davis510938e2013-08-27 05:04:57 +00001965 else if (load_cmd.cmd == LC_DYSYMTAB)
Greg Clayton3046e662013-07-10 01:23:25 +00001966 {
1967 m_dysymtab.cmd = load_cmd.cmd;
1968 m_dysymtab.cmdsize = load_cmd.cmdsize;
1969 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1970 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001971
Greg Clayton3046e662013-07-10 01:23:25 +00001972 offset = load_cmd_offset + load_cmd.cmdsize;
1973 }
Jason Molenda05a09c62014-08-22 02:46:46 +00001974
1975
1976 if (section_file_addresses_changed && module_sp.get())
1977 {
1978 module_sp->SectionFileAddressesChanged();
1979 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001980 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001981}
1982
1983class MachSymtabSectionInfo
1984{
1985public:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001986 MachSymtabSectionInfo (SectionList *section_list) :
1987 m_section_list (section_list),
1988 m_section_infos()
1989 {
1990 // Get the number of sections down to a depth of 1 to include
1991 // all segments and their sections, but no other sections that
1992 // may be added for debug map or
1993 m_section_infos.resize(section_list->GetNumSections(1));
1994 }
1995
Greg Claytone72dfb32012-02-24 01:59:29 +00001996 SectionSP
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001997 GetSection (uint8_t n_sect, addr_t file_addr)
1998 {
1999 if (n_sect == 0)
Greg Claytone72dfb32012-02-24 01:59:29 +00002000 return SectionSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002001 if (n_sect < m_section_infos.size())
2002 {
Greg Claytone72dfb32012-02-24 01:59:29 +00002003 if (!m_section_infos[n_sect].section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002004 {
Greg Claytone72dfb32012-02-24 01:59:29 +00002005 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
2006 m_section_infos[n_sect].section_sp = section_sp;
Sean Callanan9a028512012-08-09 00:50:26 +00002007 if (section_sp)
Greg Claytondda0d122011-07-10 17:32:33 +00002008 {
Greg Claytone72dfb32012-02-24 01:59:29 +00002009 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
2010 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Claytondda0d122011-07-10 17:32:33 +00002011 }
2012 else
2013 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00002014 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Claytondda0d122011-07-10 17:32:33 +00002015 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002016 }
2017 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton8f258512011-08-26 20:01:35 +00002018 {
2019 // Symbol is in section.
Greg Claytone72dfb32012-02-24 01:59:29 +00002020 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00002021 }
2022 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
2023 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
2024 {
2025 // Symbol is in section with zero size, but has the same start
2026 // address as the section. This can happen with linker symbols
2027 // (symbols that start with the letter 'l' or 'L'.
Greg Claytone72dfb32012-02-24 01:59:29 +00002028 return m_section_infos[n_sect].section_sp;
Greg Clayton8f258512011-08-26 20:01:35 +00002029 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002030 }
Greg Claytone72dfb32012-02-24 01:59:29 +00002031 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002032 }
2033
2034protected:
2035 struct SectionInfo
2036 {
2037 SectionInfo () :
2038 vm_range(),
Greg Claytone72dfb32012-02-24 01:59:29 +00002039 section_sp ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002040 {
2041 }
2042
2043 VMRange vm_range;
Greg Claytone72dfb32012-02-24 01:59:29 +00002044 SectionSP section_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002045 };
2046 SectionList *m_section_list;
2047 std::vector<SectionInfo> m_section_infos;
2048};
2049
Greg Clayton9191db42013-10-21 18:40:51 +00002050struct TrieEntry
2051{
2052 TrieEntry () :
2053 name(),
2054 address(LLDB_INVALID_ADDRESS),
2055 flags (0),
2056 other(0),
2057 import_name()
2058 {
2059 }
2060
2061 void
2062 Clear ()
2063 {
2064 name.Clear();
2065 address = LLDB_INVALID_ADDRESS;
2066 flags = 0;
2067 other = 0;
2068 import_name.Clear();
2069 }
2070
2071 void
2072 Dump () const
2073 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002074 printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
2075 static_cast<unsigned long long>(address),
2076 static_cast<unsigned long long>(flags),
2077 static_cast<unsigned long long>(other), name.GetCString());
Greg Clayton9191db42013-10-21 18:40:51 +00002078 if (import_name)
2079 printf (" -> \"%s\"\n", import_name.GetCString());
2080 else
2081 printf ("\n");
2082 }
2083 ConstString name;
2084 uint64_t address;
2085 uint64_t flags;
2086 uint64_t other;
2087 ConstString import_name;
2088};
2089
2090struct TrieEntryWithOffset
2091{
2092 lldb::offset_t nodeOffset;
2093 TrieEntry entry;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002094
Greg Clayton9191db42013-10-21 18:40:51 +00002095 TrieEntryWithOffset (lldb::offset_t offset) :
2096 nodeOffset (offset),
2097 entry()
2098 {
2099 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002100
Greg Clayton9191db42013-10-21 18:40:51 +00002101 void
2102 Dump (uint32_t idx) const
2103 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002104 printf ("[%3u] 0x%16.16llx: ", idx,
2105 static_cast<unsigned long long>(nodeOffset));
Greg Clayton9191db42013-10-21 18:40:51 +00002106 entry.Dump();
2107 }
2108
2109 bool
2110 operator<(const TrieEntryWithOffset& other) const
2111 {
2112 return ( nodeOffset < other.nodeOffset );
2113 }
2114};
2115
Greg Clayton8f265f72015-10-28 20:49:34 +00002116static bool
Greg Clayton9191db42013-10-21 18:40:51 +00002117ParseTrieEntries (DataExtractor &data,
2118 lldb::offset_t offset,
Greg Claytonb887da12015-07-16 19:50:57 +00002119 const bool is_arm,
Greg Clayton9191db42013-10-21 18:40:51 +00002120 std::vector<llvm::StringRef> &nameSlices,
2121 std::set<lldb::addr_t> &resolver_addresses,
2122 std::vector<TrieEntryWithOffset>& output)
2123{
2124 if (!data.ValidOffset(offset))
Greg Clayton8f265f72015-10-28 20:49:34 +00002125 return true;
Greg Clayton9191db42013-10-21 18:40:51 +00002126
2127 const uint64_t terminalSize = data.GetULEB128(&offset);
2128 lldb::offset_t children_offset = offset + terminalSize;
2129 if ( terminalSize != 0 ) {
2130 TrieEntryWithOffset e (offset);
2131 e.entry.flags = data.GetULEB128(&offset);
2132 const char *import_name = NULL;
2133 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
2134 e.entry.address = 0;
2135 e.entry.other = data.GetULEB128(&offset); // dylib ordinal
2136 import_name = data.GetCStr(&offset);
2137 }
2138 else {
2139 e.entry.address = data.GetULEB128(&offset);
2140 if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
2141 {
Greg Clayton9191db42013-10-21 18:40:51 +00002142 e.entry.other = data.GetULEB128(&offset);
Greg Claytonb887da12015-07-16 19:50:57 +00002143 uint64_t resolver_addr = e.entry.other;
2144 if (is_arm)
2145 resolver_addr &= THUMB_ADDRESS_BIT_MASK;
2146 resolver_addresses.insert(resolver_addr);
Greg Clayton9191db42013-10-21 18:40:51 +00002147 }
2148 else
2149 e.entry.other = 0;
2150 }
2151 // Only add symbols that are reexport symbols with a valid import name
2152 if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
2153 {
2154 std::string name;
2155 if (!nameSlices.empty())
2156 {
2157 for (auto name_slice: nameSlices)
2158 name.append(name_slice.data(), name_slice.size());
2159 }
2160 if (name.size() > 1)
2161 {
2162 // Skip the leading '_'
2163 e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
2164 }
2165 if (import_name)
2166 {
2167 // Skip the leading '_'
2168 e.entry.import_name.SetCString(import_name+1);
2169 }
2170 output.push_back(e);
2171 }
2172 }
2173
2174 const uint8_t childrenCount = data.GetU8(&children_offset);
2175 for (uint8_t i=0; i < childrenCount; ++i) {
Greg Clayton8f265f72015-10-28 20:49:34 +00002176 const char *cstr = data.GetCStr(&children_offset);
2177 if (cstr)
2178 nameSlices.push_back(llvm::StringRef(cstr));
2179 else
2180 return false; // Corrupt data
Greg Clayton9191db42013-10-21 18:40:51 +00002181 lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
2182 if (childNodeOffset)
2183 {
Greg Clayton8f265f72015-10-28 20:49:34 +00002184 if (!ParseTrieEntries(data,
2185 childNodeOffset,
2186 is_arm,
2187 nameSlices,
2188 resolver_addresses,
2189 output))
2190 {
2191 return false;
2192 }
Greg Clayton9191db42013-10-21 18:40:51 +00002193 }
2194 nameSlices.pop_back();
2195 }
Greg Clayton8f265f72015-10-28 20:49:34 +00002196 return true;
Greg Clayton9191db42013-10-21 18:40:51 +00002197}
2198
Jason Molenda649a6072015-11-10 05:21:54 +00002199// Read the UUID out of a dyld_shared_cache file on-disk.
2200UUID
2201ObjectFileMachO::GetSharedCacheUUID (FileSpec dyld_shared_cache, const ByteOrder byte_order, const uint32_t addr_byte_size)
2202{
2203 UUID dsc_uuid;
2204 DataBufferSP dsc_data_sp = dyld_shared_cache.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
2205 if (dsc_data_sp)
2206 {
2207 DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size);
2208
2209 char version_str[7];
2210 lldb::offset_t offset = 0;
2211 memcpy (version_str, dsc_header_data.GetData (&offset, 6), 6);
2212 version_str[6] = '\0';
2213 if (strcmp (version_str, "dyld_v") == 0)
2214 {
2215 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
2216 uint8_t uuid_bytes[sizeof (uuid_t)];
2217 memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
2218 dsc_uuid.SetBytes (uuid_bytes);
2219 }
2220 }
2221 return dsc_uuid;
2222}
2223
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002224size_t
Greg Clayton3046e662013-07-10 01:23:25 +00002225ObjectFileMachO::ParseSymtab ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002226{
2227 Timer scoped_timer(__PRETTY_FUNCTION__,
2228 "ObjectFileMachO::ParseSymtab () module = %s",
2229 m_file.GetFilename().AsCString(""));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002230 ModuleSP module_sp (GetModule());
2231 if (!module_sp)
2232 return 0;
2233
2234 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
2235 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
Greg Clayton9191db42013-10-21 18:40:51 +00002236 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 +00002237 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
2238 FunctionStarts function_starts;
Greg Claytonc7bece562013-01-25 18:06:21 +00002239 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002240 uint32_t i;
Greg Clayton9191db42013-10-21 18:40:51 +00002241 FileSpecList dylib_files;
Greg Clayton5160ce52013-03-27 23:08:40 +00002242 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
Greg Clayton1e28adf2015-02-25 17:25:02 +00002243 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2244 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2245 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
Greg Clayton77ccca72011-12-30 00:32:24 +00002246
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002247 for (i=0; i<m_header.ncmds; ++i)
2248 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002249 const lldb::offset_t cmd_offset = offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002250 // Read in the load command and load command size
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002251 struct load_command lc;
2252 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002253 break;
2254 // Watch for the symbol table load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002255 switch (lc.cmd)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002256 {
Charles Davis510938e2013-08-27 05:04:57 +00002257 case LC_SYMTAB:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002258 symtab_load_command.cmd = lc.cmd;
2259 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002260 // Read in the rest of the symtab load command
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002261 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
2262 return 0;
2263 if (symtab_load_command.symoff == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002264 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002265 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002266 module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002267 return 0;
2268 }
2269
2270 if (symtab_load_command.stroff == 0)
2271 {
2272 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002273 module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002274 return 0;
2275 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002276
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002277 if (symtab_load_command.nsyms == 0)
2278 {
2279 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002280 module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002281 return 0;
2282 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002283
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002284 if (symtab_load_command.strsize == 0)
2285 {
2286 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002287 module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002288 return 0;
2289 }
2290 break;
2291
Greg Clayton9191db42013-10-21 18:40:51 +00002292 case LC_DYLD_INFO:
2293 case LC_DYLD_INFO_ONLY:
2294 if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
2295 {
2296 dyld_info.cmd = lc.cmd;
2297 dyld_info.cmdsize = lc.cmdsize;
2298 }
2299 else
2300 {
2301 memset (&dyld_info, 0, sizeof(dyld_info));
2302 }
2303 break;
2304
2305 case LC_LOAD_DYLIB:
2306 case LC_LOAD_WEAK_DYLIB:
2307 case LC_REEXPORT_DYLIB:
2308 case LC_LOADFVMLIB:
2309 case LC_LOAD_UPWARD_DYLIB:
2310 {
2311 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2312 const char *path = m_data.PeekCStr(name_offset);
2313 if (path)
2314 {
2315 FileSpec file_spec(path, false);
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002316 // Strip the path if there is @rpath, @executable, etc so we just use the basename
Greg Clayton9191db42013-10-21 18:40:51 +00002317 if (path[0] == '@')
2318 file_spec.GetDirectory().Clear();
Jim Inghamfbe0b9a2014-05-21 03:58:03 +00002319
2320 if (lc.cmd == LC_REEXPORT_DYLIB)
2321 {
2322 m_reexported_dylibs.AppendIfUnique(file_spec);
2323 }
Greg Clayton9191db42013-10-21 18:40:51 +00002324
2325 dylib_files.Append(file_spec);
2326 }
2327 }
2328 break;
2329
Charles Davis510938e2013-08-27 05:04:57 +00002330 case LC_FUNCTION_STARTS:
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002331 function_starts_load_command.cmd = lc.cmd;
2332 function_starts_load_command.cmdsize = lc.cmdsize;
2333 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 +00002334 memset (&function_starts_load_command, 0, sizeof(function_starts_load_command));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002335 break;
2336
2337 default:
2338 break;
2339 }
2340 offset = cmd_offset + lc.cmdsize;
2341 }
2342
2343 if (symtab_load_command.cmd)
2344 {
2345 Symtab *symtab = m_symtab_ap.get();
2346 SectionList *section_list = GetSectionList();
2347 if (section_list == NULL)
2348 return 0;
2349
Greg Claytonc7bece562013-01-25 18:06:21 +00002350 const uint32_t addr_byte_size = m_data.GetAddressByteSize();
2351 const ByteOrder byte_order = m_data.GetByteOrder();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002352 bool bit_width_32 = addr_byte_size == 4;
2353 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
2354
Greg Claytonc7bece562013-01-25 18:06:21 +00002355 DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
2356 DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
2357 DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
Jason Molendad34e6522013-02-05 22:31:24 +00002358 DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002359 DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);
Jason Molenda4e7511e2013-03-06 23:19:17 +00002360
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002361 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
2362 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Clayton4c82d422012-05-18 23:20:01 +00002363 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
Greg Claytonfd814c52013-08-13 01:42:25 +00002364
2365 ProcessSP process_sp (m_process_wp.lock());
2366 Process *process = process_sp.get();
2367
Greg Clayton86eac942013-08-13 21:32:34 +00002368 uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;
2369
Greg Clayton48672af2014-06-24 22:22:43 +00002370 if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002371 {
Greg Clayton4c82d422012-05-18 23:20:01 +00002372 Target &target = process->GetTarget();
Greg Claytonfd814c52013-08-13 01:42:25 +00002373
Greg Clayton86eac942013-08-13 21:32:34 +00002374 memory_module_load_level = target.GetMemoryModuleLoadLevel();
Greg Claytonfd814c52013-08-13 01:42:25 +00002375
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002376 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
2377 // Reading mach file from memory in a process or core file...
2378
2379 if (linkedit_section_sp)
2380 {
Greg Clayton07347372015-06-08 21:53:11 +00002381 addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
2382 if (linkedit_load_addr == LLDB_INVALID_ADDRESS)
2383 {
2384 // We might be trying to access the symbol table before the __LINKEDIT's load
2385 // address has been set in the target. We can't fail to read the symbol table,
2386 // so calculate the right address manually
2387 linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
2388 }
2389
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002390 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
2391 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Clayton4c82d422012-05-18 23:20:01 +00002392 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton26b47e22012-04-18 05:19:20 +00002393
2394 bool data_was_read = false;
2395
Todd Fiala013434e2014-07-09 01:29:05 +00002396#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa3329782014-03-29 18:54:20 +00002397 if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
Greg Clayton77ccca72011-12-30 00:32:24 +00002398 {
Greg Clayton26b47e22012-04-18 05:19:20 +00002399 // This mach-o memory file is in the dyld shared cache. If this
2400 // program is not remote and this is iOS, then this process will
2401 // share the same shared cache as the process we are debugging and
2402 // we can read the entire __LINKEDIT from the address space in this
2403 // process. This is a needed optimization that is used for local iOS
2404 // debugging only since all shared libraries in the shared cache do
2405 // not have corresponding files that exist in the file system of the
2406 // device. They have been combined into a single file. This means we
2407 // always have to load these files from memory. All of the symbol and
2408 // string tables from all of the __LINKEDIT sections from the shared
2409 // libraries in the shared cache have been merged into a single large
2410 // symbol and string table. Reading all of this symbol and string table
2411 // data across can slow down debug launch times, so we optimize this by
2412 // reading the memory for the __LINKEDIT section from this process.
Jason Molenda0e0954c2013-04-16 06:24:42 +00002413
2414 UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
2415 UUID process_shared_cache(GetProcessSharedCacheUUID(process));
2416 bool use_lldb_cache = true;
2417 if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache)
2418 {
2419 use_lldb_cache = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002420 ModuleSP module_sp (GetModule());
2421 if (module_sp)
2422 module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow.");
2423
Jason Molenda0e0954c2013-04-16 06:24:42 +00002424 }
2425
Greg Clayton26b47e22012-04-18 05:19:20 +00002426 PlatformSP platform_sp (target.GetPlatform());
Jason Molenda0e0954c2013-04-16 06:24:42 +00002427 if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
Greg Clayton26b47e22012-04-18 05:19:20 +00002428 {
2429 data_was_read = true;
2430 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Clayton4c82d422012-05-18 23:20:01 +00002431 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton26b47e22012-04-18 05:19:20 +00002432 if (function_starts_load_command.cmd)
2433 {
2434 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2435 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
2436 }
2437 }
2438 }
2439#endif
2440
2441 if (!data_was_read)
2442 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002443 if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
Jason Molendad34e6522013-02-05 22:31:24 +00002444 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002445 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
2446 if (nlist_data_sp)
2447 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
2448 // Load strings individually from memory when loading from memory since shared cache
2449 // string tables contain strings for all symbols from all shared cached libraries
2450 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
2451 //if (strtab_data_sp)
2452 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
2453 if (m_dysymtab.nindirectsyms != 0)
2454 {
2455 const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
2456 DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
2457 if (indirect_syms_data_sp)
2458 indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
2459 }
Jason Molendad34e6522013-02-05 22:31:24 +00002460 }
Greg Claytonfd814c52013-08-13 01:42:25 +00002461
2462 if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
Greg Clayton26b47e22012-04-18 05:19:20 +00002463 {
Greg Claytonfd814c52013-08-13 01:42:25 +00002464 if (function_starts_load_command.cmd)
2465 {
2466 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
2467 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
2468 if (func_start_data_sp)
2469 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
2470 }
Greg Clayton26b47e22012-04-18 05:19:20 +00002471 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002472 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002473 }
2474 }
2475 else
2476 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002477 nlist_data.SetData (m_data,
2478 symtab_load_command.symoff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002479 nlist_data_byte_size);
2480 strtab_data.SetData (m_data,
Jason Molenda4e7511e2013-03-06 23:19:17 +00002481 symtab_load_command.stroff,
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002482 strtab_data_byte_size);
Greg Clayton9191db42013-10-21 18:40:51 +00002483
2484 if (dyld_info.export_size > 0)
2485 {
2486 dyld_trie_data.SetData (m_data,
2487 dyld_info.export_off,
2488 dyld_info.export_size);
2489 }
2490
Jason Molendad34e6522013-02-05 22:31:24 +00002491 if (m_dysymtab.nindirectsyms != 0)
2492 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00002493 indirect_symbol_index_data.SetData (m_data,
2494 m_dysymtab.indirectsymoff,
Jason Molendad34e6522013-02-05 22:31:24 +00002495 m_dysymtab.nindirectsyms * 4);
2496 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002497 if (function_starts_load_command.cmd)
2498 {
2499 function_starts_data.SetData (m_data,
2500 function_starts_load_command.dataoff,
2501 function_starts_load_command.datasize);
2502 }
2503 }
Greg Clayton77ccca72011-12-30 00:32:24 +00002504
Greg Clayton86eac942013-08-13 21:32:34 +00002505 if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete)
2506 {
2507 if (log)
2508 module_sp->LogMessage(log, "failed to read nlist data");
2509 return 0;
2510 }
2511
Greg Claytondebb8812012-05-25 17:04:00 +00002512 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
2513 if (!have_strtab_data)
Greg Clayton4c82d422012-05-18 23:20:01 +00002514 {
Greg Claytondebb8812012-05-25 17:04:00 +00002515 if (process)
2516 {
2517 if (strtab_addr == LLDB_INVALID_ADDRESS)
2518 {
2519 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002520 module_sp->LogMessage(log, "failed to locate the strtab in memory");
Greg Claytondebb8812012-05-25 17:04:00 +00002521 return 0;
2522 }
2523 }
2524 else
Greg Clayton4c82d422012-05-18 23:20:01 +00002525 {
2526 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002527 module_sp->LogMessage(log, "failed to read strtab data");
Greg Clayton4c82d422012-05-18 23:20:01 +00002528 return 0;
2529 }
2530 }
Greg Clayton4c82d422012-05-18 23:20:01 +00002531
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002532 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
2533 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
Greg Claytona381e102015-07-27 23:21:05 +00002534 const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
2535 const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002536 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
2537 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
2538 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
2539 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
Greg Claytona381e102015-07-27 23:21:05 +00002540 SectionSP data_dirty_section_sp(section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
2541 SectionSP data_const_section_sp(section_list->FindSectionByName(g_segment_name_DATA_CONST));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002542 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
2543 SectionSP eh_frame_section_sp;
2544 if (text_section_sp.get())
2545 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
2546 else
2547 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
2548
Charles Davis510938e2013-08-27 05:04:57 +00002549 const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);
Jason Molenda5635f772013-03-21 03:36:01 +00002550
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002551 // lldb works best if it knows the start address of all functions in a module.
Jason Molenda5635f772013-03-21 03:36:01 +00002552 // Linker symbols or debug info are normally the best source of information for start addr / size but
2553 // they may be stripped in a released binary.
Jason Molendad63d3c72013-04-16 00:18:44 +00002554 // Two additional sources of information exist in Mach-O binaries:
Jason Molenda5635f772013-03-21 03:36:01 +00002555 // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
2556 // binary, relative to the text section.
2557 // eh_frame - the eh_frame FDEs have the start addr & size of each function
2558 // LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
2559 // Binaries built to run on older releases may need to use eh_frame information.
2560
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002561 if (text_section_sp && function_starts_data.GetByteSize())
2562 {
2563 FunctionStarts::Entry function_start_entry;
2564 function_start_entry.data = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00002565 lldb::offset_t function_start_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002566 function_start_entry.addr = text_section_sp->GetFileAddress();
2567 uint64_t delta;
2568 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
2569 {
2570 // Now append the current entry
2571 function_start_entry.addr += delta;
2572 function_starts.Append(function_start_entry);
2573 }
Jason Molendad63d3c72013-04-16 00:18:44 +00002574 }
Jason Molenda5635f772013-03-21 03:36:01 +00002575 else
2576 {
Jason Molenda584ce2f2013-03-22 00:38:45 +00002577 // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
2578 // but it doesn't actually have the eh_frame content. And if we have a dSYM, we don't need to do any
2579 // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
2580 // the module.
2581 if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
Jason Molenda5635f772013-03-21 03:36:01 +00002582 {
Jason Molendaa18f7072015-08-15 01:21:01 +00002583 DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindEHFrame, true);
Jason Molenda5635f772013-03-21 03:36:01 +00002584 DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
2585 eh_frame.GetFunctionAddressAndSizeVector (functions);
2586 addr_t text_base_addr = text_section_sp->GetFileAddress();
2587 size_t count = functions.GetSize();
2588 for (size_t i = 0; i < count; ++i)
2589 {
2590 const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
2591 if (func)
2592 {
2593 FunctionStarts::Entry function_start_entry;
2594 function_start_entry.addr = func->base - text_base_addr;
2595 function_starts.Append(function_start_entry);
2596 }
2597 }
2598 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002599 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00002600
Greg Claytonc7bece562013-01-25 18:06:21 +00002601 const size_t function_starts_count = function_starts.GetSize();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002602
Saleem Abdulrasoolb5c128b2014-07-23 01:53:52 +00002603 const user_id_t TEXT_eh_frame_sectID =
2604 eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
2605 : static_cast<user_id_t>(NO_SECT);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002606
Greg Claytonc7bece562013-01-25 18:06:21 +00002607 lldb::offset_t nlist_data_offset = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002608
2609 uint32_t N_SO_index = UINT32_MAX;
2610
2611 MachSymtabSectionInfo section_info (section_list);
2612 std::vector<uint32_t> N_FUN_indexes;
2613 std::vector<uint32_t> N_NSYM_indexes;
2614 std::vector<uint32_t> N_INCL_indexes;
2615 std::vector<uint32_t> N_BRAC_indexes;
2616 std::vector<uint32_t> N_COMM_indexes;
Greg Claytond81088c2014-01-16 01:38:29 +00002617 typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002618 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
Greg Claytondacc4a92013-05-14 22:19:37 +00002619 typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002620 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
2621 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
Greg Claytondacc4a92013-05-14 22:19:37 +00002622 ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002623 // Any symbols that get merged into another will get an entry
2624 // in this map so we know
2625 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
2626 uint32_t nlist_idx = 0;
2627 Symbol *symbol_ptr = NULL;
2628
2629 uint32_t sym_idx = 0;
Jason Molendaa5609c82012-06-21 01:51:02 +00002630 Symbol *sym = NULL;
Greg Claytonc7bece562013-01-25 18:06:21 +00002631 size_t num_syms = 0;
Greg Clayton4c82d422012-05-18 23:20:01 +00002632 std::string memory_symbol_name;
Jason Molendaa5609c82012-06-21 01:51:02 +00002633 uint32_t unmapped_local_symbols_found = 0;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00002634
Jim Inghamea3ac272014-01-10 22:55:37 +00002635 std::vector<TrieEntryWithOffset> trie_entries;
2636 std::set<lldb::addr_t> resolver_addresses;
2637
2638 if (dyld_trie_data.GetByteSize() > 0)
2639 {
2640 std::vector<llvm::StringRef> nameSlices;
2641 ParseTrieEntries (dyld_trie_data,
2642 0,
Greg Claytonb887da12015-07-16 19:50:57 +00002643 is_arm,
Jim Inghamea3ac272014-01-10 22:55:37 +00002644 nameSlices,
2645 resolver_addresses,
2646 trie_entries);
2647
2648 ConstString text_segment_name ("__TEXT");
2649 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2650 if (text_segment_sp)
2651 {
2652 const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
2653 if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
2654 {
2655 for (auto &e : trie_entries)
2656 e.entry.address += text_segment_file_addr;
2657 }
2658 }
2659 }
2660
Greg Claytonb65c6292015-02-20 22:20:05 +00002661 typedef std::set<ConstString> IndirectSymbols;
2662 IndirectSymbols indirect_symbol_names;
2663
Todd Fiala013434e2014-07-09 01:29:05 +00002664#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molendaa5609c82012-06-21 01:51:02 +00002665
2666 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
2667 // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
2668 // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
2669 // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
2670 // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
2671 // nlist parser to ignore all LOCAL symbols.
2672
2673 if (m_header.flags & 0x80000000u)
2674 {
2675 // Before we can start mapping the DSC, we need to make certain the target process is actually
2676 // using the cache we can find.
2677
Jason Molendaa5609c82012-06-21 01:51:02 +00002678 // Next we need to determine the correct path for the dyld shared cache.
2679
Greg Clayton7ab7f892014-05-29 21:33:45 +00002680 ArchSpec header_arch;
2681 GetArchitecture(header_arch);
Jason Molendaa5609c82012-06-21 01:51:02 +00002682 char dsc_path[PATH_MAX];
Jason Molenda649a6072015-11-10 05:21:54 +00002683 char dsc_path_development[PATH_MAX];
Jason Molendaa5609c82012-06-21 01:51:02 +00002684
2685 snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
Jason Molenda4e7511e2013-03-06 23:19:17 +00002686 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
2687 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
Jason Molendaa5609c82012-06-21 01:51:02 +00002688 header_arch.GetArchitectureName());
2689
Jason Molenda649a6072015-11-10 05:21:54 +00002690 snprintf(dsc_path_development, sizeof(dsc_path), "%s%s%s%s",
2691 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
2692 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
2693 header_arch.GetArchitectureName(),
2694 ".development");
Jason Molendaa5609c82012-06-21 01:51:02 +00002695
Jason Molenda649a6072015-11-10 05:21:54 +00002696 FileSpec dsc_nondevelopment_filespec(dsc_path, false);
2697 FileSpec dsc_development_filespec(dsc_path_development, false);
2698 FileSpec dsc_filespec;
Eugene Zelenko8157a882015-10-23 16:56:07 +00002699
Jason Molenda649a6072015-11-10 05:21:54 +00002700 UUID dsc_uuid;
2701 UUID process_shared_cache_uuid;
Jason Molenda255f9bb2013-03-06 23:17:36 +00002702
Jason Molenda649a6072015-11-10 05:21:54 +00002703 if (process)
Jason Molendad63d3c72013-04-16 00:18:44 +00002704 {
Jason Molenda649a6072015-11-10 05:21:54 +00002705 process_shared_cache_uuid = GetProcessSharedCacheUUID(process);
2706 }
Jason Molenda255f9bb2013-03-06 23:17:36 +00002707
Jason Molenda649a6072015-11-10 05:21:54 +00002708 // First see if we can find an exact match for the inferior process shared cache UUID in
2709 // the development or non-development shared caches on disk.
2710 if (process_shared_cache_uuid.IsValid())
Greg Clayton946f8902012-09-05 22:30:51 +00002711 {
Jason Molenda649a6072015-11-10 05:21:54 +00002712 if (dsc_development_filespec.Exists())
2713 {
2714 UUID dsc_development_uuid = GetSharedCacheUUID (dsc_development_filespec, byte_order, addr_byte_size);
2715 if (dsc_development_uuid.IsValid() && dsc_development_uuid == process_shared_cache_uuid)
2716 {
2717 dsc_filespec = dsc_development_filespec;
2718 dsc_uuid = dsc_development_uuid;
2719 }
2720 }
2721 if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists())
2722 {
2723 UUID dsc_nondevelopment_uuid = GetSharedCacheUUID (dsc_nondevelopment_filespec, byte_order, addr_byte_size);
2724 if (dsc_nondevelopment_uuid.IsValid() && dsc_nondevelopment_uuid == process_shared_cache_uuid)
2725 {
2726 dsc_filespec = dsc_nondevelopment_filespec;
2727 dsc_uuid = dsc_nondevelopment_uuid;
2728 }
2729 }
2730 }
Eugene Zelenko8157a882015-10-23 16:56:07 +00002731
Jason Molenda649a6072015-11-10 05:21:54 +00002732 // Failing a UUID match, prefer the development dyld_shared cache if both are present.
2733 if (!dsc_filespec.Exists())
Greg Clayton946f8902012-09-05 22:30:51 +00002734 {
Jason Molenda649a6072015-11-10 05:21:54 +00002735 if (dsc_development_filespec.Exists())
2736 {
2737 dsc_filespec = dsc_development_filespec;
2738 }
2739 else
2740 {
2741 dsc_filespec = dsc_nondevelopment_filespec;
2742 }
2743 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002744
Jason Molendaf8130862012-06-22 03:28:35 +00002745 /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
2746 The dyld_cache_local_symbols_info structure gives us three things:
2747 1. The start and count of the nlist records in the dyld_shared_cache file
2748 2. The start and size of the strings for these nlist records
2749 3. The start and count of dyld_cache_local_symbols_entry entries
2750
2751 There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
2752 The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
Jason Molenda4e7511e2013-03-06 23:19:17 +00002753 The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
Jason Molendaf8130862012-06-22 03:28:35 +00002754 and the count of how many nlist records there are for this dylib/framework.
2755 */
2756
Jason Molenda649a6072015-11-10 05:21:54 +00002757 // Process the dyld shared cache header to find the unmapped symbols
Jason Molendaa5609c82012-06-21 01:51:02 +00002758
Jason Molenda649a6072015-11-10 05:21:54 +00002759 DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
2760 if (!dsc_uuid.IsValid())
2761 {
2762 dsc_uuid = GetSharedCacheUUID (dsc_filespec, byte_order, addr_byte_size);
2763 }
Jason Molenda255f9bb2013-03-06 23:17:36 +00002764 if (dsc_data_sp)
Jason Molendaa5609c82012-06-21 01:51:02 +00002765 {
Jason Molenda649a6072015-11-10 05:21:54 +00002766 DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size);
Jason Molenda0e0954c2013-04-16 06:24:42 +00002767
2768 bool uuid_match = true;
2769 if (dsc_uuid.IsValid() && process)
2770 {
Jason Molenda649a6072015-11-10 05:21:54 +00002771 if (process_shared_cache_uuid.IsValid() && dsc_uuid != process_shared_cache_uuid)
Jason Molenda0e0954c2013-04-16 06:24:42 +00002772 {
2773 // The on-disk dyld_shared_cache file is not the same as the one in this
2774 // process' memory, don't use it.
2775 uuid_match = false;
Jason Molendac9cb7d22013-04-16 21:42:58 +00002776 ModuleSP module_sp (GetModule());
2777 if (module_sp)
2778 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 +00002779 }
2780 }
2781
Jason Molenda4e7511e2013-03-06 23:19:17 +00002782 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);
Jason Molenda255f9bb2013-03-06 23:17:36 +00002783
Jason Molendaa5609c82012-06-21 01:51:02 +00002784 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
2785
2786 // If the mappingOffset points to a location inside the header, we've
2787 // opened an old dyld shared cache, and should not proceed further.
Jason Molenda649a6072015-11-10 05:21:54 +00002788 if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1))
Jason Molendaa5609c82012-06-21 01:51:02 +00002789 {
2790
Greg Clayton736888c2015-02-23 23:47:09 +00002791 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 +00002792 DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
2793 offset = 0;
2794
2795 // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
2796 // in the shared library cache need to be adjusted by an offset to match up with the
2797 // dylibOffset identifying field in the dyld_cache_local_symbol_entry's. This offset is
2798 // recorded in mapping_offset_value.
2799 const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
2800
2801 offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
Jason Molendaa5609c82012-06-21 01:51:02 +00002802 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
2803 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
2804
Jason Molenda4e7511e2013-03-06 23:19:17 +00002805 if (localSymbolsOffset && localSymbolsSize)
Jason Molendaa5609c82012-06-21 01:51:02 +00002806 {
2807 // Map the local symbols
Greg Clayton736888c2015-02-23 23:47:09 +00002808 if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(localSymbolsOffset, localSymbolsSize))
Jason Molendaa5609c82012-06-21 01:51:02 +00002809 {
Greg Claytonc7bece562013-01-25 18:06:21 +00002810 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
Jason Molendaa5609c82012-06-21 01:51:02 +00002811
2812 offset = 0;
2813
Greg Claytonb65c6292015-02-20 22:20:05 +00002814 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
2815 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
2816 UndefinedNameToDescMap undefined_name_to_desc;
2817 SymbolIndexToName reexport_shlib_needs_fixup;
2818
2819
Jason Molendaa5609c82012-06-21 01:51:02 +00002820 // Read the local_symbols_infos struct in one shot
2821 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
2822 dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
2823
Jason Molendaa5609c82012-06-21 01:51:02 +00002824 SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
2825
Jason Molenda255f9bb2013-03-06 23:17:36 +00002826 uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00002827
2828 offset = local_symbols_info.entriesOffset;
2829 for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
2830 {
2831 struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
2832 local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
2833 local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
2834 local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
2835
Jason Molenda4e7511e2013-03-06 23:19:17 +00002836 if (header_file_offset == local_symbols_entry.dylibOffset)
Jason Molendaa5609c82012-06-21 01:51:02 +00002837 {
2838 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
2839
2840 // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
2841 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
2842 num_syms = symtab->GetNumSymbols();
2843
2844 nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
2845 uint32_t string_table_offset = local_symbols_info.stringsOffset;
2846
Jason Molenda4e7511e2013-03-06 23:19:17 +00002847 for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
Jason Molendaa5609c82012-06-21 01:51:02 +00002848 {
2849 /////////////////////////////
2850 {
2851 struct nlist_64 nlist;
2852 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2853 break;
2854
2855 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
2856 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2857 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
2858 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
2859 nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
2860
2861 SymbolType type = eSymbolTypeInvalid;
2862 const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
2863
2864 if (symbol_name == NULL)
2865 {
2866 // No symbol should be NULL, even the symbols with no
2867 // string values should have an offset zero which points
2868 // to an empty C-string
2869 Host::SystemLog (Host::eSystemLogError,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002870 "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 +00002871 entry_index,
2872 nlist.n_strx,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00002873 module_sp->GetFileSpec().GetPath().c_str());
Jason Molendaa5609c82012-06-21 01:51:02 +00002874 continue;
2875 }
2876 if (symbol_name[0] == '\0')
2877 symbol_name = NULL;
2878
2879 const char *symbol_name_non_abi_mangled = NULL;
2880
2881 SectionSP symbol_section;
2882 uint32_t symbol_byte_size = 0;
2883 bool add_nlist = true;
Charles Davis510938e2013-08-27 05:04:57 +00002884 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Clayton3d51b9f2012-11-27 01:52:16 +00002885 bool demangled_is_synthesized = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00002886 bool is_gsym = false;
Greg Clayton60038be2015-02-14 00:51:13 +00002887 bool set_value = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00002888
2889 assert (sym_idx < num_syms);
2890
2891 sym[sym_idx].SetDebug (is_debug);
2892
2893 if (is_debug)
2894 {
2895 switch (nlist.n_type)
2896 {
Charles Davis510938e2013-08-27 05:04:57 +00002897 case N_GSYM:
2898 // global symbol: name,,NO_SECT,type,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002899 // Sometimes the N_GSYM value contains the address.
2900
2901 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
2902 // have the same address, but we want to ensure that we always find only the real symbol,
2903 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
2904 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
2905 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
2906 // same address.
2907
Greg Clayton1e28adf2015-02-25 17:25:02 +00002908 is_gsym = true;
2909 sym[sym_idx].SetExternal(true);
2910
2911 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
2912 {
2913 llvm::StringRef symbol_name_ref(symbol_name);
2914 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
2915 {
2916 symbol_name_non_abi_mangled = symbol_name + 1;
2917 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2918 type = eSymbolTypeObjCClass;
2919 demangled_is_synthesized = true;
2920
2921 }
2922 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
2923 {
2924 symbol_name_non_abi_mangled = symbol_name + 1;
2925 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2926 type = eSymbolTypeObjCMetaClass;
2927 demangled_is_synthesized = true;
2928 }
2929 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
2930 {
2931 symbol_name_non_abi_mangled = symbol_name + 1;
2932 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2933 type = eSymbolTypeObjCIVar;
2934 demangled_is_synthesized = true;
2935 }
2936 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002937 else
2938 {
Jason Molendaa5609c82012-06-21 01:51:02 +00002939 if (nlist.n_value != 0)
2940 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2941 type = eSymbolTypeData;
2942 }
2943 break;
2944
Charles Davis510938e2013-08-27 05:04:57 +00002945 case N_FNAME:
2946 // procedure name (f77 kludge): name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00002947 type = eSymbolTypeCompiler;
2948 break;
2949
Charles Davis510938e2013-08-27 05:04:57 +00002950 case N_FUN:
2951 // procedure: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002952 if (symbol_name)
2953 {
2954 type = eSymbolTypeCode;
2955 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2956
Greg Claytond81088c2014-01-16 01:38:29 +00002957 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002958 // We use the current number of symbols in the symbol table in lieu of
2959 // using nlist_idx in case we ever start trimming entries out
2960 N_FUN_indexes.push_back(sym_idx);
2961 }
2962 else
2963 {
2964 type = eSymbolTypeCompiler;
2965
2966 if ( !N_FUN_indexes.empty() )
2967 {
2968 // Copy the size of the function into the original STAB entry so we don't have
2969 // to hunt for it later
2970 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
2971 N_FUN_indexes.pop_back();
2972 // We don't really need the end function STAB as it contains the size which
2973 // we already placed with the original symbol, so don't add it if we want a
2974 // minimal symbol table
Greg Clayton3046e662013-07-10 01:23:25 +00002975 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00002976 }
2977 }
2978 break;
2979
Charles Davis510938e2013-08-27 05:04:57 +00002980 case N_STSYM:
2981 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00002982 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Jason Molendaa5609c82012-06-21 01:51:02 +00002983 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Jason Molenda649a6072015-11-10 05:21:54 +00002984 if (symbol_name && symbol_name[0])
2985 {
2986 type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, eSymbolTypeData);
2987 }
Jason Molendaa5609c82012-06-21 01:51:02 +00002988 break;
2989
Charles Davis510938e2013-08-27 05:04:57 +00002990 case N_LCSYM:
2991 // .lcomm symbol: name,,n_sect,type,address
Jason Molendaa5609c82012-06-21 01:51:02 +00002992 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2993 type = eSymbolTypeCommonBlock;
2994 break;
2995
Charles Davis510938e2013-08-27 05:04:57 +00002996 case N_BNSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00002997 // We use the current number of symbols in the symbol table in lieu of
2998 // using nlist_idx in case we ever start trimming entries out
Greg Clayton3046e662013-07-10 01:23:25 +00002999 // Skip these if we want minimal symbol tables
3000 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00003001 break;
3002
Charles Davis510938e2013-08-27 05:04:57 +00003003 case N_ENSYM:
Jason Molendaa5609c82012-06-21 01:51:02 +00003004 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
3005 // so that we can always skip the entire symbol if we need to navigate
3006 // more quickly at the source level when parsing STABS
Greg Clayton3046e662013-07-10 01:23:25 +00003007 // Skip these if we want minimal symbol tables
3008 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00003009 break;
3010
Charles Davis510938e2013-08-27 05:04:57 +00003011 case N_OPT:
3012 // emitted with gcc2_compiled and in gcc source
Jason Molendaa5609c82012-06-21 01:51:02 +00003013 type = eSymbolTypeCompiler;
3014 break;
3015
Charles Davis510938e2013-08-27 05:04:57 +00003016 case N_RSYM:
3017 // register sym: name,,NO_SECT,type,register
Jason Molendaa5609c82012-06-21 01:51:02 +00003018 type = eSymbolTypeVariable;
3019 break;
3020
Charles Davis510938e2013-08-27 05:04:57 +00003021 case N_SLINE:
3022 // src line: 0,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003023 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3024 type = eSymbolTypeLineEntry;
3025 break;
3026
Charles Davis510938e2013-08-27 05:04:57 +00003027 case N_SSYM:
3028 // structure elt: name,,NO_SECT,type,struct_offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003029 type = eSymbolTypeVariableType;
3030 break;
3031
Charles Davis510938e2013-08-27 05:04:57 +00003032 case N_SO:
3033 // source file name
Jason Molendaa5609c82012-06-21 01:51:02 +00003034 type = eSymbolTypeSourceFile;
3035 if (symbol_name == NULL)
3036 {
Greg Clayton3046e662013-07-10 01:23:25 +00003037 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00003038 if (N_SO_index != UINT32_MAX)
3039 {
3040 // Set the size of the N_SO to the terminating index of this N_SO
3041 // so that we can always skip the entire N_SO if we need to navigate
3042 // more quickly at the source level when parsing STABS
3043 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
Greg Clayton3046e662013-07-10 01:23:25 +00003044 symbol_ptr->SetByteSize(sym_idx);
Jason Molendaa5609c82012-06-21 01:51:02 +00003045 symbol_ptr->SetSizeIsSibling(true);
3046 }
3047 N_NSYM_indexes.clear();
3048 N_INCL_indexes.clear();
3049 N_BRAC_indexes.clear();
3050 N_COMM_indexes.clear();
3051 N_FUN_indexes.clear();
3052 N_SO_index = UINT32_MAX;
3053 }
3054 else
3055 {
3056 // We use the current number of symbols in the symbol table in lieu of
3057 // using nlist_idx in case we ever start trimming entries out
3058 const bool N_SO_has_full_path = symbol_name[0] == '/';
3059 if (N_SO_has_full_path)
3060 {
Greg Clayton3046e662013-07-10 01:23:25 +00003061 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00003062 {
3063 // We have two consecutive N_SO entries where the first contains a directory
3064 // and the second contains a full path.
Jason Molendad9d5cf52012-07-20 03:35:44 +00003065 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00003066 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3067 add_nlist = false;
3068 }
3069 else
3070 {
3071 // This is the first entry in a N_SO that contains a directory or
3072 // a full path to the source file
3073 N_SO_index = sym_idx;
3074 }
3075 }
Greg Clayton3046e662013-07-10 01:23:25 +00003076 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Jason Molendaa5609c82012-06-21 01:51:02 +00003077 {
3078 // This is usually the second N_SO entry that contains just the filename,
3079 // so here we combine it with the first one if we are minimizing the symbol table
3080 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
3081 if (so_path && so_path[0])
3082 {
3083 std::string full_so_path (so_path);
Greg Clayton0662d962012-09-07 20:29:13 +00003084 const size_t double_slash_pos = full_so_path.find("//");
3085 if (double_slash_pos != std::string::npos)
3086 {
3087 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003088 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Clayton0662d962012-09-07 20:29:13 +00003089 // and the second is the directory for the source file so you end up with
3090 // a path that looks like "/tmp/src//tmp/src/"
3091 FileSpec so_dir(so_path, false);
3092 if (!so_dir.Exists())
3093 {
3094 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3095 if (so_dir.Exists())
3096 {
3097 // Trim off the incorrect path
3098 full_so_path.erase(0, double_slash_pos + 1);
3099 }
3100 }
3101 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003102 if (*full_so_path.rbegin() != '/')
3103 full_so_path += '/';
3104 full_so_path += symbol_name;
Jason Molendad9d5cf52012-07-20 03:35:44 +00003105 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Jason Molendaa5609c82012-06-21 01:51:02 +00003106 add_nlist = false;
3107 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3108 }
3109 }
Greg Clayton946f8902012-09-05 22:30:51 +00003110 else
3111 {
3112 // This could be a relative path to a N_SO
3113 N_SO_index = sym_idx;
3114 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003115 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003116 break;
3117
Charles Davis510938e2013-08-27 05:04:57 +00003118 case N_OSO:
3119 // object file name: name,,0,0,st_mtime
Jason Molendaa5609c82012-06-21 01:51:02 +00003120 type = eSymbolTypeObjectFile;
3121 break;
3122
Charles Davis510938e2013-08-27 05:04:57 +00003123 case N_LSYM:
3124 // local sym: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003125 type = eSymbolTypeLocal;
3126 break;
3127
3128 //----------------------------------------------------------------------
3129 // INCL scopes
3130 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003131 case N_BINCL:
3132 // include file beginning: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003133 // We use the current number of symbols in the symbol table in lieu of
3134 // using nlist_idx in case we ever start trimming entries out
3135 N_INCL_indexes.push_back(sym_idx);
3136 type = eSymbolTypeScopeBegin;
3137 break;
3138
Charles Davis510938e2013-08-27 05:04:57 +00003139 case N_EINCL:
3140 // include file end: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003141 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3142 // so that we can always skip the entire symbol if we need to navigate
3143 // more quickly at the source level when parsing STABS
3144 if ( !N_INCL_indexes.empty() )
3145 {
3146 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
3147 symbol_ptr->SetByteSize(sym_idx + 1);
3148 symbol_ptr->SetSizeIsSibling(true);
3149 N_INCL_indexes.pop_back();
3150 }
3151 type = eSymbolTypeScopeEnd;
3152 break;
3153
Charles Davis510938e2013-08-27 05:04:57 +00003154 case N_SOL:
3155 // #included file name: name,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003156 type = eSymbolTypeHeaderFile;
3157
3158 // We currently don't use the header files on darwin
Greg Clayton3046e662013-07-10 01:23:25 +00003159 add_nlist = false;
Jason Molendaa5609c82012-06-21 01:51:02 +00003160 break;
3161
Charles Davis510938e2013-08-27 05:04:57 +00003162 case N_PARAMS:
3163 // compiler parameters: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003164 type = eSymbolTypeCompiler;
3165 break;
3166
Charles Davis510938e2013-08-27 05:04:57 +00003167 case N_VERSION:
3168 // compiler version: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003169 type = eSymbolTypeCompiler;
3170 break;
3171
Charles Davis510938e2013-08-27 05:04:57 +00003172 case N_OLEVEL:
3173 // compiler -O level: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003174 type = eSymbolTypeCompiler;
3175 break;
3176
Charles Davis510938e2013-08-27 05:04:57 +00003177 case N_PSYM:
3178 // parameter: name,,NO_SECT,type,offset
Jason Molendaa5609c82012-06-21 01:51:02 +00003179 type = eSymbolTypeVariable;
3180 break;
3181
Charles Davis510938e2013-08-27 05:04:57 +00003182 case N_ENTRY:
3183 // alternate entry: name,,n_sect,linenumber,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003184 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3185 type = eSymbolTypeLineEntry;
3186 break;
3187
3188 //----------------------------------------------------------------------
3189 // Left and Right Braces
3190 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003191 case N_LBRAC:
3192 // left bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003193 // We use the current number of symbols in the symbol table in lieu of
3194 // using nlist_idx in case we ever start trimming entries out
3195 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3196 N_BRAC_indexes.push_back(sym_idx);
3197 type = eSymbolTypeScopeBegin;
3198 break;
3199
Charles Davis510938e2013-08-27 05:04:57 +00003200 case N_RBRAC:
3201 // right bracket: 0,,NO_SECT,nesting level,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003202 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
3203 // so that we can always skip the entire symbol if we need to navigate
3204 // more quickly at the source level when parsing STABS
3205 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3206 if ( !N_BRAC_indexes.empty() )
3207 {
3208 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
3209 symbol_ptr->SetByteSize(sym_idx + 1);
3210 symbol_ptr->SetSizeIsSibling(true);
3211 N_BRAC_indexes.pop_back();
3212 }
3213 type = eSymbolTypeScopeEnd;
3214 break;
3215
Charles Davis510938e2013-08-27 05:04:57 +00003216 case N_EXCL:
3217 // deleted include file: name,,NO_SECT,0,sum
Jason Molendaa5609c82012-06-21 01:51:02 +00003218 type = eSymbolTypeHeaderFile;
3219 break;
3220
3221 //----------------------------------------------------------------------
3222 // COMM scopes
3223 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003224 case N_BCOMM:
3225 // begin common: name,,NO_SECT,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003226 // We use the current number of symbols in the symbol table in lieu of
3227 // using nlist_idx in case we ever start trimming entries out
3228 type = eSymbolTypeScopeBegin;
3229 N_COMM_indexes.push_back(sym_idx);
3230 break;
3231
Charles Davis510938e2013-08-27 05:04:57 +00003232 case N_ECOML:
3233 // end common (local name): 0,,n_sect,0,address
Jason Molendaa5609c82012-06-21 01:51:02 +00003234 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3235 // Fall through
3236
Charles Davis510938e2013-08-27 05:04:57 +00003237 case N_ECOMM:
3238 // end common: name,,n_sect,0,0
Jason Molendaa5609c82012-06-21 01:51:02 +00003239 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
3240 // so that we can always skip the entire symbol if we need to navigate
3241 // more quickly at the source level when parsing STABS
3242 if ( !N_COMM_indexes.empty() )
3243 {
3244 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
3245 symbol_ptr->SetByteSize(sym_idx + 1);
3246 symbol_ptr->SetSizeIsSibling(true);
3247 N_COMM_indexes.pop_back();
3248 }
3249 type = eSymbolTypeScopeEnd;
3250 break;
3251
Charles Davis510938e2013-08-27 05:04:57 +00003252 case N_LENG:
3253 // second stab entry with length information
Jason Molendaa5609c82012-06-21 01:51:02 +00003254 type = eSymbolTypeAdditional;
3255 break;
3256
3257 default: break;
3258 }
3259 }
3260 else
3261 {
Charles Davis510938e2013-08-27 05:04:57 +00003262 //uint8_t n_pext = N_PEXT & nlist.n_type;
3263 uint8_t n_type = N_TYPE & nlist.n_type;
3264 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Jason Molendaa5609c82012-06-21 01:51:02 +00003265
3266 switch (n_type)
3267 {
Greg Clayton60038be2015-02-14 00:51:13 +00003268 case N_INDR:
3269 {
3270 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
3271 if (reexport_name_cstr && reexport_name_cstr[0])
3272 {
3273 type = eSymbolTypeReExported;
3274 ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
3275 sym[sym_idx].SetReExportedSymbolName(reexport_name);
3276 set_value = false;
3277 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
3278 indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
3279 }
3280 else
3281 type = eSymbolTypeUndefined;
3282 }
3283 break;
3284
Charles Davis510938e2013-08-27 05:04:57 +00003285 case N_UNDF:
Greg Clayton786ad182015-03-03 01:40:46 +00003286 if (symbol_name && symbol_name[0])
Greg Clayton60038be2015-02-14 00:51:13 +00003287 {
3288 ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
3289 undefined_name_to_desc[undefined_name] = nlist.n_desc;
3290 }
3291 // Fall through
3292 case N_PBUD:
Jason Molendaa5609c82012-06-21 01:51:02 +00003293 type = eSymbolTypeUndefined;
3294 break;
3295
Charles Davis510938e2013-08-27 05:04:57 +00003296 case N_ABS:
Jason Molendaa5609c82012-06-21 01:51:02 +00003297 type = eSymbolTypeAbsolute;
3298 break;
3299
Charles Davis510938e2013-08-27 05:04:57 +00003300 case N_SECT:
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003301 {
3302 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Jason Molendaa5609c82012-06-21 01:51:02 +00003303
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003304 if (symbol_section == NULL)
Jason Molendaa5609c82012-06-21 01:51:02 +00003305 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003306 // TODO: warn about this?
3307 add_nlist = false;
3308 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003309 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003310
3311 if (TEXT_eh_frame_sectID == nlist.n_sect)
Jason Molendaa5609c82012-06-21 01:51:02 +00003312 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003313 type = eSymbolTypeException;
3314 }
3315 else
3316 {
Charles Davis510938e2013-08-27 05:04:57 +00003317 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003318
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003319 switch (section_type)
Jason Molendaa5609c82012-06-21 01:51:02 +00003320 {
Charles Davis510938e2013-08-27 05:04:57 +00003321 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
3322 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
3323 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
3324 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
3325 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
3326 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
3327 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
3328 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
3329 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00003330 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
3331 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
3332 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
3333 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00003334 default:
3335 switch (symbol_section->GetType())
3336 {
3337 case lldb::eSectionTypeCode:
3338 type = eSymbolTypeCode;
3339 break;
3340 case eSectionTypeData:
3341 case eSectionTypeDataCString: // Inlined C string data
3342 case eSectionTypeDataCStringPointers: // Pointers to C string data
3343 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
3344 case eSectionTypeData4:
3345 case eSectionTypeData8:
3346 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00003347 type = eSymbolTypeData;
3348 break;
3349 default:
3350 break;
3351 }
3352 break;
Jason Molendaa5609c82012-06-21 01:51:02 +00003353 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003354
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003355 if (type == eSymbolTypeInvalid)
3356 {
3357 const char *symbol_sect_name = symbol_section->GetName().AsCString();
3358 if (symbol_section->IsDescendant (text_section_sp.get()))
3359 {
Charles Davis510938e2013-08-27 05:04:57 +00003360 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
3361 S_ATTR_SELF_MODIFYING_CODE |
3362 S_ATTR_SOME_INSTRUCTIONS))
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003363 type = eSymbolTypeData;
3364 else
3365 type = eSymbolTypeCode;
3366 }
Greg Claytona381e102015-07-27 23:21:05 +00003367 else if (symbol_section->IsDescendant(data_section_sp.get()) ||
3368 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
3369 symbol_section->IsDescendant(data_const_section_sp.get()))
Jason Molendaa5609c82012-06-21 01:51:02 +00003370 {
3371 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
3372 {
3373 type = eSymbolTypeRuntime;
Jason Molenda649a6072015-11-10 05:21:54 +00003374
3375 if (symbol_name)
Jason Molendaa5609c82012-06-21 01:51:02 +00003376 {
3377 llvm::StringRef symbol_name_ref(symbol_name);
Jason Molenda649a6072015-11-10 05:21:54 +00003378 if (symbol_name_ref.startswith("_OBJC_"))
Jason Molendaa5609c82012-06-21 01:51:02 +00003379 {
Jason Molenda649a6072015-11-10 05:21:54 +00003380 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
3381 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
3382 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
3383 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3384 {
3385 symbol_name_non_abi_mangled = symbol_name + 1;
3386 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3387 type = eSymbolTypeObjCClass;
3388 demangled_is_synthesized = true;
3389 }
3390 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3391 {
3392 symbol_name_non_abi_mangled = symbol_name + 1;
3393 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3394 type = eSymbolTypeObjCMetaClass;
3395 demangled_is_synthesized = true;
3396 }
3397 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3398 {
3399 symbol_name_non_abi_mangled = symbol_name + 1;
3400 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3401 type = eSymbolTypeObjCIVar;
3402 demangled_is_synthesized = true;
3403 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003404 }
3405 }
3406 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003407 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
Jason Molendaa5609c82012-06-21 01:51:02 +00003408 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003409 type = eSymbolTypeException;
Jason Molendaa5609c82012-06-21 01:51:02 +00003410 }
3411 else
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003412 {
3413 type = eSymbolTypeData;
3414 }
3415 }
3416 else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
3417 {
3418 type = eSymbolTypeTrampoline;
3419 }
3420 else if (symbol_section->IsDescendant(objc_section_sp.get()))
3421 {
3422 type = eSymbolTypeRuntime;
3423 if (symbol_name && symbol_name[0] == '.')
3424 {
3425 llvm::StringRef symbol_name_ref(symbol_name);
3426 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
3427 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
Jason Molendaa5609c82012-06-21 01:51:02 +00003428 {
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003429 symbol_name_non_abi_mangled = symbol_name;
3430 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
3431 type = eSymbolTypeObjCClass;
3432 demangled_is_synthesized = true;
Jason Molendaa5609c82012-06-21 01:51:02 +00003433 }
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003434 }
3435 }
3436 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003437 }
3438 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003439 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003440 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003441 }
3442
3443 if (add_nlist)
3444 {
3445 uint64_t symbol_value = nlist.n_value;
Jason Molendaa5609c82012-06-21 01:51:02 +00003446 if (symbol_name_non_abi_mangled)
3447 {
Jason Molendad9d5cf52012-07-20 03:35:44 +00003448 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
3449 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Jason Molendaa5609c82012-06-21 01:51:02 +00003450 }
3451 else
3452 {
Greg Clayton3046e662013-07-10 01:23:25 +00003453 bool symbol_name_is_mangled = false;
3454
Jason Molendaa5609c82012-06-21 01:51:02 +00003455 if (symbol_name && symbol_name[0] == '_')
3456 {
3457 symbol_name_is_mangled = symbol_name[1] == '_';
3458 symbol_name++; // Skip the leading underscore
3459 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003460
Jason Molendaa5609c82012-06-21 01:51:02 +00003461 if (symbol_name)
3462 {
Greg Claytondacc4a92013-05-14 22:19:37 +00003463 ConstString const_symbol_name(symbol_name);
Greg Claytondacc4a92013-05-14 22:19:37 +00003464 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Clayton3046e662013-07-10 01:23:25 +00003465 if (is_gsym && is_debug)
Greg Clayton14cd13c2015-07-01 23:29:06 +00003466 {
3467 const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
3468 if (gsym_name)
3469 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
3470 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003471 }
3472 }
3473 if (symbol_section)
3474 {
3475 const addr_t section_file_addr = symbol_section->GetFileAddress();
3476 if (symbol_byte_size == 0 && function_starts_count > 0)
3477 {
3478 addr_t symbol_lookup_file_addr = nlist.n_value;
3479 // Do an exact address match for non-ARM addresses, else get the closest since
3480 // the symbol might be a thumb symbol which has an address with bit zero set
3481 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
3482 if (is_arm && func_start_entry)
3483 {
3484 // Verify that the function start address is the symbol address (ARM)
3485 // or the symbol address + 1 (thumb)
3486 if (func_start_entry->addr != symbol_lookup_file_addr &&
3487 func_start_entry->addr != (symbol_lookup_file_addr + 1))
3488 {
3489 // Not the right entry, NULL it out...
3490 func_start_entry = NULL;
3491 }
3492 }
3493 if (func_start_entry)
3494 {
3495 func_start_entry->data = true;
Jason Molenda4e7511e2013-03-06 23:19:17 +00003496
Jason Molendaa5609c82012-06-21 01:51:02 +00003497 addr_t symbol_file_addr = func_start_entry->addr;
3498 uint32_t symbol_flags = 0;
3499 if (is_arm)
3500 {
3501 if (symbol_file_addr & 1)
3502 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Greg Claytonb887da12015-07-16 19:50:57 +00003503 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Jason Molendaa5609c82012-06-21 01:51:02 +00003504 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003505
Jason Molendaa5609c82012-06-21 01:51:02 +00003506 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3507 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3508 if (next_func_start_entry)
3509 {
3510 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3511 // Be sure the clear the Thumb address bit when we calculate the size
3512 // from the current and next address
3513 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00003514 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Jason Molendaa5609c82012-06-21 01:51:02 +00003515 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
3516 }
3517 else
3518 {
3519 symbol_byte_size = section_end_file_addr - symbol_file_addr;
3520 }
3521 }
3522 }
3523 symbol_value -= section_file_addr;
3524 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003525
Greg Claytondacc4a92013-05-14 22:19:37 +00003526 if (is_debug == false)
3527 {
3528 if (type == eSymbolTypeCode)
3529 {
3530 // See if we can find a N_FUN entry for any code symbols.
3531 // If we do find a match, and the name matches, then we
3532 // can merge the two into just the function symbol to avoid
3533 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003534 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3535 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
3536 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003537 {
Greg Claytond81088c2014-01-16 01:38:29 +00003538 bool found_it = false;
3539 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003540 {
Greg Claytond81088c2014-01-16 01:38:29 +00003541 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3542 {
3543 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3544 // We just need the flags from the linker symbol, so put these flags
3545 // into the N_FUN flags to avoid duplicate symbols in the symbol table
3546 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3547 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3548 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
3549 sym[pos->second].SetType (eSymbolTypeResolver);
3550 sym[sym_idx].Clear();
3551 found_it = true;
3552 break;
3553 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003554 }
Greg Claytond81088c2014-01-16 01:38:29 +00003555 if (found_it)
3556 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003557 }
Jim Inghamea3ac272014-01-10 22:55:37 +00003558 else
3559 {
Greg Claytond81088c2014-01-16 01:38:29 +00003560 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00003561 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00003562 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003563 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00003564 else if (type == eSymbolTypeData ||
3565 type == eSymbolTypeObjCClass ||
3566 type == eSymbolTypeObjCMetaClass ||
3567 type == eSymbolTypeObjCIVar )
Greg Claytondacc4a92013-05-14 22:19:37 +00003568 {
3569 // See if we can find a N_STSYM entry for any data symbols.
3570 // If we do find a match, and the name matches, then we
3571 // can merge the two into just the Static symbol to avoid
3572 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00003573 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
3574 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
3575 if (range.first != range.second)
Greg Claytondacc4a92013-05-14 22:19:37 +00003576 {
Greg Claytond81088c2014-01-16 01:38:29 +00003577 bool found_it = false;
3578 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytondacc4a92013-05-14 22:19:37 +00003579 {
Greg Claytond81088c2014-01-16 01:38:29 +00003580 if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
3581 {
3582 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
3583 // We just need the flags from the linker symbol, so put these flags
3584 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
3585 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
3586 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3587 sym[sym_idx].Clear();
3588 found_it = true;
3589 break;
3590 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003591 }
Greg Claytond81088c2014-01-16 01:38:29 +00003592 if (found_it)
3593 continue;
Greg Claytondacc4a92013-05-14 22:19:37 +00003594 }
3595 else
3596 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00003597 const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
3598 if (gsym_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003599 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00003600 // Combine N_GSYM stab entries with the non stab symbol
3601 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
3602 if (pos != N_GSYM_name_to_sym_idx.end())
3603 {
3604 const uint32_t GSYM_sym_idx = pos->second;
3605 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
3606 // Copy the address, because often the N_GSYM address has an invalid address of zero
3607 // when the global is a common symbol
3608 sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
3609 sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
3610 // We just need the flags from the linker symbol, so put these flags
3611 // into the N_GSYM flags to avoid duplicate symbols in the symbol table
3612 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3613 sym[sym_idx].Clear();
3614 continue;
3615 }
Greg Claytondacc4a92013-05-14 22:19:37 +00003616 }
3617 }
3618 }
3619 }
3620
Jason Molendaa5609c82012-06-21 01:51:02 +00003621 sym[sym_idx].SetID (nlist_idx);
3622 sym[sym_idx].SetType (type);
Greg Clayton60038be2015-02-14 00:51:13 +00003623 if (set_value)
3624 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00003625 sym[sym_idx].GetAddressRef().SetSection (symbol_section);
3626 sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
Greg Clayton60038be2015-02-14 00:51:13 +00003627 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003628 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003629
Jason Molendaa5609c82012-06-21 01:51:02 +00003630 if (symbol_byte_size > 0)
3631 sym[sym_idx].SetByteSize(symbol_byte_size);
3632
Greg Clayton3d51b9f2012-11-27 01:52:16 +00003633 if (demangled_is_synthesized)
3634 sym[sym_idx].SetDemangledNameIsSynthesized(true);
Jason Molendaa5609c82012-06-21 01:51:02 +00003635 ++sym_idx;
3636 }
3637 else
3638 {
3639 sym[sym_idx].Clear();
3640 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003641
Jason Molendaa5609c82012-06-21 01:51:02 +00003642 }
3643 /////////////////////////////
3644 }
3645 break; // No more entries to consider
3646 }
3647 }
Greg Clayton60038be2015-02-14 00:51:13 +00003648
3649 for (const auto &pos :reexport_shlib_needs_fixup)
3650 {
3651 const auto undef_pos = undefined_name_to_desc.find(pos.second);
3652 if (undef_pos != undefined_name_to_desc.end())
3653 {
3654 const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
3655 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
3656 sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
3657 }
3658 }
Jason Molendaa5609c82012-06-21 01:51:02 +00003659 }
3660 }
3661 }
3662 }
3663 }
3664
3665 // Must reset this in case it was mutated above!
3666 nlist_data_offset = 0;
3667#endif
Jim Inghamea3ac272014-01-10 22:55:37 +00003668
Greg Claytonfd814c52013-08-13 01:42:25 +00003669 if (nlist_data.GetByteSize() > 0)
Jason Molendaa5609c82012-06-21 01:51:02 +00003670 {
Jason Molendaa5609c82012-06-21 01:51:02 +00003671
Greg Claytonfd814c52013-08-13 01:42:25 +00003672 // If the sym array was not created while parsing the DSC unmapped
3673 // symbols, create it now.
3674 if (sym == NULL)
Greg Clayton4c82d422012-05-18 23:20:01 +00003675 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003676 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
3677 num_syms = symtab->GetNumSymbols();
3678 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00003679
Greg Claytonfd814c52013-08-13 01:42:25 +00003680 if (unmapped_local_symbols_found)
3681 {
3682 assert(m_dysymtab.ilocalsym == 0);
3683 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
3684 nlist_idx = m_dysymtab.nlocalsym;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003685 }
Greg Claytondebb8812012-05-25 17:04:00 +00003686 else
3687 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003688 nlist_idx = 0;
Greg Claytondebb8812012-05-25 17:04:00 +00003689 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003690
Greg Clayton60038be2015-02-14 00:51:13 +00003691 typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
3692 typedef std::map<uint32_t, ConstString> SymbolIndexToName;
3693 UndefinedNameToDescMap undefined_name_to_desc;
3694 SymbolIndexToName reexport_shlib_needs_fixup;
Greg Claytonfd814c52013-08-13 01:42:25 +00003695 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003696 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003697 struct nlist_64 nlist;
3698 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
3699 break;
3700
3701 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
3702 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
3703 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
3704 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
3705 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
3706
3707 SymbolType type = eSymbolTypeInvalid;
3708 const char *symbol_name = NULL;
3709
3710 if (have_strtab_data)
Greg Clayton77ccca72011-12-30 00:32:24 +00003711 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003712 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
Jason Molenda4e7511e2013-03-06 23:19:17 +00003713
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003714 if (symbol_name == NULL)
3715 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003716 // No symbol should be NULL, even the symbols with no
3717 // string values should have an offset zero which points
3718 // to an empty C-string
3719 Host::SystemLog (Host::eSystemLogError,
3720 "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
3721 nlist_idx,
3722 nlist.n_strx,
3723 module_sp->GetFileSpec().GetPath().c_str());
3724 continue;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003725 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003726 if (symbol_name[0] == '\0')
3727 symbol_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003728 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003729 else
3730 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003731 const addr_t str_addr = strtab_addr + nlist.n_strx;
3732 Error str_error;
3733 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
3734 symbol_name = memory_symbol_name.c_str();
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003735 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003736 const char *symbol_name_non_abi_mangled = NULL;
3737
3738 SectionSP symbol_section;
3739 lldb::addr_t symbol_byte_size = 0;
3740 bool add_nlist = true;
3741 bool is_gsym = false;
Charles Davis510938e2013-08-27 05:04:57 +00003742 bool is_debug = ((nlist.n_type & N_STAB) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00003743 bool demangled_is_synthesized = false;
Greg Clayton60038be2015-02-14 00:51:13 +00003744 bool set_value = true;
Greg Claytonfd814c52013-08-13 01:42:25 +00003745 assert (sym_idx < num_syms);
3746
3747 sym[sym_idx].SetDebug (is_debug);
3748
3749 if (is_debug)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003750 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003751 switch (nlist.n_type)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003752 {
Charles Davis510938e2013-08-27 05:04:57 +00003753 case N_GSYM:
3754 // global symbol: name,,NO_SECT,type,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003755 // Sometimes the N_GSYM value contains the address.
Jason Molenda4e7511e2013-03-06 23:19:17 +00003756
Greg Claytonfd814c52013-08-13 01:42:25 +00003757 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
3758 // have the same address, but we want to ensure that we always find only the real symbol,
3759 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
3760 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
3761 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
3762 // same address.
Greg Clayton1e28adf2015-02-25 17:25:02 +00003763 is_gsym = true;
3764 sym[sym_idx].SetExternal(true);
Greg Clayton29e08cb2012-03-14 01:53:24 +00003765
Greg Clayton1e28adf2015-02-25 17:25:02 +00003766 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O')
3767 {
3768 llvm::StringRef symbol_name_ref(symbol_name);
3769 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
3770 {
3771 symbol_name_non_abi_mangled = symbol_name + 1;
3772 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
3773 type = eSymbolTypeObjCClass;
3774 demangled_is_synthesized = true;
3775
3776 }
3777 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
3778 {
3779 symbol_name_non_abi_mangled = symbol_name + 1;
3780 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
3781 type = eSymbolTypeObjCMetaClass;
3782 demangled_is_synthesized = true;
3783 }
3784 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
3785 {
3786 symbol_name_non_abi_mangled = symbol_name + 1;
3787 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
3788 type = eSymbolTypeObjCIVar;
3789 demangled_is_synthesized = true;
3790 }
3791 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003792 else
3793 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003794 if (nlist.n_value != 0)
3795 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3796 type = eSymbolTypeData;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003797 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003798 break;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00003799
Charles Davis510938e2013-08-27 05:04:57 +00003800 case N_FNAME:
3801 // procedure name (f77 kludge): name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003802 type = eSymbolTypeCompiler;
3803 break;
3804
Charles Davis510938e2013-08-27 05:04:57 +00003805 case N_FUN:
3806 // procedure: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003807 if (symbol_name)
Greg Claytondacc4a92013-05-14 22:19:37 +00003808 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003809 type = eSymbolTypeCode;
3810 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3811
Greg Claytond81088c2014-01-16 01:38:29 +00003812 N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003813 // We use the current number of symbols in the symbol table in lieu of
3814 // using nlist_idx in case we ever start trimming entries out
3815 N_FUN_indexes.push_back(sym_idx);
Greg Claytondacc4a92013-05-14 22:19:37 +00003816 }
3817 else
3818 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003819 type = eSymbolTypeCompiler;
3820
3821 if ( !N_FUN_indexes.empty() )
Greg Claytondacc4a92013-05-14 22:19:37 +00003822 {
Greg Claytonfd814c52013-08-13 01:42:25 +00003823 // Copy the size of the function into the original STAB entry so we don't have
3824 // to hunt for it later
3825 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
3826 N_FUN_indexes.pop_back();
3827 // We don't really need the end function STAB as it contains the size which
3828 // we already placed with the original symbol, so don't add it if we want a
3829 // minimal symbol table
3830 add_nlist = false;
Greg Claytondacc4a92013-05-14 22:19:37 +00003831 }
3832 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003833 break;
3834
Charles Davis510938e2013-08-27 05:04:57 +00003835 case N_STSYM:
3836 // static symbol: name,,n_sect,type,address
Greg Claytond81088c2014-01-16 01:38:29 +00003837 N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
Greg Claytonfd814c52013-08-13 01:42:25 +00003838 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Jason Molenda649a6072015-11-10 05:21:54 +00003839 if (symbol_name && symbol_name[0])
3840 {
3841 type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, eSymbolTypeData);
3842 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003843 break;
3844
Charles Davis510938e2013-08-27 05:04:57 +00003845 case N_LCSYM:
3846 // .lcomm symbol: name,,n_sect,type,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003847 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3848 type = eSymbolTypeCommonBlock;
3849 break;
3850
Charles Davis510938e2013-08-27 05:04:57 +00003851 case N_BNSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003852 // We use the current number of symbols in the symbol table in lieu of
3853 // using nlist_idx in case we ever start trimming entries out
3854 // Skip these if we want minimal symbol tables
3855 add_nlist = false;
3856 break;
3857
Charles Davis510938e2013-08-27 05:04:57 +00003858 case N_ENSYM:
Greg Claytonfd814c52013-08-13 01:42:25 +00003859 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
3860 // so that we can always skip the entire symbol if we need to navigate
3861 // more quickly at the source level when parsing STABS
3862 // Skip these if we want minimal symbol tables
3863 add_nlist = false;
3864 break;
3865
3866
Charles Davis510938e2013-08-27 05:04:57 +00003867 case N_OPT:
3868 // emitted with gcc2_compiled and in gcc source
Greg Claytonfd814c52013-08-13 01:42:25 +00003869 type = eSymbolTypeCompiler;
3870 break;
3871
Charles Davis510938e2013-08-27 05:04:57 +00003872 case N_RSYM:
3873 // register sym: name,,NO_SECT,type,register
Greg Claytonfd814c52013-08-13 01:42:25 +00003874 type = eSymbolTypeVariable;
3875 break;
3876
Charles Davis510938e2013-08-27 05:04:57 +00003877 case N_SLINE:
3878 // src line: 0,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00003879 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
3880 type = eSymbolTypeLineEntry;
3881 break;
3882
Charles Davis510938e2013-08-27 05:04:57 +00003883 case N_SSYM:
3884 // structure elt: name,,NO_SECT,type,struct_offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003885 type = eSymbolTypeVariableType;
3886 break;
3887
Charles Davis510938e2013-08-27 05:04:57 +00003888 case N_SO:
3889 // source file name
Greg Claytonfd814c52013-08-13 01:42:25 +00003890 type = eSymbolTypeSourceFile;
3891 if (symbol_name == NULL)
3892 {
3893 add_nlist = false;
3894 if (N_SO_index != UINT32_MAX)
3895 {
3896 // Set the size of the N_SO to the terminating index of this N_SO
3897 // so that we can always skip the entire N_SO if we need to navigate
3898 // more quickly at the source level when parsing STABS
3899 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
3900 symbol_ptr->SetByteSize(sym_idx);
3901 symbol_ptr->SetSizeIsSibling(true);
3902 }
3903 N_NSYM_indexes.clear();
3904 N_INCL_indexes.clear();
3905 N_BRAC_indexes.clear();
3906 N_COMM_indexes.clear();
3907 N_FUN_indexes.clear();
3908 N_SO_index = UINT32_MAX;
3909 }
3910 else
3911 {
3912 // We use the current number of symbols in the symbol table in lieu of
3913 // using nlist_idx in case we ever start trimming entries out
3914 const bool N_SO_has_full_path = symbol_name[0] == '/';
3915 if (N_SO_has_full_path)
3916 {
3917 if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3918 {
3919 // We have two consecutive N_SO entries where the first contains a directory
3920 // and the second contains a full path.
3921 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
3922 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3923 add_nlist = false;
3924 }
3925 else
3926 {
3927 // This is the first entry in a N_SO that contains a directory or
3928 // a full path to the source file
3929 N_SO_index = sym_idx;
3930 }
3931 }
3932 else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
3933 {
3934 // This is usually the second N_SO entry that contains just the filename,
3935 // so here we combine it with the first one if we are minimizing the symbol table
Greg Claytonddaf6a72015-07-08 22:32:23 +00003936 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString();
Greg Claytonfd814c52013-08-13 01:42:25 +00003937 if (so_path && so_path[0])
3938 {
3939 std::string full_so_path (so_path);
3940 const size_t double_slash_pos = full_so_path.find("//");
3941 if (double_slash_pos != std::string::npos)
3942 {
3943 // The linker has been generating bad N_SO entries with doubled up paths
Ashok Thirumurthi03520b72013-08-27 14:56:58 +00003944 // in the format "%s%s" where the first string in the DW_AT_comp_dir,
Greg Claytonfd814c52013-08-13 01:42:25 +00003945 // and the second is the directory for the source file so you end up with
3946 // a path that looks like "/tmp/src//tmp/src/"
3947 FileSpec so_dir(so_path, false);
3948 if (!so_dir.Exists())
3949 {
3950 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
3951 if (so_dir.Exists())
3952 {
3953 // Trim off the incorrect path
3954 full_so_path.erase(0, double_slash_pos + 1);
3955 }
3956 }
3957 }
3958 if (*full_so_path.rbegin() != '/')
3959 full_so_path += '/';
3960 full_so_path += symbol_name;
3961 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
3962 add_nlist = false;
3963 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
3964 }
3965 }
3966 else
3967 {
3968 // This could be a relative path to a N_SO
3969 N_SO_index = sym_idx;
3970 }
3971 }
Greg Claytonfd814c52013-08-13 01:42:25 +00003972 break;
3973
Charles Davis510938e2013-08-27 05:04:57 +00003974 case N_OSO:
3975 // object file name: name,,0,0,st_mtime
Greg Claytonfd814c52013-08-13 01:42:25 +00003976 type = eSymbolTypeObjectFile;
3977 break;
3978
Charles Davis510938e2013-08-27 05:04:57 +00003979 case N_LSYM:
3980 // local sym: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00003981 type = eSymbolTypeLocal;
3982 break;
3983
3984 //----------------------------------------------------------------------
3985 // INCL scopes
3986 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00003987 case N_BINCL:
3988 // include file beginning: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00003989 // We use the current number of symbols in the symbol table in lieu of
3990 // using nlist_idx in case we ever start trimming entries out
3991 N_INCL_indexes.push_back(sym_idx);
3992 type = eSymbolTypeScopeBegin;
3993 break;
3994
Charles Davis510938e2013-08-27 05:04:57 +00003995 case N_EINCL:
3996 // include file end: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00003997 // Set the size of the N_BINCL to the terminating index of this N_EINCL
3998 // so that we can always skip the entire symbol if we need to navigate
3999 // more quickly at the source level when parsing STABS
4000 if ( !N_INCL_indexes.empty() )
4001 {
4002 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
4003 symbol_ptr->SetByteSize(sym_idx + 1);
4004 symbol_ptr->SetSizeIsSibling(true);
4005 N_INCL_indexes.pop_back();
4006 }
4007 type = eSymbolTypeScopeEnd;
4008 break;
4009
Charles Davis510938e2013-08-27 05:04:57 +00004010 case N_SOL:
4011 // #included file name: name,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004012 type = eSymbolTypeHeaderFile;
4013
4014 // We currently don't use the header files on darwin
4015 add_nlist = false;
4016 break;
4017
Charles Davis510938e2013-08-27 05:04:57 +00004018 case N_PARAMS:
4019 // compiler parameters: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004020 type = eSymbolTypeCompiler;
4021 break;
4022
Charles Davis510938e2013-08-27 05:04:57 +00004023 case N_VERSION:
4024 // compiler version: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004025 type = eSymbolTypeCompiler;
4026 break;
4027
Charles Davis510938e2013-08-27 05:04:57 +00004028 case N_OLEVEL:
4029 // compiler -O level: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004030 type = eSymbolTypeCompiler;
4031 break;
4032
Charles Davis510938e2013-08-27 05:04:57 +00004033 case N_PSYM:
4034 // parameter: name,,NO_SECT,type,offset
Greg Claytonfd814c52013-08-13 01:42:25 +00004035 type = eSymbolTypeVariable;
4036 break;
4037
Charles Davis510938e2013-08-27 05:04:57 +00004038 case N_ENTRY:
4039 // alternate entry: name,,n_sect,linenumber,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004040 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4041 type = eSymbolTypeLineEntry;
4042 break;
4043
4044 //----------------------------------------------------------------------
4045 // Left and Right Braces
4046 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00004047 case N_LBRAC:
4048 // left bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004049 // We use the current number of symbols in the symbol table in lieu of
4050 // using nlist_idx in case we ever start trimming entries out
4051 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4052 N_BRAC_indexes.push_back(sym_idx);
4053 type = eSymbolTypeScopeBegin;
4054 break;
4055
Charles Davis510938e2013-08-27 05:04:57 +00004056 case N_RBRAC:
4057 // right bracket: 0,,NO_SECT,nesting level,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004058 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
4059 // so that we can always skip the entire symbol if we need to navigate
4060 // more quickly at the source level when parsing STABS
4061 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4062 if ( !N_BRAC_indexes.empty() )
4063 {
4064 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
4065 symbol_ptr->SetByteSize(sym_idx + 1);
4066 symbol_ptr->SetSizeIsSibling(true);
4067 N_BRAC_indexes.pop_back();
4068 }
4069 type = eSymbolTypeScopeEnd;
4070 break;
4071
Charles Davis510938e2013-08-27 05:04:57 +00004072 case N_EXCL:
4073 // deleted include file: name,,NO_SECT,0,sum
Greg Claytonfd814c52013-08-13 01:42:25 +00004074 type = eSymbolTypeHeaderFile;
4075 break;
4076
4077 //----------------------------------------------------------------------
4078 // COMM scopes
4079 //----------------------------------------------------------------------
Charles Davis510938e2013-08-27 05:04:57 +00004080 case N_BCOMM:
4081 // begin common: name,,NO_SECT,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004082 // We use the current number of symbols in the symbol table in lieu of
4083 // using nlist_idx in case we ever start trimming entries out
4084 type = eSymbolTypeScopeBegin;
4085 N_COMM_indexes.push_back(sym_idx);
4086 break;
4087
Charles Davis510938e2013-08-27 05:04:57 +00004088 case N_ECOML:
4089 // end common (local name): 0,,n_sect,0,address
Greg Claytonfd814c52013-08-13 01:42:25 +00004090 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4091 // Fall through
4092
Charles Davis510938e2013-08-27 05:04:57 +00004093 case N_ECOMM:
4094 // end common: name,,n_sect,0,0
Greg Claytonfd814c52013-08-13 01:42:25 +00004095 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
4096 // so that we can always skip the entire symbol if we need to navigate
4097 // more quickly at the source level when parsing STABS
4098 if ( !N_COMM_indexes.empty() )
4099 {
4100 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
4101 symbol_ptr->SetByteSize(sym_idx + 1);
4102 symbol_ptr->SetSizeIsSibling(true);
4103 N_COMM_indexes.pop_back();
4104 }
4105 type = eSymbolTypeScopeEnd;
4106 break;
4107
Charles Davis510938e2013-08-27 05:04:57 +00004108 case N_LENG:
4109 // second stab entry with length information
Greg Claytonfd814c52013-08-13 01:42:25 +00004110 type = eSymbolTypeAdditional;
4111 break;
4112
4113 default: break;
4114 }
4115 }
4116 else
4117 {
Charles Davis510938e2013-08-27 05:04:57 +00004118 //uint8_t n_pext = N_PEXT & nlist.n_type;
4119 uint8_t n_type = N_TYPE & nlist.n_type;
4120 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
Greg Claytonfd814c52013-08-13 01:42:25 +00004121
4122 switch (n_type)
4123 {
Greg Clayton60038be2015-02-14 00:51:13 +00004124 case N_INDR:
4125 {
4126 const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
4127 if (reexport_name_cstr && reexport_name_cstr[0])
4128 {
4129 type = eSymbolTypeReExported;
4130 ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
4131 sym[sym_idx].SetReExportedSymbolName(reexport_name);
4132 set_value = false;
4133 reexport_shlib_needs_fixup[sym_idx] = reexport_name;
4134 indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
4135 }
4136 else
4137 type = eSymbolTypeUndefined;
4138 }
4139 break;
4140
Charles Davis510938e2013-08-27 05:04:57 +00004141 case N_UNDF:
Greg Clayton786ad182015-03-03 01:40:46 +00004142 if (symbol_name && symbol_name[0])
Greg Clayton60038be2015-02-14 00:51:13 +00004143 {
4144 ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
4145 undefined_name_to_desc[undefined_name] = nlist.n_desc;
4146 }
4147 // Fall through
4148 case N_PBUD:
Greg Claytonfd814c52013-08-13 01:42:25 +00004149 type = eSymbolTypeUndefined;
4150 break;
4151
Charles Davis510938e2013-08-27 05:04:57 +00004152 case N_ABS:
Greg Claytonfd814c52013-08-13 01:42:25 +00004153 type = eSymbolTypeAbsolute;
4154 break;
4155
Charles Davis510938e2013-08-27 05:04:57 +00004156 case N_SECT:
Greg Claytonfd814c52013-08-13 01:42:25 +00004157 {
4158 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
4159
4160 if (!symbol_section)
4161 {
4162 // TODO: warn about this?
4163 add_nlist = false;
4164 break;
4165 }
4166
4167 if (TEXT_eh_frame_sectID == nlist.n_sect)
4168 {
4169 type = eSymbolTypeException;
4170 }
4171 else
4172 {
Charles Davis510938e2013-08-27 05:04:57 +00004173 uint32_t section_type = symbol_section->Get() & SECTION_TYPE;
Greg Claytonfd814c52013-08-13 01:42:25 +00004174
4175 switch (section_type)
4176 {
Charles Davis510938e2013-08-27 05:04:57 +00004177 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings
4178 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals
4179 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals
4180 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
4181 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
4182 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
4183 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
4184 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization
4185 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination
Charles Davis510938e2013-08-27 05:04:57 +00004186 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
4187 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals
4188 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break;
4189 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
Greg Clayton38f9cc42014-06-16 22:53:16 +00004190 default:
4191 switch (symbol_section->GetType())
4192 {
4193 case lldb::eSectionTypeCode:
4194 type = eSymbolTypeCode;
4195 break;
4196 case eSectionTypeData:
4197 case eSectionTypeDataCString: // Inlined C string data
4198 case eSectionTypeDataCStringPointers: // Pointers to C string data
4199 case eSectionTypeDataSymbolAddress: // Address of a symbol in the symbol table
4200 case eSectionTypeData4:
4201 case eSectionTypeData8:
4202 case eSectionTypeData16:
Greg Clayton38f9cc42014-06-16 22:53:16 +00004203 type = eSymbolTypeData;
4204 break;
4205 default:
4206 break;
4207 }
4208 break;
Greg Claytonfd814c52013-08-13 01:42:25 +00004209 }
4210
4211 if (type == eSymbolTypeInvalid)
4212 {
4213 const char *symbol_sect_name = symbol_section->GetName().AsCString();
4214 if (symbol_section->IsDescendant (text_section_sp.get()))
4215 {
Charles Davis510938e2013-08-27 05:04:57 +00004216 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
4217 S_ATTR_SELF_MODIFYING_CODE |
4218 S_ATTR_SOME_INSTRUCTIONS))
Greg Claytonfd814c52013-08-13 01:42:25 +00004219 type = eSymbolTypeData;
4220 else
4221 type = eSymbolTypeCode;
4222 }
4223 else
Greg Claytona381e102015-07-27 23:21:05 +00004224 if (symbol_section->IsDescendant(data_section_sp.get()) ||
4225 symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
4226 symbol_section->IsDescendant(data_const_section_sp.get()))
Greg Claytonfd814c52013-08-13 01:42:25 +00004227 {
4228 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
4229 {
4230 type = eSymbolTypeRuntime;
4231
Jason Molenda649a6072015-11-10 05:21:54 +00004232 if (symbol_name)
Greg Claytonfd814c52013-08-13 01:42:25 +00004233 {
4234 llvm::StringRef symbol_name_ref(symbol_name);
Jason Molenda649a6072015-11-10 05:21:54 +00004235 if (symbol_name_ref.startswith("_OBJC_"))
Greg Claytonfd814c52013-08-13 01:42:25 +00004236 {
Jason Molenda649a6072015-11-10 05:21:54 +00004237 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
4238 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
4239 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
4240 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
4241 {
4242 symbol_name_non_abi_mangled = symbol_name + 1;
4243 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
4244 type = eSymbolTypeObjCClass;
4245 demangled_is_synthesized = true;
4246 }
4247 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
4248 {
4249 symbol_name_non_abi_mangled = symbol_name + 1;
4250 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
4251 type = eSymbolTypeObjCMetaClass;
4252 demangled_is_synthesized = true;
4253 }
4254 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
4255 {
4256 symbol_name_non_abi_mangled = symbol_name + 1;
4257 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
4258 type = eSymbolTypeObjCIVar;
4259 demangled_is_synthesized = true;
4260 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004261 }
4262 }
4263 }
4264 else
4265 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
4266 {
4267 type = eSymbolTypeException;
4268 }
4269 else
4270 {
4271 type = eSymbolTypeData;
4272 }
4273 }
4274 else
4275 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
4276 {
4277 type = eSymbolTypeTrampoline;
4278 }
4279 else
4280 if (symbol_section->IsDescendant(objc_section_sp.get()))
4281 {
4282 type = eSymbolTypeRuntime;
4283 if (symbol_name && symbol_name[0] == '.')
4284 {
4285 llvm::StringRef symbol_name_ref(symbol_name);
4286 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
4287 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
4288 {
4289 symbol_name_non_abi_mangled = symbol_name;
4290 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
4291 type = eSymbolTypeObjCClass;
4292 demangled_is_synthesized = true;
4293 }
4294 }
4295 }
4296 }
4297 }
4298 }
4299 break;
Greg Claytondacc4a92013-05-14 22:19:37 +00004300 }
4301 }
4302
Greg Claytonfd814c52013-08-13 01:42:25 +00004303 if (add_nlist)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004304 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004305 uint64_t symbol_value = nlist.n_value;
4306
4307 if (symbol_name_non_abi_mangled)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004308 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004309 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
4310 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
4311 }
4312 else
4313 {
4314 bool symbol_name_is_mangled = false;
4315
4316 if (symbol_name && symbol_name[0] == '_')
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004317 {
Greg Claytonfd814c52013-08-13 01:42:25 +00004318 symbol_name_is_mangled = symbol_name[1] == '_';
4319 symbol_name++; // Skip the leading underscore
4320 }
4321
4322 if (symbol_name)
4323 {
4324 ConstString const_symbol_name(symbol_name);
4325 sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
Greg Claytonfd814c52013-08-13 01:42:25 +00004326 }
4327 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004328
4329 if (is_gsym)
Greg Clayton14cd13c2015-07-01 23:29:06 +00004330 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004331 const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
Greg Clayton14cd13c2015-07-01 23:29:06 +00004332 if (gsym_name)
4333 N_GSYM_name_to_sym_idx[gsym_name] = sym_idx;
4334 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004335
Greg Claytonfd814c52013-08-13 01:42:25 +00004336 if (symbol_section)
4337 {
4338 const addr_t section_file_addr = symbol_section->GetFileAddress();
4339 if (symbol_byte_size == 0 && function_starts_count > 0)
4340 {
4341 addr_t symbol_lookup_file_addr = nlist.n_value;
4342 // Do an exact address match for non-ARM addresses, else get the closest since
4343 // the symbol might be a thumb symbol which has an address with bit zero set
4344 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
4345 if (is_arm && func_start_entry)
4346 {
4347 // Verify that the function start address is the symbol address (ARM)
4348 // or the symbol address + 1 (thumb)
4349 if (func_start_entry->addr != symbol_lookup_file_addr &&
4350 func_start_entry->addr != (symbol_lookup_file_addr + 1))
4351 {
4352 // Not the right entry, NULL it out...
4353 func_start_entry = NULL;
4354 }
4355 }
4356 if (func_start_entry)
4357 {
4358 func_start_entry->data = true;
4359
4360 addr_t symbol_file_addr = func_start_entry->addr;
4361 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004362 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Claytonfd814c52013-08-13 01:42:25 +00004363
4364 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4365 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4366 if (next_func_start_entry)
4367 {
4368 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4369 // Be sure the clear the Thumb address bit when we calculate the size
4370 // from the current and next address
4371 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004372 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Claytonfd814c52013-08-13 01:42:25 +00004373 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
4374 }
4375 else
4376 {
4377 symbol_byte_size = section_end_file_addr - symbol_file_addr;
4378 }
4379 }
4380 }
4381 symbol_value -= section_file_addr;
4382 }
4383
4384 if (is_debug == false)
4385 {
4386 if (type == eSymbolTypeCode)
4387 {
4388 // See if we can find a N_FUN entry for any code symbols.
4389 // If we do find a match, and the name matches, then we
4390 // can merge the two into just the function symbol to avoid
4391 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004392 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4393 range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
4394 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004395 {
Greg Claytond81088c2014-01-16 01:38:29 +00004396 bool found_it = false;
4397 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004398 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004399 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 +00004400 {
4401 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4402 // We just need the flags from the linker symbol, so put these flags
4403 // into the N_FUN flags to avoid duplicate symbols in the symbol table
4404 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4405 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4406 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
4407 sym[pos->second].SetType (eSymbolTypeResolver);
4408 sym[sym_idx].Clear();
4409 found_it = true;
4410 break;
4411 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004412 }
Greg Claytond81088c2014-01-16 01:38:29 +00004413 if (found_it)
4414 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004415 }
Jim Inghamea3ac272014-01-10 22:55:37 +00004416 else
4417 {
4418 if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
Greg Claytonbaf2c222014-01-16 01:48:44 +00004419 type = eSymbolTypeResolver;
Jim Inghamea3ac272014-01-10 22:55:37 +00004420 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004421 }
Greg Clayton1e28adf2015-02-25 17:25:02 +00004422 else if (type == eSymbolTypeData ||
4423 type == eSymbolTypeObjCClass ||
4424 type == eSymbolTypeObjCMetaClass ||
4425 type == eSymbolTypeObjCIVar )
Greg Claytonfd814c52013-08-13 01:42:25 +00004426 {
4427 // See if we can find a N_STSYM entry for any data symbols.
4428 // If we do find a match, and the name matches, then we
4429 // can merge the two into just the Static symbol to avoid
4430 // duplicate entries in the symbol table
Greg Claytond81088c2014-01-16 01:38:29 +00004431 std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
4432 range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
4433 if (range.first != range.second)
Greg Claytonfd814c52013-08-13 01:42:25 +00004434 {
Greg Claytond81088c2014-01-16 01:38:29 +00004435 bool found_it = false;
4436 for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
Greg Claytonfd814c52013-08-13 01:42:25 +00004437 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00004438 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 +00004439 {
4440 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
4441 // We just need the flags from the linker symbol, so put these flags
4442 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
4443 sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
4444 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4445 sym[sym_idx].Clear();
4446 found_it = true;
4447 break;
4448 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004449 }
Greg Claytond81088c2014-01-16 01:38:29 +00004450 if (found_it)
4451 continue;
Greg Claytonfd814c52013-08-13 01:42:25 +00004452 }
4453 else
4454 {
4455 // Combine N_GSYM stab entries with the non stab symbol
Greg Claytonddaf6a72015-07-08 22:32:23 +00004456 const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
Greg Clayton14cd13c2015-07-01 23:29:06 +00004457 if (gsym_name)
Greg Claytonfd814c52013-08-13 01:42:25 +00004458 {
Greg Clayton14cd13c2015-07-01 23:29:06 +00004459 ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
4460 if (pos != N_GSYM_name_to_sym_idx.end())
4461 {
4462 const uint32_t GSYM_sym_idx = pos->second;
4463 m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
4464 // Copy the address, because often the N_GSYM address has an invalid address of zero
4465 // when the global is a common symbol
4466 sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
4467 sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
4468 // We just need the flags from the linker symbol, so put these flags
4469 // into the N_GSYM flags to avoid duplicate symbols in the symbol table
4470 sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4471 sym[sym_idx].Clear();
4472 continue;
4473 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004474 }
4475 }
4476 }
4477 }
4478
4479 sym[sym_idx].SetID (nlist_idx);
4480 sym[sym_idx].SetType (type);
Greg Clayton60038be2015-02-14 00:51:13 +00004481 if (set_value)
4482 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00004483 sym[sym_idx].GetAddressRef().SetSection (symbol_section);
4484 sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
Greg Clayton60038be2015-02-14 00:51:13 +00004485 }
Greg Claytonfd814c52013-08-13 01:42:25 +00004486 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
4487
4488 if (symbol_byte_size > 0)
4489 sym[sym_idx].SetByteSize(symbol_byte_size);
4490
4491 if (demangled_is_synthesized)
4492 sym[sym_idx].SetDemangledNameIsSynthesized(true);
4493
4494 ++sym_idx;
4495 }
4496 else
4497 {
4498 sym[sym_idx].Clear();
4499 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004500 }
Greg Clayton60038be2015-02-14 00:51:13 +00004501
4502 for (const auto &pos :reexport_shlib_needs_fixup)
4503 {
4504 const auto undef_pos = undefined_name_to_desc.find(pos.second);
4505 if (undef_pos != undefined_name_to_desc.end())
4506 {
4507 const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
4508 if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
4509 sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
4510 }
4511 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004512 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004513
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004514 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
4515
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004516 if (function_starts_count > 0)
4517 {
4518 char synthetic_function_symbol[PATH_MAX];
4519 uint32_t num_synthetic_function_symbols = 0;
4520 for (i=0; i<function_starts_count; ++i)
4521 {
4522 if (function_starts.GetEntryRef (i).data == false)
4523 ++num_synthetic_function_symbols;
4524 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004525
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004526 if (num_synthetic_function_symbols > 0)
4527 {
4528 if (num_syms < sym_idx + num_synthetic_function_symbols)
4529 {
4530 num_syms = sym_idx + num_synthetic_function_symbols;
4531 sym = symtab->Resize (num_syms);
4532 }
4533 uint32_t synthetic_function_symbol_idx = 0;
4534 for (i=0; i<function_starts_count; ++i)
4535 {
4536 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
4537 if (func_start_entry->data == false)
4538 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004539 addr_t symbol_file_addr = func_start_entry->addr;
4540 uint32_t symbol_flags = 0;
4541 if (is_arm)
4542 {
4543 if (symbol_file_addr & 1)
4544 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Greg Claytonb887da12015-07-16 19:50:57 +00004545 symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004546 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004547 Address symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004548 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004549 {
4550 SectionSP symbol_section (symbol_addr.GetSection());
4551 uint32_t symbol_byte_size = 0;
4552 if (symbol_section)
4553 {
4554 const addr_t section_file_addr = symbol_section->GetFileAddress();
4555 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
4556 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
4557 if (next_func_start_entry)
4558 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004559 addr_t next_symbol_file_addr = next_func_start_entry->addr;
4560 if (is_arm)
Greg Claytonb887da12015-07-16 19:50:57 +00004561 next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004562 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 +00004563 }
4564 else
4565 {
Greg Clayton29e08cb2012-03-14 01:53:24 +00004566 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004567 }
4568 snprintf (synthetic_function_symbol,
4569 sizeof(synthetic_function_symbol),
4570 "___lldb_unnamed_function%u$$%s",
4571 ++synthetic_function_symbol_idx,
4572 module_sp->GetFileSpec().GetFilename().GetCString());
4573 sym[sym_idx].SetID (synthetic_sym_id++);
Greg Clayton037520e2012-07-18 23:18:10 +00004574 sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004575 sym[sym_idx].SetType (eSymbolTypeCode);
4576 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004577 sym[sym_idx].GetAddressRef() = symbol_addr;
Greg Clayton29e08cb2012-03-14 01:53:24 +00004578 if (symbol_flags)
4579 sym[sym_idx].SetFlags (symbol_flags);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004580 if (symbol_byte_size)
4581 sym[sym_idx].SetByteSize (symbol_byte_size);
4582 ++sym_idx;
4583 }
4584 }
4585 }
4586 }
4587 }
4588 }
4589
4590 // Trim our symbols down to just what we ended up with after
4591 // removing any symbols.
4592 if (sym_idx < num_syms)
4593 {
4594 num_syms = sym_idx;
4595 sym = symtab->Resize (num_syms);
4596 }
4597
4598 // Now synthesize indirect symbols
4599 if (m_dysymtab.nindirectsyms != 0)
4600 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004601 if (indirect_symbol_index_data.GetByteSize())
4602 {
4603 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
4604
4605 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
4606 {
Charles Davis510938e2013-08-27 05:04:57 +00004607 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004608 {
4609 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
4610 if (symbol_stub_byte_size == 0)
4611 continue;
4612
4613 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
4614
4615 if (num_symbol_stubs == 0)
4616 continue;
4617
4618 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
4619 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
4620 {
4621 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
4622 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 +00004623 lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004624 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
4625 {
4626 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
Charles Davis510938e2013-08-27 05:04:57 +00004627 if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004628 continue;
4629
4630 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
4631 Symbol *stub_symbol = NULL;
4632 if (index_pos != end_index_pos)
4633 {
4634 // We have a remapping from the original nlist index to
4635 // a current symbol index, so just look this up by index
4636 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
4637 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00004638 else
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004639 {
4640 // We need to lookup a symbol using the original nlist
Jason Molenda4e7511e2013-03-06 23:19:17 +00004641 // symbol index since this index is coming from the
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004642 // S_SYMBOL_STUBS
4643 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
4644 }
4645
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004646 if (stub_symbol)
4647 {
4648 Address so_addr(symbol_stub_addr, section_list);
4649
4650 if (stub_symbol->GetType() == eSymbolTypeUndefined)
4651 {
4652 // Change the external symbol into a trampoline that makes sense
4653 // These symbols were N_UNDF N_EXT, and are useless to us, so we
4654 // can re-use them so we don't have to make up a synthetic symbol
4655 // for no good reason.
Greg Clayton9191db42013-10-21 18:40:51 +00004656 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4657 stub_symbol->SetType (eSymbolTypeTrampoline);
4658 else
4659 stub_symbol->SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004660 stub_symbol->SetExternal (false);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004661 stub_symbol->GetAddressRef() = so_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004662 stub_symbol->SetByteSize (symbol_stub_byte_size);
4663 }
4664 else
4665 {
4666 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda0a287e02012-04-24 02:09:58 +00004667 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004668 if (sym_idx >= num_syms)
Jason Molenda0a287e02012-04-24 02:09:58 +00004669 {
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004670 sym = symtab->Resize (++num_syms);
Jason Molenda0a287e02012-04-24 02:09:58 +00004671 stub_symbol = NULL; // this pointer no longer valid
4672 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004673 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda0a287e02012-04-24 02:09:58 +00004674 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton9191db42013-10-21 18:40:51 +00004675 if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
4676 sym[sym_idx].SetType (eSymbolTypeTrampoline);
4677 else
4678 sym[sym_idx].SetType (eSymbolTypeResolver);
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004679 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton358cf1e2015-06-25 21:46:34 +00004680 sym[sym_idx].GetAddressRef() = so_addr;
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004681 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
4682 ++sym_idx;
4683 }
4684 }
Greg Clayton3f839a32012-09-05 01:38:55 +00004685 else
4686 {
4687 if (log)
4688 log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
4689 }
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004690 }
4691 }
4692 }
4693 }
4694 }
4695 }
Greg Clayton9191db42013-10-21 18:40:51 +00004696
Greg Clayton9191db42013-10-21 18:40:51 +00004697 if (!trie_entries.empty())
4698 {
4699 for (const auto &e : trie_entries)
4700 {
4701 if (e.entry.import_name)
4702 {
Greg Clayton60038be2015-02-14 00:51:13 +00004703 // Only add indirect symbols from the Trie entries if we
4704 // didn't have a N_INDR nlist entry for this already
4705 if (indirect_symbol_names.find(e.entry.name) == indirect_symbol_names.end())
Greg Clayton9191db42013-10-21 18:40:51 +00004706 {
Greg Clayton60038be2015-02-14 00:51:13 +00004707 // Make a synthetic symbol to describe re-exported symbol.
4708 if (sym_idx >= num_syms)
4709 sym = symtab->Resize (++num_syms);
4710 sym[sym_idx].SetID (synthetic_sym_id++);
4711 sym[sym_idx].GetMangled() = Mangled(e.entry.name);
4712 sym[sym_idx].SetType (eSymbolTypeReExported);
4713 sym[sym_idx].SetIsSynthetic (true);
4714 sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
4715 if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
4716 {
4717 sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
4718 }
4719 ++sym_idx;
Greg Clayton9191db42013-10-21 18:40:51 +00004720 }
Greg Clayton9191db42013-10-21 18:40:51 +00004721 }
4722 }
4723 }
Eugene Zelenko8157a882015-10-23 16:56:07 +00004724
Greg Clayton3046e662013-07-10 01:23:25 +00004725// StreamFile s(stdout, false);
4726// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
4727// symtab->Dump(&s, NULL, eSortOrderNone);
4728 // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
4729 symtab->CalculateSymbolSizes();
4730
4731// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
4732// symtab->Dump(&s, NULL, eSortOrderNone);
4733
Greg Claytonf3bb3e42012-03-09 04:26:05 +00004734 return symtab->GetNumSymbols();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004735 }
4736 return 0;
4737}
4738
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004739void
4740ObjectFileMachO::Dump (Stream *s)
4741{
Greg Claytona1743492012-03-13 23:14:29 +00004742 ModuleSP module_sp(GetModule());
4743 if (module_sp)
4744 {
4745 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004746 s->Printf("%p: ", static_cast<void*>(this));
Greg Claytona1743492012-03-13 23:14:29 +00004747 s->Indent();
Charles Davis510938e2013-08-27 05:04:57 +00004748 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
Greg Claytona1743492012-03-13 23:14:29 +00004749 s->PutCString("ObjectFileMachO64");
4750 else
4751 s->PutCString("ObjectFileMachO32");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004752
Greg Clayton7ab7f892014-05-29 21:33:45 +00004753 ArchSpec header_arch;
4754 GetArchitecture(header_arch);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004755
Greg Claytona1743492012-03-13 23:14:29 +00004756 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004757
Greg Clayton3046e662013-07-10 01:23:25 +00004758 SectionList *sections = GetSectionList();
4759 if (sections)
4760 sections->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004761
Greg Claytona1743492012-03-13 23:14:29 +00004762 if (m_symtab_ap.get())
4763 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
4764 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004765}
4766
Greg Claytonf4d6de62013-04-24 22:29:28 +00004767bool
4768ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header,
4769 const lldb_private::DataExtractor &data,
4770 lldb::offset_t lc_offset,
4771 lldb_private::UUID& uuid)
4772{
4773 uint32_t i;
4774 struct uuid_command load_cmd;
4775
4776 lldb::offset_t offset = lc_offset;
4777 for (i=0; i<header.ncmds; ++i)
4778 {
4779 const lldb::offset_t cmd_offset = offset;
4780 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4781 break;
4782
Charles Davis510938e2013-08-27 05:04:57 +00004783 if (load_cmd.cmd == LC_UUID)
Greg Claytonf4d6de62013-04-24 22:29:28 +00004784 {
4785 const uint8_t *uuid_bytes = data.PeekData(offset, 16);
4786
4787 if (uuid_bytes)
4788 {
4789 // OpenCL on Mac OS X uses the same UUID for each of its object files.
4790 // We pretend these object files have no UUID to prevent crashing.
4791
4792 const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
4793 0x3b, 0xa8,
4794 0x4b, 0x16,
4795 0xb6, 0xa4,
4796 0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
4797
4798 if (!memcmp(uuid_bytes, opencl_uuid, 16))
4799 return false;
4800
4801 uuid.SetBytes (uuid_bytes);
4802 return true;
4803 }
4804 return false;
4805 }
4806 offset = cmd_offset + load_cmd.cmdsize;
4807 }
4808 return false;
4809}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004810
Greg Clayton7ab7f892014-05-29 21:33:45 +00004811bool
4812ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header,
4813 const lldb_private::DataExtractor &data,
4814 lldb::offset_t lc_offset,
4815 ArchSpec &arch)
4816{
4817 arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype);
4818
4819 if (arch.IsValid())
4820 {
4821 llvm::Triple &triple = arch.GetTriple();
Greg Claytona3706882015-10-28 23:26:59 +00004822
4823 // Set OS to an unspecified unknown or a "*" so it can match any OS
4824 triple.setOS(llvm::Triple::UnknownOS);
4825 triple.setOSName(llvm::StringRef());
4826
Greg Clayton7ab7f892014-05-29 21:33:45 +00004827 if (header.filetype == MH_PRELOAD)
4828 {
Greg Claytona3706882015-10-28 23:26:59 +00004829 // Set vendor to an unspecified unknown or a "*" so it can match any vendor
4830 triple.setVendor(llvm::Triple::UnknownVendor);
4831 triple.setVendorName(llvm::StringRef());
Greg Clayton7ab7f892014-05-29 21:33:45 +00004832 return true;
4833 }
4834 else
4835 {
4836 struct load_command load_cmd;
Greg Claytona3706882015-10-28 23:26:59 +00004837
Greg Clayton7ab7f892014-05-29 21:33:45 +00004838 lldb::offset_t offset = lc_offset;
4839 for (uint32_t i=0; i<header.ncmds; ++i)
4840 {
4841 const lldb::offset_t cmd_offset = offset;
4842 if (data.GetU32(&offset, &load_cmd, 2) == NULL)
4843 break;
4844
4845 switch (load_cmd.cmd)
4846 {
Jason Molenda649a6072015-11-10 05:21:54 +00004847 case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
Greg Clayton7ab7f892014-05-29 21:33:45 +00004848 triple.setOS (llvm::Triple::IOS);
4849 return true;
4850
Jason Molenda649a6072015-11-10 05:21:54 +00004851 case llvm::MachO::LC_VERSION_MIN_MACOSX:
Greg Clayton7ab7f892014-05-29 21:33:45 +00004852 triple.setOS (llvm::Triple::MacOSX);
4853 return true;
Jason Molenda649a6072015-11-10 05:21:54 +00004854
4855 case llvm::MachO::LC_VERSION_MIN_TVOS:
4856 triple.setOS (llvm::Triple::TvOS);
4857 return true;
Greg Clayton7ab7f892014-05-29 21:33:45 +00004858
Jason Molenda649a6072015-11-10 05:21:54 +00004859 case llvm::MachO::LC_VERSION_MIN_WATCHOS:
4860 triple.setOS (llvm::Triple::WatchOS);
4861 return true;
4862
Greg Clayton7ab7f892014-05-29 21:33:45 +00004863 default:
4864 break;
4865 }
4866
4867 offset = cmd_offset + load_cmd.cmdsize;
4868 }
4869
Greg Claytona3706882015-10-28 23:26:59 +00004870 if (header.filetype != MH_KEXT_BUNDLE)
4871 {
4872 // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT
4873 // so lets not say our Vendor is Apple, leave it as an unspecified unknown
4874 triple.setVendor(llvm::Triple::UnknownVendor);
4875 triple.setVendorName(llvm::StringRef());
4876 }
Greg Clayton7ab7f892014-05-29 21:33:45 +00004877 }
4878 }
4879 return arch.IsValid();
4880}
4881
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004882bool
Greg Clayton60830262011-02-04 18:53:10 +00004883ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004884{
Greg Claytona1743492012-03-13 23:14:29 +00004885 ModuleSP module_sp(GetModule());
4886 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004887 {
Greg Claytona1743492012-03-13 23:14:29 +00004888 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Claytonc7bece562013-01-25 18:06:21 +00004889 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytonf4d6de62013-04-24 22:29:28 +00004890 return GetUUID (m_header, m_data, offset, *uuid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004891 }
4892 return false;
4893}
4894
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004895uint32_t
4896ObjectFileMachO::GetDependentModules (FileSpecList& files)
4897{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004898 uint32_t count = 0;
Greg Claytona1743492012-03-13 23:14:29 +00004899 ModuleSP module_sp(GetModule());
4900 if (module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004901 {
Greg Claytona1743492012-03-13 23:14:29 +00004902 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
4903 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00004904 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Clayton5a271952015-06-02 22:43:29 +00004905 std::vector<std::string> rpath_paths;
4906 std::vector<std::string> rpath_relative_paths;
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00004907 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 +00004908 uint32_t i;
4909 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004910 {
Greg Claytona1743492012-03-13 23:14:29 +00004911 const uint32_t cmd_offset = offset;
4912 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
4913 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004914
Greg Claytona1743492012-03-13 23:14:29 +00004915 switch (load_cmd.cmd)
4916 {
Greg Clayton5a271952015-06-02 22:43:29 +00004917 case LC_RPATH:
Charles Davis510938e2013-08-27 05:04:57 +00004918 case LC_LOAD_DYLIB:
4919 case LC_LOAD_WEAK_DYLIB:
4920 case LC_REEXPORT_DYLIB:
4921 case LC_LOAD_DYLINKER:
4922 case LC_LOADFVMLIB:
4923 case LC_LOAD_UPWARD_DYLIB:
Greg Claytona1743492012-03-13 23:14:29 +00004924 {
4925 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
4926 const char *path = m_data.PeekCStr(name_offset);
Greg Clayton5a271952015-06-02 22:43:29 +00004927 if (path)
Greg Claytona1743492012-03-13 23:14:29 +00004928 {
Greg Clayton5a271952015-06-02 22:43:29 +00004929 if (load_cmd.cmd == LC_RPATH)
4930 rpath_paths.push_back(path);
4931 else
4932 {
4933 if (path[0] == '@')
4934 {
4935 if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
4936 rpath_relative_paths.push_back(path + strlen("@rpath"));
4937 }
4938 else
4939 {
4940 FileSpec file_spec(path, resolve_path);
4941 if (files.AppendIfUnique(file_spec))
4942 count++;
4943 }
4944 }
Greg Claytona1743492012-03-13 23:14:29 +00004945 }
4946 }
4947 break;
4948
4949 default:
4950 break;
4951 }
4952 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004953 }
Greg Clayton5a271952015-06-02 22:43:29 +00004954
4955 if (!rpath_paths.empty())
4956 {
4957 // Fixup all LC_RPATH values to be absolute paths
4958 FileSpec this_file_spec(m_file);
4959 this_file_spec.ResolvePath();
4960 std::string loader_path("@loader_path");
4961 std::string executable_path("@executable_path");
4962 for (auto &rpath : rpath_paths)
4963 {
4964 if (rpath.find(loader_path) == 0)
4965 {
4966 rpath.erase(0, loader_path.size());
4967 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
4968 }
4969 else if (rpath.find(executable_path) == 0)
4970 {
4971 rpath.erase(0, executable_path.size());
4972 rpath.insert(0, this_file_spec.GetDirectory().GetCString());
4973 }
4974 }
4975
4976 for (const auto &rpath_relative_path : rpath_relative_paths)
4977 {
4978 for (const auto &rpath : rpath_paths)
4979 {
4980 std::string path = rpath;
4981 path += rpath_relative_path;
4982 // It is OK to resolve this path because we must find a file on
4983 // disk for us to accept it anyway if it is rpath relative.
4984 FileSpec file_spec(path, true);
4985 // Remove any redundant parts of the path (like "../foo") since
4986 // LC_RPATH values often contain "..".
4987 file_spec.NormalizePath ();
4988 if (file_spec.Exists() && files.AppendIfUnique(file_spec))
4989 {
4990 count++;
4991 break;
4992 }
4993 }
4994 }
4995 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004996 }
4997 return count;
4998}
4999
Jim Ingham672e6f52011-03-07 23:44:08 +00005000lldb_private::Address
Jason Molenda4e7511e2013-03-06 23:19:17 +00005001ObjectFileMachO::GetEntryPointAddress ()
Jim Ingham672e6f52011-03-07 23:44:08 +00005002{
5003 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
5004 // is initialized to an invalid address, so we can just return that.
5005 // 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 +00005006
Jim Ingham672e6f52011-03-07 23:44:08 +00005007 if (!IsExecutable() || m_entry_point_address.IsValid())
5008 return m_entry_point_address;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005009
5010 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
Jim Ingham672e6f52011-03-07 23:44:08 +00005011 // /usr/include/mach-o.h, but it is basically:
5012 //
5013 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
5014 // uint32_t count - this is the count of longs in the thread state data
5015 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
5016 // <repeat this trio>
Jason Molenda4e7511e2013-03-06 23:19:17 +00005017 //
Jim Ingham672e6f52011-03-07 23:44:08 +00005018 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
5019 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
5020 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
5021 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
5022 //
5023 // For now we hard-code the offsets and flavors we need:
5024 //
5025 //
5026
Greg Claytona1743492012-03-13 23:14:29 +00005027 ModuleSP module_sp(GetModule());
5028 if (module_sp)
Jim Ingham672e6f52011-03-07 23:44:08 +00005029 {
Greg Claytona1743492012-03-13 23:14:29 +00005030 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5031 struct load_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00005032 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005033 uint32_t i;
5034 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
5035 bool done = false;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005036
Greg Claytona1743492012-03-13 23:14:29 +00005037 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham672e6f52011-03-07 23:44:08 +00005038 {
Greg Claytonc7bece562013-01-25 18:06:21 +00005039 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00005040 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
5041 break;
5042
5043 switch (load_cmd.cmd)
Jim Ingham672e6f52011-03-07 23:44:08 +00005044 {
Charles Davis510938e2013-08-27 05:04:57 +00005045 case LC_UNIXTHREAD:
5046 case LC_THREAD:
Jim Ingham672e6f52011-03-07 23:44:08 +00005047 {
Greg Claytona1743492012-03-13 23:14:29 +00005048 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham672e6f52011-03-07 23:44:08 +00005049 {
Greg Claytona1743492012-03-13 23:14:29 +00005050 uint32_t flavor = m_data.GetU32(&offset);
5051 uint32_t count = m_data.GetU32(&offset);
5052 if (count == 0)
5053 {
5054 // We've gotten off somehow, log and exit;
5055 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00005056 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005057
Greg Claytona1743492012-03-13 23:14:29 +00005058 switch (m_header.cputype)
5059 {
Charles Davis510938e2013-08-27 05:04:57 +00005060 case llvm::MachO::CPU_TYPE_ARM:
Greg Claytona1743492012-03-13 23:14:29 +00005061 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
5062 {
5063 offset += 60; // This is the offset of pc in the GPR thread state data structure.
5064 start_address = m_data.GetU32(&offset);
5065 done = true;
5066 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005067 break;
Jason Molendaa3329782014-03-29 18:54:20 +00005068 case llvm::MachO::CPU_TYPE_ARM64:
5069 if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
5070 {
5071 offset += 256; // This is the offset of pc in the GPR thread state data structure.
5072 start_address = m_data.GetU64(&offset);
5073 done = true;
5074 }
5075 break;
Charles Davis510938e2013-08-27 05:04:57 +00005076 case llvm::MachO::CPU_TYPE_I386:
Greg Claytona1743492012-03-13 23:14:29 +00005077 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
5078 {
5079 offset += 40; // This is the offset of eip in the GPR thread state data structure.
5080 start_address = m_data.GetU32(&offset);
5081 done = true;
5082 }
5083 break;
Charles Davis510938e2013-08-27 05:04:57 +00005084 case llvm::MachO::CPU_TYPE_X86_64:
Greg Claytona1743492012-03-13 23:14:29 +00005085 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
5086 {
5087 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
5088 start_address = m_data.GetU64(&offset);
5089 done = true;
5090 }
5091 break;
5092 default:
5093 return m_entry_point_address;
5094 }
5095 // Haven't found the GPR flavor yet, skip over the data for this flavor:
5096 if (done)
5097 break;
5098 offset += count * 4;
5099 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005100 }
Greg Claytona1743492012-03-13 23:14:29 +00005101 break;
Charles Davis510938e2013-08-27 05:04:57 +00005102 case LC_MAIN:
Sean Callanan226b70c2012-03-08 02:39:03 +00005103 {
Greg Claytona1743492012-03-13 23:14:29 +00005104 ConstString text_segment_name ("__TEXT");
5105 uint64_t entryoffset = m_data.GetU64(&offset);
5106 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
5107 if (text_segment_sp)
5108 {
5109 done = true;
5110 start_address = text_segment_sp->GetFileAddress() + entryoffset;
5111 }
Sean Callanan226b70c2012-03-08 02:39:03 +00005112 }
Greg Claytona1743492012-03-13 23:14:29 +00005113
5114 default:
5115 break;
Sean Callanan226b70c2012-03-08 02:39:03 +00005116 }
Greg Claytona1743492012-03-13 23:14:29 +00005117 if (done)
5118 break;
Jim Ingham672e6f52011-03-07 23:44:08 +00005119
Greg Claytona1743492012-03-13 23:14:29 +00005120 // Go to the next load command:
5121 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham672e6f52011-03-07 23:44:08 +00005122 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005123
Greg Claytona1743492012-03-13 23:14:29 +00005124 if (start_address != LLDB_INVALID_ADDRESS)
Greg Claytone72dfb32012-02-24 01:59:29 +00005125 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00005126 // We got the start address from the load commands, so now resolve that address in the sections
Greg Claytona1743492012-03-13 23:14:29 +00005127 // of this ObjectFile:
5128 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Claytone72dfb32012-02-24 01:59:29 +00005129 {
Greg Claytona1743492012-03-13 23:14:29 +00005130 m_entry_point_address.Clear();
5131 }
5132 }
5133 else
5134 {
5135 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
5136 // "start" symbol in the main executable.
Jason Molenda4e7511e2013-03-06 23:19:17 +00005137
Greg Claytona1743492012-03-13 23:14:29 +00005138 ModuleSP module_sp (GetModule());
Jason Molenda4e7511e2013-03-06 23:19:17 +00005139
Greg Claytona1743492012-03-13 23:14:29 +00005140 if (module_sp)
5141 {
5142 SymbolContextList contexts;
5143 SymbolContext context;
5144 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
5145 {
5146 if (contexts.GetContextAtIndex(0, context))
5147 m_entry_point_address = context.symbol->GetAddress();
5148 }
Greg Claytone72dfb32012-02-24 01:59:29 +00005149 }
5150 }
Jim Ingham672e6f52011-03-07 23:44:08 +00005151 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005152
Jim Ingham672e6f52011-03-07 23:44:08 +00005153 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +00005154}
5155
Greg Claytonc9660542012-02-05 02:38:54 +00005156lldb_private::Address
5157ObjectFileMachO::GetHeaderAddress ()
5158{
5159 lldb_private::Address header_addr;
5160 SectionList *section_list = GetSectionList();
5161 if (section_list)
5162 {
5163 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
5164 if (text_segment_sp)
5165 {
Greg Claytone72dfb32012-02-24 01:59:29 +00005166 header_addr.SetSection (text_segment_sp);
Greg Claytonc9660542012-02-05 02:38:54 +00005167 header_addr.SetOffset (0);
5168 }
5169 }
5170 return header_addr;
5171}
5172
Greg Claytonc3776bf2012-02-09 06:16:32 +00005173uint32_t
5174ObjectFileMachO::GetNumThreadContexts ()
5175{
Greg Claytona1743492012-03-13 23:14:29 +00005176 ModuleSP module_sp(GetModule());
5177 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005178 {
Greg Claytona1743492012-03-13 23:14:29 +00005179 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5180 if (!m_thread_context_offsets_valid)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005181 {
Greg Claytona1743492012-03-13 23:14:29 +00005182 m_thread_context_offsets_valid = true;
Greg Claytonc7bece562013-01-25 18:06:21 +00005183 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005184 FileRangeArray::Entry file_range;
5185 thread_command thread_cmd;
5186 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005187 {
Greg Claytona1743492012-03-13 23:14:29 +00005188 const uint32_t cmd_offset = offset;
5189 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
5190 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005191
Charles Davis510938e2013-08-27 05:04:57 +00005192 if (thread_cmd.cmd == LC_THREAD)
Greg Claytona1743492012-03-13 23:14:29 +00005193 {
5194 file_range.SetRangeBase (offset);
5195 file_range.SetByteSize (thread_cmd.cmdsize - 8);
5196 m_thread_context_offsets.Append (file_range);
5197 }
5198 offset = cmd_offset + thread_cmd.cmdsize;
Greg Claytonc3776bf2012-02-09 06:16:32 +00005199 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00005200 }
5201 }
5202 return m_thread_context_offsets.GetSize();
5203}
5204
5205lldb::RegisterContextSP
5206ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
5207{
Greg Claytonc3776bf2012-02-09 06:16:32 +00005208 lldb::RegisterContextSP reg_ctx_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +00005209
Greg Claytona1743492012-03-13 23:14:29 +00005210 ModuleSP module_sp(GetModule());
5211 if (module_sp)
Greg Claytonc3776bf2012-02-09 06:16:32 +00005212 {
Greg Claytona1743492012-03-13 23:14:29 +00005213 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5214 if (!m_thread_context_offsets_valid)
5215 GetNumThreadContexts ();
5216
5217 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
Jim Ingham28eb5712012-10-12 17:34:26 +00005218 if (thread_context_file_range)
Greg Claytona1743492012-03-13 23:14:29 +00005219 {
Jason Molenda4e7511e2013-03-06 23:19:17 +00005220
5221 DataExtractor data (m_data,
5222 thread_context_file_range->GetRangeBase(),
Jim Ingham28eb5712012-10-12 17:34:26 +00005223 thread_context_file_range->GetByteSize());
5224
5225 switch (m_header.cputype)
5226 {
Jason Molendaa3329782014-03-29 18:54:20 +00005227 case llvm::MachO::CPU_TYPE_ARM64:
5228 reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
5229 break;
5230
Charles Davis510938e2013-08-27 05:04:57 +00005231 case llvm::MachO::CPU_TYPE_ARM:
Jim Ingham28eb5712012-10-12 17:34:26 +00005232 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
5233 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005234
Charles Davis510938e2013-08-27 05:04:57 +00005235 case llvm::MachO::CPU_TYPE_I386:
Jim Ingham28eb5712012-10-12 17:34:26 +00005236 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
5237 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005238
Charles Davis510938e2013-08-27 05:04:57 +00005239 case llvm::MachO::CPU_TYPE_X86_64:
Jim Ingham28eb5712012-10-12 17:34:26 +00005240 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
5241 break;
5242 }
Greg Claytona1743492012-03-13 23:14:29 +00005243 }
Greg Claytonc3776bf2012-02-09 06:16:32 +00005244 }
5245 return reg_ctx_sp;
5246}
5247
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005248ObjectFile::Type
5249ObjectFileMachO::CalculateType()
5250{
5251 switch (m_header.filetype)
5252 {
Charles Davis510938e2013-08-27 05:04:57 +00005253 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005254 if (GetAddressByteSize () == 4)
5255 {
5256 // 32 bit kexts are just object files, but they do have a valid
5257 // UUID load command.
5258 UUID uuid;
5259 if (GetUUID(&uuid))
5260 {
5261 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00005262 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005263 // "OSKextGetCurrentIdentifier" as this is required of kexts
5264 if (m_strata == eStrataInvalid)
5265 m_strata = eStrataKernel;
5266 return eTypeSharedLibrary;
5267 }
5268 }
5269 return eTypeObjectFile;
5270
Charles Davis510938e2013-08-27 05:04:57 +00005271 case MH_EXECUTE: return eTypeExecutable; // 0x2u
5272 case MH_FVMLIB: return eTypeSharedLibrary; // 0x3u
5273 case MH_CORE: return eTypeCoreFile; // 0x4u
5274 case MH_PRELOAD: return eTypeSharedLibrary; // 0x5u
5275 case MH_DYLIB: return eTypeSharedLibrary; // 0x6u
5276 case MH_DYLINKER: return eTypeDynamicLinker; // 0x7u
5277 case MH_BUNDLE: return eTypeSharedLibrary; // 0x8u
5278 case MH_DYLIB_STUB: return eTypeStubLibrary; // 0x9u
5279 case MH_DSYM: return eTypeDebugInfo; // 0xAu
5280 case MH_KEXT_BUNDLE: return eTypeSharedLibrary; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005281 default:
5282 break;
5283 }
5284 return eTypeUnknown;
5285}
5286
5287ObjectFile::Strata
5288ObjectFileMachO::CalculateStrata()
5289{
5290 switch (m_header.filetype)
5291 {
Charles Davis510938e2013-08-27 05:04:57 +00005292 case MH_OBJECT: // 0x1u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005293 {
5294 // 32 bit kexts are just object files, but they do have a valid
5295 // UUID load command.
5296 UUID uuid;
5297 if (GetUUID(&uuid))
5298 {
5299 // this checking for the UUID load command is not enough
Jason Molenda4e7511e2013-03-06 23:19:17 +00005300 // we could eventually look for the symbol named
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005301 // "OSKextGetCurrentIdentifier" as this is required of kexts
5302 if (m_type == eTypeInvalid)
5303 m_type = eTypeSharedLibrary;
5304
5305 return eStrataKernel;
5306 }
5307 }
5308 return eStrataUnknown;
5309
Charles Davis510938e2013-08-27 05:04:57 +00005310 case MH_EXECUTE: // 0x2u
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005311 // Check for the MH_DYLDLINK bit in the flags
Charles Davis510938e2013-08-27 05:04:57 +00005312 if (m_header.flags & MH_DYLDLINK)
Sean Callanan49bce8e2012-02-10 20:22:35 +00005313 {
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005314 return eStrataUser;
Sean Callanan49bce8e2012-02-10 20:22:35 +00005315 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005316 else
Sean Callanan49bce8e2012-02-10 20:22:35 +00005317 {
5318 SectionList *section_list = GetSectionList();
5319 if (section_list)
5320 {
5321 static ConstString g_kld_section_name ("__KLD");
5322 if (section_list->FindSectionByName(g_kld_section_name))
5323 return eStrataKernel;
5324 }
5325 }
5326 return eStrataRawImage;
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005327
Charles Davis510938e2013-08-27 05:04:57 +00005328 case MH_FVMLIB: return eStrataUser; // 0x3u
5329 case MH_CORE: return eStrataUnknown; // 0x4u
5330 case MH_PRELOAD: return eStrataRawImage; // 0x5u
5331 case MH_DYLIB: return eStrataUser; // 0x6u
5332 case MH_DYLINKER: return eStrataUser; // 0x7u
5333 case MH_BUNDLE: return eStrataUser; // 0x8u
5334 case MH_DYLIB_STUB: return eStrataUser; // 0x9u
5335 case MH_DSYM: return eStrataUnknown; // 0xAu
5336 case MH_KEXT_BUNDLE: return eStrataKernel; // 0xBu
Greg Clayton9e00b6a652011-07-09 00:41:34 +00005337 default:
5338 break;
5339 }
5340 return eStrataUnknown;
5341}
5342
Greg Claytonc2ff9312012-02-22 19:41:02 +00005343uint32_t
5344ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
5345{
Greg Claytona1743492012-03-13 23:14:29 +00005346 ModuleSP module_sp(GetModule());
5347 if (module_sp)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005348 {
Greg Claytona1743492012-03-13 23:14:29 +00005349 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
5350 struct dylib_command load_cmd;
Greg Claytonc7bece562013-01-25 18:06:21 +00005351 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
Greg Claytona1743492012-03-13 23:14:29 +00005352 uint32_t version_cmd = 0;
5353 uint64_t version = 0;
5354 uint32_t i;
5355 for (i=0; i<m_header.ncmds; ++i)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005356 {
Greg Claytonc7bece562013-01-25 18:06:21 +00005357 const lldb::offset_t cmd_offset = offset;
Greg Claytona1743492012-03-13 23:14:29 +00005358 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
5359 break;
Jason Molenda4e7511e2013-03-06 23:19:17 +00005360
Charles Davis510938e2013-08-27 05:04:57 +00005361 if (load_cmd.cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005362 {
Greg Claytona1743492012-03-13 23:14:29 +00005363 if (version_cmd == 0)
5364 {
5365 version_cmd = load_cmd.cmd;
5366 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
5367 break;
5368 version = load_cmd.dylib.current_version;
5369 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005370 break; // Break for now unless there is another more complete version
Greg Claytona1743492012-03-13 23:14:29 +00005371 // number load command in the future.
Greg Claytonc2ff9312012-02-22 19:41:02 +00005372 }
Greg Claytona1743492012-03-13 23:14:29 +00005373 offset = cmd_offset + load_cmd.cmdsize;
Greg Claytonc2ff9312012-02-22 19:41:02 +00005374 }
Jason Molenda4e7511e2013-03-06 23:19:17 +00005375
Charles Davis510938e2013-08-27 05:04:57 +00005376 if (version_cmd == LC_ID_DYLIB)
Greg Claytonc2ff9312012-02-22 19:41:02 +00005377 {
Greg Claytona1743492012-03-13 23:14:29 +00005378 if (versions != NULL && num_versions > 0)
5379 {
5380 if (num_versions > 0)
5381 versions[0] = (version & 0xFFFF0000ull) >> 16;
5382 if (num_versions > 1)
5383 versions[1] = (version & 0x0000FF00ull) >> 8;
5384 if (num_versions > 2)
5385 versions[2] = (version & 0x000000FFull);
5386 // Fill in an remaining version numbers with invalid values
5387 for (i=3; i<num_versions; ++i)
5388 versions[i] = UINT32_MAX;
5389 }
5390 // The LC_ID_DYLIB load command has a version with 3 version numbers
5391 // in it, so always return 3
5392 return 3;
Greg Claytonc2ff9312012-02-22 19:41:02 +00005393 }
Greg Claytonc2ff9312012-02-22 19:41:02 +00005394 }
5395 return false;
5396}
5397
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005398bool
Greg Clayton514487e2011-02-15 21:59:32 +00005399ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005400{
Greg Claytona1743492012-03-13 23:14:29 +00005401 ModuleSP module_sp(GetModule());
5402 if (module_sp)
Greg Clayton593577a2011-09-21 03:57:31 +00005403 {
Greg Claytona1743492012-03-13 23:14:29 +00005404 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Greg Clayton7ab7f892014-05-29 21:33:45 +00005405 return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch);
Greg Clayton593577a2011-09-21 03:57:31 +00005406 }
Greg Claytona1743492012-03-13 23:14:29 +00005407 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005408}
5409
Jason Molenda0e0954c2013-04-16 06:24:42 +00005410UUID
5411ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
5412{
5413 UUID uuid;
5414 if (process)
5415 {
5416 addr_t all_image_infos = process->GetImageInfoAddress();
5417
5418 // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
5419 // or it may be the address of the dyld_all_image_infos structure (want). The first four
5420 // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
5421 // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
5422
5423 Error err;
5424 uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +00005425 if (version_or_magic != static_cast<uint32_t>(-1)
Charles Davis510938e2013-08-27 05:04:57 +00005426 && version_or_magic != MH_MAGIC
5427 && version_or_magic != MH_CIGAM
5428 && version_or_magic != MH_MAGIC_64
5429 && version_or_magic != MH_CIGAM_64
Jason Molenda0e0954c2013-04-16 06:24:42 +00005430 && version_or_magic >= 13)
5431 {
5432 addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
5433 int wordsize = process->GetAddressByteSize();
5434 if (wordsize == 8)
5435 {
5436 sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
5437 }
5438 if (wordsize == 4)
5439 {
5440 sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
5441 }
5442 if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
5443 {
5444 uuid_t shared_cache_uuid;
5445 if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
5446 {
5447 uuid.SetBytes (shared_cache_uuid);
5448 }
5449 }
5450 }
5451 }
5452 return uuid;
5453}
5454
5455UUID
5456ObjectFileMachO::GetLLDBSharedCacheUUID ()
5457{
5458 UUID uuid;
Todd Fiala013434e2014-07-09 01:29:05 +00005459#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
Jason Molenda0e0954c2013-04-16 06:24:42 +00005460 uint8_t *(*dyld_get_all_image_infos)(void);
5461 dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
5462 if (dyld_get_all_image_infos)
5463 {
5464 uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
5465 if (dyld_all_image_infos_address)
5466 {
Jason Molendac9cb7d22013-04-16 21:42:58 +00005467 uint32_t *version = (uint32_t*) dyld_all_image_infos_address; // version <mach-o/dyld_images.h>
5468 if (*version >= 13)
Jason Molenda0e0954c2013-04-16 06:24:42 +00005469 {
Jason Molendaa3329782014-03-29 18:54:20 +00005470 uuid_t *sharedCacheUUID_address = 0;
5471 int wordsize = sizeof (uint8_t *);
5472 if (wordsize == 8)
5473 {
5474 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
5475 }
5476 else
5477 {
5478 sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84); // sharedCacheUUID <mach-o/dyld_images.h>
5479 }
Jason Molenda0e0954c2013-04-16 06:24:42 +00005480 uuid.SetBytes (sharedCacheUUID_address);
5481 }
5482 }
5483 }
5484#endif
5485 return uuid;
5486}
5487
Greg Clayton9b234982013-10-24 22:54:08 +00005488uint32_t
5489ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
5490{
5491 if (m_min_os_versions.empty())
5492 {
5493 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5494 bool success = false;
5495 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5496 {
5497 const lldb::offset_t load_cmd_offset = offset;
5498
5499 version_min_command lc;
5500 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5501 break;
Jason Molenda649a6072015-11-10 05:21:54 +00005502 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX
5503 || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS
5504 || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS
5505 || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS)
Greg Clayton9b234982013-10-24 22:54:08 +00005506 {
5507 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5508 {
5509 const uint32_t xxxx = lc.version >> 16;
5510 const uint32_t yy = (lc.version >> 8) & 0xffu;
5511 const uint32_t zz = lc.version & 0xffu;
5512 if (xxxx)
5513 {
5514 m_min_os_versions.push_back(xxxx);
Greg Clayton8031d282015-02-04 00:40:25 +00005515 m_min_os_versions.push_back(yy);
5516 m_min_os_versions.push_back(zz);
Greg Clayton9b234982013-10-24 22:54:08 +00005517 }
5518 success = true;
5519 }
5520 }
5521 offset = load_cmd_offset + lc.cmdsize;
5522 }
5523
5524 if (success == false)
5525 {
5526 // Push an invalid value so we don't keep trying to
5527 m_min_os_versions.push_back(UINT32_MAX);
5528 }
5529 }
5530
5531 if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
5532 {
5533 if (versions != NULL && num_versions > 0)
5534 {
5535 for (size_t i=0; i<num_versions; ++i)
5536 {
5537 if (i < m_min_os_versions.size())
5538 versions[i] = m_min_os_versions[i];
5539 else
5540 versions[i] = 0;
5541 }
5542 }
5543 return m_min_os_versions.size();
5544 }
5545 // Call the superclasses version that will empty out the data
5546 return ObjectFile::GetMinimumOSVersion (versions, num_versions);
5547}
5548
5549uint32_t
5550ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions)
5551{
5552 if (m_sdk_versions.empty())
5553 {
5554 lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
5555 bool success = false;
5556 for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
5557 {
5558 const lldb::offset_t load_cmd_offset = offset;
5559
5560 version_min_command lc;
5561 if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
5562 break;
Jason Molenda649a6072015-11-10 05:21:54 +00005563 if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX
5564 || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS
5565 || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS
5566 || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS)
Greg Clayton9b234982013-10-24 22:54:08 +00005567 {
5568 if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
5569 {
Todd Fialaebecb382014-09-04 19:31:52 +00005570 const uint32_t xxxx = lc.sdk >> 16;
5571 const uint32_t yy = (lc.sdk >> 8) & 0xffu;
5572 const uint32_t zz = lc.sdk & 0xffu;
Greg Clayton9b234982013-10-24 22:54:08 +00005573 if (xxxx)
5574 {
5575 m_sdk_versions.push_back(xxxx);
Greg Clayton8031d282015-02-04 00:40:25 +00005576 m_sdk_versions.push_back(yy);
5577 m_sdk_versions.push_back(zz);
Greg Clayton9b234982013-10-24 22:54:08 +00005578 }
5579 success = true;
5580 }
5581 }
5582 offset = load_cmd_offset + lc.cmdsize;
5583 }
5584
5585 if (success == false)
5586 {
5587 // Push an invalid value so we don't keep trying to
5588 m_sdk_versions.push_back(UINT32_MAX);
5589 }
5590 }
5591
5592 if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
5593 {
5594 if (versions != NULL && num_versions > 0)
5595 {
5596 for (size_t i=0; i<num_versions; ++i)
5597 {
5598 if (i < m_sdk_versions.size())
5599 versions[i] = m_sdk_versions[i];
5600 else
5601 versions[i] = 0;
5602 }
5603 }
5604 return m_sdk_versions.size();
5605 }
5606 // Call the superclasses version that will empty out the data
5607 return ObjectFile::GetSDKVersion (versions, num_versions);
5608}
5609
Greg Clayton08928f32015-02-05 02:01:34 +00005610bool
5611ObjectFileMachO::GetIsDynamicLinkEditor()
5612{
5613 return m_header.filetype == llvm::MachO::MH_DYLINKER;
5614}
5615
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005616//------------------------------------------------------------------
5617// PluginInterface protocol
5618//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00005619lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005620ObjectFileMachO::GetPluginName()
5621{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005622 return GetPluginNameStatic();
5623}
5624
5625uint32_t
5626ObjectFileMachO::GetPluginVersion()
5627{
5628 return 1;
5629}
5630
Greg Clayton07347372015-06-08 21:53:11 +00005631Section *
5632ObjectFileMachO::GetMachHeaderSection()
5633{
5634 // Find the first address of the mach header which is the first non-zero
5635 // file sized section whose file offset is zero. This is the base file address
5636 // of the mach-o file which can be subtracted from the vmaddr of the other
5637 // segments found in memory and added to the load address
5638 ModuleSP module_sp = GetModule();
5639 if (module_sp)
5640 {
5641 SectionList *section_list = GetSectionList ();
5642 if (section_list)
5643 {
5644 lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
5645 const size_t num_sections = section_list->GetSize();
5646
5647 for (size_t sect_idx = 0;
5648 sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
5649 ++sect_idx)
5650 {
5651 Section *section = section_list->GetSectionAtIndex (sect_idx).get();
5652 if (section &&
5653 section->GetFileSize() > 0 &&
5654 section->GetFileOffset() == 0 &&
5655 section->IsThreadSpecific() == false &&
5656 module_sp.get() == section->GetModule().get())
5657 {
5658 return section;
5659 }
5660 }
5661 }
5662 }
5663 return nullptr;
5664}
5665
5666lldb::addr_t
5667ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const Section *mach_header_section, const Section *section)
5668{
5669 ModuleSP module_sp = GetModule();
5670 if (module_sp && mach_header_section && section && mach_header_load_address != LLDB_INVALID_ADDRESS)
5671 {
5672 lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
5673 if (mach_header_file_addr != LLDB_INVALID_ADDRESS)
5674 {
5675 if (section &&
5676 section->GetFileSize() > 0 &&
5677 section->IsThreadSpecific() == false &&
5678 module_sp.get() == section->GetModule().get())
5679 {
5680 // Ignore __LINKEDIT and __DWARF segments
5681 if (section->GetName() == GetSegmentNameLINKEDIT())
5682 {
5683 // Only map __LINKEDIT if we have an in memory image and this isn't
5684 // a kernel binary like a kext or mach_kernel.
5685 const bool is_memory_image = (bool)m_process_wp.lock();
5686 const Strata strata = GetStrata();
5687 if (is_memory_image == false || strata == eStrataKernel)
5688 return LLDB_INVALID_ADDRESS;
5689 }
5690 return section->GetFileAddress() - mach_header_file_addr + mach_header_load_address;
5691 }
5692 }
5693 }
5694 return LLDB_INVALID_ADDRESS;
5695}
5696
Greg Clayton7524e092014-02-06 20:10:16 +00005697bool
Greg Clayton751caf62014-02-07 22:54:47 +00005698ObjectFileMachO::SetLoadAddress (Target &target,
5699 lldb::addr_t value,
5700 bool value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005701{
Greg Clayton7524e092014-02-06 20:10:16 +00005702 ModuleSP module_sp = GetModule();
5703 if (module_sp)
5704 {
5705 size_t num_loaded_sections = 0;
5706 SectionList *section_list = GetSectionList ();
5707 if (section_list)
5708 {
Greg Clayton7524e092014-02-06 20:10:16 +00005709 const size_t num_sections = section_list->GetSize();
5710
Greg Clayton751caf62014-02-07 22:54:47 +00005711 if (value_is_offset)
Greg Clayton7524e092014-02-06 20:10:16 +00005712 {
Greg Clayton751caf62014-02-07 22:54:47 +00005713 // "value" is an offset to apply to each top level segment
Greg Clayton7524e092014-02-06 20:10:16 +00005714 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5715 {
5716 // Iterate through the object file sections to find all
5717 // of the sections that size on disk (to avoid __PAGEZERO)
5718 // and load them
5719 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton751caf62014-02-07 22:54:47 +00005720 if (section_sp &&
5721 section_sp->GetFileSize() > 0 &&
5722 section_sp->IsThreadSpecific() == false &&
5723 module_sp.get() == section_sp->GetModule().get())
Greg Clayton7524e092014-02-06 20:10:16 +00005724 {
Greg Clayton751caf62014-02-07 22:54:47 +00005725 // Ignore __LINKEDIT and __DWARF segments
Greg Clayton07347372015-06-08 21:53:11 +00005726 if (section_sp->GetName() == GetSegmentNameLINKEDIT())
Greg Clayton751caf62014-02-07 22:54:47 +00005727 {
5728 // Only map __LINKEDIT if we have an in memory image and this isn't
5729 // a kernel binary like a kext or mach_kernel.
Greg Clayton07347372015-06-08 21:53:11 +00005730 const bool is_memory_image = (bool)m_process_wp.lock();
5731 const Strata strata = GetStrata();
Greg Clayton751caf62014-02-07 22:54:47 +00005732 if (is_memory_image == false || strata == eStrataKernel)
5733 continue;
5734 }
5735 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
Greg Clayton7524e092014-02-06 20:10:16 +00005736 ++num_loaded_sections;
5737 }
5738 }
5739 }
Greg Clayton751caf62014-02-07 22:54:47 +00005740 else
5741 {
5742 // "value" is the new base address of the mach_header, adjust each
5743 // section accordingly
5744
Greg Clayton07347372015-06-08 21:53:11 +00005745 Section *mach_header_section = GetMachHeaderSection();
5746 if (mach_header_section)
Greg Clayton751caf62014-02-07 22:54:47 +00005747 {
5748 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
5749 {
Greg Clayton751caf62014-02-07 22:54:47 +00005750 SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
Greg Clayton07347372015-06-08 21:53:11 +00005751
5752 lldb::addr_t section_load_addr = CalculateSectionLoadAddressForMemoryImage(value, mach_header_section, section_sp.get());
5753 if (section_load_addr != LLDB_INVALID_ADDRESS)
Greg Clayton751caf62014-02-07 22:54:47 +00005754 {
Greg Clayton07347372015-06-08 21:53:11 +00005755 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_load_addr))
Greg Clayton751caf62014-02-07 22:54:47 +00005756 ++num_loaded_sections;
5757 }
5758 }
5759 }
5760 }
Greg Clayton7524e092014-02-06 20:10:16 +00005761 }
Greg Clayton7524e092014-02-06 20:10:16 +00005762 return num_loaded_sections > 0;
5763 }
Jason Molenda5cf1e232014-10-16 07:41:32 +00005764 return false;
Greg Clayton7524e092014-02-06 20:10:16 +00005765}
5766
Greg Claytona2715cf2014-06-13 00:54:12 +00005767bool
5768ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp,
5769 const FileSpec &outfile,
5770 Error &error)
5771{
5772 if (process_sp)
5773 {
5774 Target &target = process_sp->GetTarget();
5775 const ArchSpec target_arch = target.GetArchitecture();
5776 const llvm::Triple &target_triple = target_arch.GetTriple();
5777 if (target_triple.getVendor() == llvm::Triple::Apple &&
Jason Molenda649a6072015-11-10 05:21:54 +00005778 (target_triple.getOS() == llvm::Triple::MacOSX
5779 || target_triple.getOS() == llvm::Triple::IOS
5780 || target_triple.getOS() == llvm::Triple::WatchOS
5781 || target_triple.getOS() == llvm::Triple::TvOS))
Greg Claytona2715cf2014-06-13 00:54:12 +00005782 {
5783 bool make_core = false;
5784 switch (target_arch.GetMachine())
5785 {
Jason Molenda16dc86d2015-06-25 23:58:25 +00005786 case llvm::Triple::aarch64:
Jason Molenda4b0c1182014-11-12 02:39:14 +00005787 case llvm::Triple::arm:
Jason Molenda6d9fe8c2015-08-21 00:13:37 +00005788 case llvm::Triple::thumb:
Greg Claytona2715cf2014-06-13 00:54:12 +00005789 case llvm::Triple::x86:
5790 case llvm::Triple::x86_64:
5791 make_core = true;
5792 break;
5793 default:
5794 error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str());
5795 break;
5796 }
5797
5798 if (make_core)
5799 {
5800 std::vector<segment_command_64> segment_load_commands;
Saleem Abdulrasool3924d752014-06-13 03:30:39 +00005801// uint32_t range_info_idx = 0;
Greg Claytona2715cf2014-06-13 00:54:12 +00005802 MemoryRegionInfo range_info;
5803 Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
Jason Molendad20359d2014-11-11 10:59:15 +00005804 const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
5805 const ByteOrder byte_order = target_arch.GetByteOrder();
Greg Claytona2715cf2014-06-13 00:54:12 +00005806 if (range_error.Success())
5807 {
5808 while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS)
5809 {
5810 const addr_t addr = range_info.GetRange().GetRangeBase();
5811 const addr_t size = range_info.GetRange().GetByteSize();
5812
5813 if (size == 0)
5814 break;
5815
5816 // Calculate correct protections
5817 uint32_t prot = 0;
5818 if (range_info.GetReadable() == MemoryRegionInfo::eYes)
5819 prot |= VM_PROT_READ;
5820 if (range_info.GetWritable() == MemoryRegionInfo::eYes)
5821 prot |= VM_PROT_WRITE;
5822 if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
5823 prot |= VM_PROT_EXECUTE;
5824
5825// printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n",
5826// range_info_idx,
5827// addr,
5828// size,
5829// (prot & VM_PROT_READ ) ? 'r' : '-',
5830// (prot & VM_PROT_WRITE ) ? 'w' : '-',
5831// (prot & VM_PROT_EXECUTE) ? 'x' : '-');
5832
5833 if (prot != 0)
5834 {
Jason Molendad20359d2014-11-11 10:59:15 +00005835 uint32_t cmd_type = LC_SEGMENT_64;
5836 uint32_t segment_size = sizeof (segment_command_64);
5837 if (addr_byte_size == 4)
5838 {
5839 cmd_type = LC_SEGMENT;
5840 segment_size = sizeof (segment_command);
5841 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005842 segment_command_64 segment = {
Jason Molendad20359d2014-11-11 10:59:15 +00005843 cmd_type, // uint32_t cmd;
5844 segment_size, // uint32_t cmdsize;
Greg Claytona2715cf2014-06-13 00:54:12 +00005845 {0}, // char segname[16];
Jason Molendad20359d2014-11-11 10:59:15 +00005846 addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
5847 size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
5848 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O
5849 size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
Greg Claytona2715cf2014-06-13 00:54:12 +00005850 prot, // uint32_t maxprot;
5851 prot, // uint32_t initprot;
5852 0, // uint32_t nsects;
5853 0 }; // uint32_t flags;
5854 segment_load_commands.push_back(segment);
5855 }
5856 else
5857 {
5858 // No protections and a size of 1 used to be returned from old
5859 // debugservers when we asked about a region that was past the
5860 // last memory region and it indicates the end...
5861 if (size == 1)
5862 break;
5863 }
5864
5865 range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info);
5866 if (range_error.Fail())
5867 break;
5868 }
5869
Greg Claytona2715cf2014-06-13 00:54:12 +00005870 StreamString buffer (Stream::eBinary,
5871 addr_byte_size,
5872 byte_order);
5873
5874 mach_header_64 mach_header;
Jason Molendad20359d2014-11-11 10:59:15 +00005875 if (addr_byte_size == 8)
5876 {
5877 mach_header.magic = MH_MAGIC_64;
5878 }
5879 else
5880 {
5881 mach_header.magic = MH_MAGIC;
5882 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005883 mach_header.cputype = target_arch.GetMachOCPUType();
5884 mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
5885 mach_header.filetype = MH_CORE;
5886 mach_header.ncmds = segment_load_commands.size();
5887 mach_header.flags = 0;
5888 mach_header.reserved = 0;
5889 ThreadList &thread_list = process_sp->GetThreadList();
5890 const uint32_t num_threads = thread_list.GetSize();
5891
5892 // Make an array of LC_THREAD data items. Each one contains
5893 // the contents of the LC_THREAD load command. The data doesn't
5894 // contain the load command + load command size, we will
5895 // add the load command and load command size as we emit the data.
5896 std::vector<StreamString> LC_THREAD_datas(num_threads);
5897 for (auto &LC_THREAD_data : LC_THREAD_datas)
5898 {
5899 LC_THREAD_data.GetFlags().Set(Stream::eBinary);
5900 LC_THREAD_data.SetAddressByteSize(addr_byte_size);
5901 LC_THREAD_data.SetByteOrder(byte_order);
5902 }
5903 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
5904 {
5905 ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx));
5906 if (thread_sp)
5907 {
5908 switch (mach_header.cputype)
5909 {
Jason Molenda22952582014-11-12 01:11:36 +00005910 case llvm::MachO::CPU_TYPE_ARM64:
5911 RegisterContextDarwin_arm64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005912 break;
Jason Molenda22952582014-11-12 01:11:36 +00005913
5914 case llvm::MachO::CPU_TYPE_ARM:
5915 RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5916 break;
5917
Greg Claytona2715cf2014-06-13 00:54:12 +00005918 case llvm::MachO::CPU_TYPE_I386:
Jason Molendad20359d2014-11-11 10:59:15 +00005919 RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
Greg Claytona2715cf2014-06-13 00:54:12 +00005920 break;
5921
5922 case llvm::MachO::CPU_TYPE_X86_64:
5923 RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
5924 break;
5925 }
5926
5927 }
5928 }
5929
5930 // The size of the load command is the size of the segments...
Jason Molendad20359d2014-11-11 10:59:15 +00005931 if (addr_byte_size == 8)
5932 {
5933 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64);
5934 }
5935 else
5936 {
5937 mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command);
5938 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005939
5940 // and the size of all LC_THREAD load command
5941 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5942 {
Greg Claytone37df2e2014-09-16 20:50:29 +00005943 ++mach_header.ncmds;
Greg Claytona2715cf2014-06-13 00:54:12 +00005944 mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
5945 }
5946
5947 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",
5948 mach_header.magic,
5949 mach_header.cputype,
5950 mach_header.cpusubtype,
5951 mach_header.filetype,
5952 mach_header.ncmds,
5953 mach_header.sizeofcmds,
5954 mach_header.flags,
5955 mach_header.reserved);
5956
5957 // Write the mach header
5958 buffer.PutHex32(mach_header.magic);
5959 buffer.PutHex32(mach_header.cputype);
5960 buffer.PutHex32(mach_header.cpusubtype);
5961 buffer.PutHex32(mach_header.filetype);
5962 buffer.PutHex32(mach_header.ncmds);
5963 buffer.PutHex32(mach_header.sizeofcmds);
5964 buffer.PutHex32(mach_header.flags);
Jason Molendad20359d2014-11-11 10:59:15 +00005965 if (addr_byte_size == 8)
5966 {
5967 buffer.PutHex32(mach_header.reserved);
5968 }
Greg Claytona2715cf2014-06-13 00:54:12 +00005969
5970 // Skip the mach header and all load commands and align to the next
5971 // 0x1000 byte boundary
5972 addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
5973 if (file_offset & 0x00000fff)
5974 {
5975 file_offset += 0x00001000ull;
5976 file_offset &= (~0x00001000ull + 1);
5977 }
5978
5979 for (auto &segment : segment_load_commands)
5980 {
5981 segment.fileoff = file_offset;
5982 file_offset += segment.filesize;
5983 }
5984
5985 // Write out all of the LC_THREAD load commands
5986 for (const auto &LC_THREAD_data : LC_THREAD_datas)
5987 {
5988 const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
5989 buffer.PutHex32(LC_THREAD);
5990 buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
5991 buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size);
5992 }
5993
5994 // Write out all of the segment load commands
5995 for (const auto &segment : segment_load_commands)
5996 {
5997 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",
5998 segment.cmd,
5999 segment.cmdsize,
6000 segment.vmaddr,
6001 segment.vmaddr + segment.vmsize,
6002 segment.fileoff,
6003 segment.filesize,
6004 segment.maxprot,
6005 segment.initprot,
6006 segment.nsects,
6007 segment.flags);
6008
6009 buffer.PutHex32(segment.cmd);
6010 buffer.PutHex32(segment.cmdsize);
6011 buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
Jason Molendad20359d2014-11-11 10:59:15 +00006012 if (addr_byte_size == 8)
6013 {
6014 buffer.PutHex64(segment.vmaddr);
6015 buffer.PutHex64(segment.vmsize);
6016 buffer.PutHex64(segment.fileoff);
6017 buffer.PutHex64(segment.filesize);
6018 }
6019 else
6020 {
6021 buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
6022 buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
6023 buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
6024 buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
6025 }
Greg Claytona2715cf2014-06-13 00:54:12 +00006026 buffer.PutHex32(segment.maxprot);
6027 buffer.PutHex32(segment.initprot);
6028 buffer.PutHex32(segment.nsects);
6029 buffer.PutHex32(segment.flags);
6030 }
6031
6032 File core_file;
6033 std::string core_file_path(outfile.GetPath());
6034 error = core_file.Open(core_file_path.c_str(),
6035 File::eOpenOptionWrite |
6036 File::eOpenOptionTruncate |
6037 File::eOpenOptionCanCreate);
6038 if (error.Success())
6039 {
6040 // Read 1 page at a time
6041 uint8_t bytes[0x1000];
6042 // Write the mach header and load commands out to the core file
6043 size_t bytes_written = buffer.GetString().size();
6044 error = core_file.Write(buffer.GetString().data(), bytes_written);
6045 if (error.Success())
6046 {
6047 // Now write the file data for all memory segments in the process
6048 for (const auto &segment : segment_load_commands)
6049 {
David Majnemerb98a5e02014-07-24 00:24:12 +00006050 if (core_file.SeekFromStart(segment.fileoff) == -1)
Greg Claytona2715cf2014-06-13 00:54:12 +00006051 {
6052 error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str());
6053 break;
6054 }
6055
Jason Molendad20359d2014-11-11 10:59:15 +00006056 printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr);
Greg Claytona2715cf2014-06-13 00:54:12 +00006057 addr_t bytes_left = segment.vmsize;
6058 addr_t addr = segment.vmaddr;
6059 Error memory_read_error;
6060 while (bytes_left > 0 && error.Success())
6061 {
6062 const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
6063 const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error);
6064 if (bytes_read == bytes_to_read)
6065 {
6066 size_t bytes_written = bytes_read;
6067 error = core_file.Write(bytes, bytes_written);
6068 bytes_left -= bytes_read;
6069 addr += bytes_read;
6070 }
6071 else
6072 {
6073 // Some pages within regions are not readable, those
6074 // should be zero filled
6075 memset (bytes, 0, bytes_to_read);
6076 size_t bytes_written = bytes_to_read;
6077 error = core_file.Write(bytes, bytes_written);
6078 bytes_left -= bytes_to_read;
6079 addr += bytes_to_read;
6080 }
6081 }
6082 }
6083 }
6084 }
6085 }
6086 else
6087 {
6088 error.SetErrorString("process doesn't support getting memory region info");
6089 }
6090 }
6091 return true; // This is the right plug to handle saving core files for this process
6092 }
6093 }
6094 return false;
6095}