blob: f44f1856ace8fe0676f65e553b634803d6bafee6 [file] [log] [blame]
Chris Lattner24943d22010-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
Greg Clayton3f69eac2011-12-03 02:30:59 +000010#include "llvm/ADT/StringRef.h"
Jim Ingham28775942011-03-07 23:44:08 +000011#include "llvm/Support/MachO.h"
12
Chris Lattner24943d22010-06-08 16:52:24 +000013#include "ObjectFileMachO.h"
14
Greg Claytond4330e62012-09-05 01:38:55 +000015#include "lldb/lldb-private-log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Core/ArchSpec.h"
17#include "lldb/Core/DataBuffer.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Core/FileSpecList.h"
Greg Claytond4330e62012-09-05 01:38:55 +000019#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Core/Module.h"
21#include "lldb/Core/PluginManager.h"
Greg Clayton6f7f8da2012-04-24 03:06:13 +000022#include "lldb/Core/RangeMap.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Core/Section.h"
24#include "lldb/Core/StreamFile.h"
25#include "lldb/Core/StreamString.h"
26#include "lldb/Core/Timer.h"
27#include "lldb/Core/UUID.h"
Greg Claytondf6dc882012-01-05 03:57:59 +000028#include "lldb/Host/Host.h"
29#include "lldb/Host/FileSpec.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000030#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031#include "lldb/Symbol/ObjectFile.h"
Greg Clayton29021d32012-04-18 05:19:20 +000032#include "lldb/Target/Platform.h"
Greg Claytonb5a8f142012-02-05 02:38:54 +000033#include "lldb/Target/Process.h"
Greg Clayton29021d32012-04-18 05:19:20 +000034#include "lldb/Target/Target.h"
Greg Clayton9ce95382012-02-13 23:10:39 +000035#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
36#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
Greg Clayton46c9a352012-02-09 06:16:32 +000037#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038
Chris Lattner24943d22010-06-08 16:52:24 +000039using namespace lldb;
40using namespace lldb_private;
Greg Clayton1674b122010-07-21 22:12:05 +000041using namespace llvm::MachO;
Chris Lattner24943d22010-06-08 16:52:24 +000042
Greg Clayton46c9a352012-02-09 06:16:32 +000043class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
44{
45public:
46 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
47 RegisterContextDarwin_x86_64 (thread, 0)
48 {
49 SetRegisterDataFrom_LC_THREAD (data);
50 }
51
52 virtual void
53 InvalidateAllRegisters ()
54 {
55 // Do nothing... registers are always valid...
56 }
57
58 void
59 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
60 {
Greg Clayton46c9a352012-02-09 06:16:32 +000061 uint32_t offset = 0;
62 SetError (GPRRegSet, Read, -1);
63 SetError (FPURegSet, Read, -1);
64 SetError (EXCRegSet, Read, -1);
Greg Clayton9ce95382012-02-13 23:10:39 +000065 bool done = false;
66
67 while (!done)
Greg Clayton46c9a352012-02-09 06:16:32 +000068 {
Greg Clayton9ce95382012-02-13 23:10:39 +000069 int flavor = data.GetU32 (&offset);
70 if (flavor == 0)
71 done = true;
72 else
Greg Clayton46c9a352012-02-09 06:16:32 +000073 {
Greg Clayton9ce95382012-02-13 23:10:39 +000074 uint32_t i;
75 uint32_t count = data.GetU32 (&offset);
76 switch (flavor)
77 {
78 case GPRRegSet:
79 for (i=0; i<count; ++i)
80 (&gpr.rax)[i] = data.GetU64(&offset);
81 SetError (GPRRegSet, Read, 0);
82 done = true;
83
84 break;
85 case FPURegSet:
86 // TODO: fill in FPU regs....
87 //SetError (FPURegSet, Read, -1);
88 done = true;
89
90 break;
91 case EXCRegSet:
92 exc.trapno = data.GetU32(&offset);
93 exc.err = data.GetU32(&offset);
94 exc.faultvaddr = data.GetU64(&offset);
95 SetError (EXCRegSet, Read, 0);
96 done = true;
97 break;
98 case 7:
99 case 8:
100 case 9:
101 // fancy flavors that encapsulate of the the above
102 // falvors...
103 break;
104
105 default:
106 done = true;
107 break;
108 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000109 }
Greg Clayton9ce95382012-02-13 23:10:39 +0000110 }
111 }
112protected:
113 virtual int
114 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
115 {
116 return 0;
117 }
118
119 virtual int
120 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
121 {
122 return 0;
123 }
124
125 virtual int
126 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
127 {
128 return 0;
129 }
130
131 virtual int
132 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
133 {
134 return 0;
135 }
136
137 virtual int
138 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
139 {
140 return 0;
141 }
142
143 virtual int
144 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
145 {
146 return 0;
147 }
148};
Greg Clayton46c9a352012-02-09 06:16:32 +0000149
Greg Clayton9ce95382012-02-13 23:10:39 +0000150
151class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
152{
153public:
154 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
155 RegisterContextDarwin_i386 (thread, 0)
156 {
157 SetRegisterDataFrom_LC_THREAD (data);
158 }
159
160 virtual void
161 InvalidateAllRegisters ()
162 {
163 // Do nothing... registers are always valid...
164 }
165
166 void
167 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
168 {
169 uint32_t offset = 0;
170 SetError (GPRRegSet, Read, -1);
171 SetError (FPURegSet, Read, -1);
172 SetError (EXCRegSet, Read, -1);
173 bool done = false;
174
175 while (!done)
176 {
177 int flavor = data.GetU32 (&offset);
178 if (flavor == 0)
179 done = true;
180 else
Greg Clayton46c9a352012-02-09 06:16:32 +0000181 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000182 uint32_t i;
183 uint32_t count = data.GetU32 (&offset);
184 switch (flavor)
185 {
186 case GPRRegSet:
187 for (i=0; i<count; ++i)
188 (&gpr.eax)[i] = data.GetU32(&offset);
189 SetError (GPRRegSet, Read, 0);
190 done = true;
191
192 break;
193 case FPURegSet:
194 // TODO: fill in FPU regs....
195 //SetError (FPURegSet, Read, -1);
196 done = true;
197
198 break;
199 case EXCRegSet:
200 exc.trapno = data.GetU32(&offset);
201 exc.err = data.GetU32(&offset);
202 exc.faultvaddr = data.GetU32(&offset);
203 SetError (EXCRegSet, Read, 0);
204 done = true;
205 break;
206 case 7:
207 case 8:
208 case 9:
209 // fancy flavors that encapsulate of the the above
210 // falvors...
211 break;
212
213 default:
214 done = true;
215 break;
216 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000217 }
218 }
219 }
220protected:
221 virtual int
222 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
223 {
224 return 0;
225 }
226
227 virtual int
228 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
229 {
230 return 0;
231 }
232
233 virtual int
234 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
235 {
236 return 0;
237 }
238
239 virtual int
240 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
241 {
242 return 0;
243 }
244
245 virtual int
246 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
247 {
248 return 0;
249 }
250
251 virtual int
252 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
253 {
254 return 0;
255 }
256};
257
Greg Clayton9ce95382012-02-13 23:10:39 +0000258class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
259{
260public:
261 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
262 RegisterContextDarwin_arm (thread, 0)
263 {
264 SetRegisterDataFrom_LC_THREAD (data);
265 }
266
267 virtual void
268 InvalidateAllRegisters ()
269 {
270 // Do nothing... registers are always valid...
271 }
272
273 void
274 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
275 {
276 uint32_t offset = 0;
277 SetError (GPRRegSet, Read, -1);
278 SetError (FPURegSet, Read, -1);
279 SetError (EXCRegSet, Read, -1);
280 int flavor = data.GetU32 (&offset);
281 uint32_t count = data.GetU32 (&offset);
282 switch (flavor)
283 {
284 case GPRRegSet:
285 for (uint32_t i=0; i<count; ++i)
286 gpr.r[i] = data.GetU32(&offset);
287 SetError (GPRRegSet, Read, 0);
288 break;
289 case FPURegSet:
290 // TODO: fill in FPU regs....
291 //SetError (FPURegSet, Read, -1);
292 break;
293 case EXCRegSet:
294 exc.exception = data.GetU32(&offset);
295 exc.fsr = data.GetU32(&offset);
296 exc.far = data.GetU32(&offset);
297 SetError (EXCRegSet, Read, 0);
298 break;
299 }
300 }
301protected:
302 virtual int
303 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
304 {
305 return 0;
306 }
307
308 virtual int
309 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
310 {
311 return 0;
312 }
313
314 virtual int
315 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
316 {
317 return 0;
318 }
319
320 virtual int
321 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
322 {
323 return 0;
324 }
325
326 virtual int
327 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
328 {
329 return 0;
330 }
331
332 virtual int
333 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
334 {
335 return 0;
336 }
337};
338
Greg Claytonb1888f22011-03-19 01:12:21 +0000339#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner24943d22010-06-08 16:52:24 +0000340
341void
342ObjectFileMachO::Initialize()
343{
344 PluginManager::RegisterPlugin (GetPluginNameStatic(),
345 GetPluginDescriptionStatic(),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000346 CreateInstance,
347 CreateMemoryInstance);
Chris Lattner24943d22010-06-08 16:52:24 +0000348}
349
350void
351ObjectFileMachO::Terminate()
352{
353 PluginManager::UnregisterPlugin (CreateInstance);
354}
355
356
357const char *
358ObjectFileMachO::GetPluginNameStatic()
359{
360 return "object-file.mach-o";
361}
362
363const char *
364ObjectFileMachO::GetPluginDescriptionStatic()
365{
366 return "Mach-o object file reader (32 and 64 bit)";
367}
368
369
370ObjectFile *
Greg Clayton3508c382012-02-24 01:59:29 +0000371ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length)
Chris Lattner24943d22010-06-08 16:52:24 +0000372{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000373 if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length))
Chris Lattner24943d22010-06-08 16:52:24 +0000374 {
Greg Clayton3508c382012-02-24 01:59:29 +0000375 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, file, offset, length));
Chris Lattner24943d22010-06-08 16:52:24 +0000376 if (objfile_ap.get() && objfile_ap->ParseHeader())
377 return objfile_ap.release();
378 }
379 return NULL;
380}
381
Greg Claytonb5a8f142012-02-05 02:38:54 +0000382ObjectFile *
Greg Clayton3508c382012-02-24 01:59:29 +0000383ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000384 DataBufferSP& data_sp,
385 const ProcessSP &process_sp,
386 lldb::addr_t header_addr)
387{
388 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
389 {
Greg Clayton3508c382012-02-24 01:59:29 +0000390 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonb5a8f142012-02-05 02:38:54 +0000391 if (objfile_ap.get() && objfile_ap->ParseHeader())
392 return objfile_ap.release();
393 }
394 return NULL;
395}
396
397
398const ConstString &
399ObjectFileMachO::GetSegmentNameTEXT()
400{
401 static ConstString g_segment_name_TEXT ("__TEXT");
402 return g_segment_name_TEXT;
403}
404
405const ConstString &
406ObjectFileMachO::GetSegmentNameDATA()
407{
408 static ConstString g_segment_name_DATA ("__DATA");
409 return g_segment_name_DATA;
410}
411
412const ConstString &
413ObjectFileMachO::GetSegmentNameOBJC()
414{
415 static ConstString g_segment_name_OBJC ("__OBJC");
416 return g_segment_name_OBJC;
417}
418
419const ConstString &
420ObjectFileMachO::GetSegmentNameLINKEDIT()
421{
422 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
423 return g_section_name_LINKEDIT;
424}
425
426const ConstString &
427ObjectFileMachO::GetSectionNameEHFrame()
428{
429 static ConstString g_section_name_eh_frame ("__eh_frame");
430 return g_section_name_eh_frame;
431}
432
433
Chris Lattner24943d22010-06-08 16:52:24 +0000434
435static uint32_t
436MachHeaderSizeFromMagic(uint32_t magic)
437{
438 switch (magic)
439 {
Greg Clayton1674b122010-07-21 22:12:05 +0000440 case HeaderMagic32:
441 case HeaderMagic32Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000442 return sizeof(struct mach_header);
443
Greg Clayton1674b122010-07-21 22:12:05 +0000444 case HeaderMagic64:
445 case HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000446 return sizeof(struct mach_header_64);
447 break;
448
449 default:
450 break;
451 }
452 return 0;
453}
454
455
456bool
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000457ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
458 lldb::addr_t data_offset,
459 lldb::addr_t data_length)
Chris Lattner24943d22010-06-08 16:52:24 +0000460{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000461 DataExtractor data;
462 data.SetData (data_sp, data_offset, data_length);
Chris Lattner24943d22010-06-08 16:52:24 +0000463 uint32_t offset = 0;
464 uint32_t magic = data.GetU32(&offset);
465 return MachHeaderSizeFromMagic(magic) != 0;
466}
467
468
Greg Clayton3508c382012-02-24 01:59:29 +0000469ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) :
470 ObjectFile(module_sp, file, offset, length, data_sp),
Chris Lattner24943d22010-06-08 16:52:24 +0000471 m_sections_ap(),
Jim Ingham28775942011-03-07 23:44:08 +0000472 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000473 m_mach_segments(),
474 m_mach_sections(),
475 m_entry_point_address(),
476 m_thread_context_offsets(),
477 m_thread_context_offsets_valid(false)
Chris Lattner24943d22010-06-08 16:52:24 +0000478{
Greg Claytonddff7cc2011-02-04 21:13:05 +0000479 ::memset (&m_header, 0, sizeof(m_header));
480 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner24943d22010-06-08 16:52:24 +0000481}
482
Greg Clayton3508c382012-02-24 01:59:29 +0000483ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000484 lldb::DataBufferSP& header_data_sp,
485 const lldb::ProcessSP &process_sp,
486 lldb::addr_t header_addr) :
Greg Clayton3508c382012-02-24 01:59:29 +0000487 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000488 m_sections_ap(),
489 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000490 m_mach_segments(),
491 m_mach_sections(),
492 m_entry_point_address(),
493 m_thread_context_offsets(),
494 m_thread_context_offsets_valid(false)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000495{
496 ::memset (&m_header, 0, sizeof(m_header));
497 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
498}
Chris Lattner24943d22010-06-08 16:52:24 +0000499
500ObjectFileMachO::~ObjectFileMachO()
501{
502}
503
504
505bool
506ObjectFileMachO::ParseHeader ()
507{
Greg Clayton9482f052012-03-13 23:14:29 +0000508 ModuleSP module_sp(GetModule());
509 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000510 {
Greg Clayton9482f052012-03-13 23:14:29 +0000511 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
512 bool can_parse = false;
513 uint32_t offset = 0;
Greg Claytoncd548032011-02-01 01:31:41 +0000514 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Greg Clayton9482f052012-03-13 23:14:29 +0000515 // Leave magic in the original byte order
516 m_header.magic = m_data.GetU32(&offset);
517 switch (m_header.magic)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000518 {
Greg Clayton9482f052012-03-13 23:14:29 +0000519 case HeaderMagic32:
520 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
521 m_data.SetAddressByteSize(4);
522 can_parse = true;
523 break;
524
525 case HeaderMagic64:
526 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
527 m_data.SetAddressByteSize(8);
528 can_parse = true;
529 break;
530
531 case HeaderMagic32Swapped:
532 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
533 m_data.SetAddressByteSize(4);
534 can_parse = true;
535 break;
536
537 case HeaderMagic64Swapped:
538 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
539 m_data.SetAddressByteSize(8);
540 can_parse = true;
541 break;
542
543 default:
544 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +0000545 }
Greg Clayton9482f052012-03-13 23:14:29 +0000546
547 if (can_parse)
548 {
549 m_data.GetU32(&offset, &m_header.cputype, 6);
550
551 ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
552
553 if (SetModulesArchitecture (mach_arch))
554 {
555 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
556 if (m_data.GetByteSize() < header_and_lc_size)
557 {
558 DataBufferSP data_sp;
559 ProcessSP process_sp (m_process_wp.lock());
560 if (process_sp)
561 {
562 data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
563 }
564 else
565 {
566 // Read in all only the load command data from the file on disk
567 data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
568 if (data_sp->GetByteSize() != header_and_lc_size)
569 return false;
570 }
571 if (data_sp)
572 m_data.SetData (data_sp);
573 }
574 }
575 return true;
576 }
577 else
578 {
579 memset(&m_header, 0, sizeof(struct mach_header));
580 }
Chris Lattner24943d22010-06-08 16:52:24 +0000581 }
582 return false;
583}
584
585
586ByteOrder
587ObjectFileMachO::GetByteOrder () const
588{
Chris Lattner24943d22010-06-08 16:52:24 +0000589 return m_data.GetByteOrder ();
590}
591
Jim Ingham7508e732010-08-09 23:31:02 +0000592bool
593ObjectFileMachO::IsExecutable() const
594{
595 return m_header.filetype == HeaderFileTypeExecutable;
596}
Chris Lattner24943d22010-06-08 16:52:24 +0000597
598size_t
599ObjectFileMachO::GetAddressByteSize () const
600{
Chris Lattner24943d22010-06-08 16:52:24 +0000601 return m_data.GetAddressByteSize ();
602}
603
Greg Claytonb3448432011-03-24 21:19:54 +0000604AddressClass
Greg Claytonb1888f22011-03-19 01:12:21 +0000605ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
606{
607 Symtab *symtab = GetSymtab();
608 if (symtab)
609 {
610 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
611 if (symbol)
612 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000613 if (symbol->ValueIsAddress())
Greg Claytonb1888f22011-03-19 01:12:21 +0000614 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000615 SectionSP section_sp (symbol->GetAddress().GetSection());
Greg Clayton3508c382012-02-24 01:59:29 +0000616 if (section_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000617 {
Greg Clayton3508c382012-02-24 01:59:29 +0000618 const SectionType section_type = section_sp->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000619 switch (section_type)
620 {
621 case eSectionTypeInvalid: return eAddressClassUnknown;
622 case eSectionTypeCode:
623 if (m_header.cputype == llvm::MachO::CPUTypeARM)
624 {
625 // For ARM we have a bit in the n_desc field of the symbol
626 // that tells us ARM/Thumb which is bit 0x0008.
627 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
628 return eAddressClassCodeAlternateISA;
629 }
630 return eAddressClassCode;
631
632 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000633 case eSectionTypeData:
634 case eSectionTypeDataCString:
635 case eSectionTypeDataCStringPointers:
636 case eSectionTypeDataSymbolAddress:
637 case eSectionTypeData4:
638 case eSectionTypeData8:
639 case eSectionTypeData16:
640 case eSectionTypeDataPointers:
641 case eSectionTypeZeroFill:
642 case eSectionTypeDataObjCMessageRefs:
643 case eSectionTypeDataObjCCFStrings:
644 return eAddressClassData;
645 case eSectionTypeDebug:
646 case eSectionTypeDWARFDebugAbbrev:
647 case eSectionTypeDWARFDebugAranges:
648 case eSectionTypeDWARFDebugFrame:
649 case eSectionTypeDWARFDebugInfo:
650 case eSectionTypeDWARFDebugLine:
651 case eSectionTypeDWARFDebugLoc:
652 case eSectionTypeDWARFDebugMacInfo:
653 case eSectionTypeDWARFDebugPubNames:
654 case eSectionTypeDWARFDebugPubTypes:
655 case eSectionTypeDWARFDebugRanges:
656 case eSectionTypeDWARFDebugStr:
657 case eSectionTypeDWARFAppleNames:
658 case eSectionTypeDWARFAppleTypes:
659 case eSectionTypeDWARFAppleNamespaces:
660 case eSectionTypeDWARFAppleObjC:
661 return eAddressClassDebug;
Greg Claytonb1888f22011-03-19 01:12:21 +0000662 case eSectionTypeEHFrame: return eAddressClassRuntime;
663 case eSectionTypeOther: return eAddressClassUnknown;
664 }
665 }
666 }
667
Greg Claytonb3448432011-03-24 21:19:54 +0000668 const SymbolType symbol_type = symbol->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000669 switch (symbol_type)
670 {
671 case eSymbolTypeAny: return eAddressClassUnknown;
672 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Greg Claytonb1888f22011-03-19 01:12:21 +0000673
674 case eSymbolTypeCode:
675 case eSymbolTypeTrampoline:
676 if (m_header.cputype == llvm::MachO::CPUTypeARM)
677 {
678 // For ARM we have a bit in the n_desc field of the symbol
679 // that tells us ARM/Thumb which is bit 0x0008.
680 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
681 return eAddressClassCodeAlternateISA;
682 }
683 return eAddressClassCode;
684
685 case eSymbolTypeData: return eAddressClassData;
686 case eSymbolTypeRuntime: return eAddressClassRuntime;
687 case eSymbolTypeException: return eAddressClassRuntime;
688 case eSymbolTypeSourceFile: return eAddressClassDebug;
689 case eSymbolTypeHeaderFile: return eAddressClassDebug;
690 case eSymbolTypeObjectFile: return eAddressClassDebug;
691 case eSymbolTypeCommonBlock: return eAddressClassDebug;
692 case eSymbolTypeBlock: return eAddressClassDebug;
693 case eSymbolTypeLocal: return eAddressClassData;
694 case eSymbolTypeParam: return eAddressClassData;
695 case eSymbolTypeVariable: return eAddressClassData;
696 case eSymbolTypeVariableType: return eAddressClassDebug;
697 case eSymbolTypeLineEntry: return eAddressClassDebug;
698 case eSymbolTypeLineHeader: return eAddressClassDebug;
699 case eSymbolTypeScopeBegin: return eAddressClassDebug;
700 case eSymbolTypeScopeEnd: return eAddressClassDebug;
701 case eSymbolTypeAdditional: return eAddressClassUnknown;
702 case eSymbolTypeCompiler: return eAddressClassDebug;
703 case eSymbolTypeInstrumentation:return eAddressClassDebug;
704 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton3f69eac2011-12-03 02:30:59 +0000705 case eSymbolTypeObjCClass: return eAddressClassRuntime;
706 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
707 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Claytonb1888f22011-03-19 01:12:21 +0000708 }
709 }
710 }
711 return eAddressClassUnknown;
712}
Chris Lattner24943d22010-06-08 16:52:24 +0000713
714Symtab *
715ObjectFileMachO::GetSymtab()
716{
Greg Clayton9482f052012-03-13 23:14:29 +0000717 ModuleSP module_sp(GetModule());
718 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000719 {
Greg Clayton9482f052012-03-13 23:14:29 +0000720 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
721 if (m_symtab_ap.get() == NULL)
722 {
723 m_symtab_ap.reset(new Symtab(this));
724 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
725 ParseSymtab (true);
726 m_symtab_ap->Finalize ();
727 }
Chris Lattner24943d22010-06-08 16:52:24 +0000728 }
729 return m_symtab_ap.get();
730}
731
732
733SectionList *
734ObjectFileMachO::GetSectionList()
735{
Greg Clayton9482f052012-03-13 23:14:29 +0000736 ModuleSP module_sp(GetModule());
737 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000738 {
Greg Clayton9482f052012-03-13 23:14:29 +0000739 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
740 if (m_sections_ap.get() == NULL)
741 {
742 m_sections_ap.reset(new SectionList());
743 ParseSections();
744 }
Chris Lattner24943d22010-06-08 16:52:24 +0000745 }
746 return m_sections_ap.get();
747}
748
749
750size_t
751ObjectFileMachO::ParseSections ()
752{
753 lldb::user_id_t segID = 0;
754 lldb::user_id_t sectID = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000755 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
756 uint32_t i;
Greg Clayton46c9a352012-02-09 06:16:32 +0000757 const bool is_core = GetType() == eTypeCoreFile;
Chris Lattner24943d22010-06-08 16:52:24 +0000758 //bool dump_sections = false;
Greg Clayton3508c382012-02-24 01:59:29 +0000759 ModuleSP module_sp (GetModule());
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000760 // First look up any LC_ENCRYPTION_INFO load commands
761 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
762 EncryptedFileRanges encrypted_file_ranges;
Greg Clayton54e33712012-05-25 18:09:55 +0000763 encryption_info_command encryption_cmd;
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000764 for (i=0; i<m_header.ncmds; ++i)
765 {
766 const uint32_t load_cmd_offset = offset;
Greg Clayton54e33712012-05-25 18:09:55 +0000767 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000768 break;
769
Greg Clayton54e33712012-05-25 18:09:55 +0000770 if (encryption_cmd.cmd == LoadCommandEncryptionInfo)
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000771 {
Greg Clayton54e33712012-05-25 18:09:55 +0000772 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
773 {
774 if (encryption_cmd.cryptid != 0)
775 {
776 EncryptedFileRanges::Entry entry;
777 entry.SetRangeBase(encryption_cmd.cryptoff);
778 entry.SetByteSize(encryption_cmd.cryptsize);
779 encrypted_file_ranges.Append(entry);
780 }
781 }
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000782 }
Greg Clayton54e33712012-05-25 18:09:55 +0000783 offset = load_cmd_offset + encryption_cmd.cmdsize;
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000784 }
785
786 offset = MachHeaderSizeFromMagic(m_header.magic);
787
Greg Clayton54e33712012-05-25 18:09:55 +0000788 struct segment_command_64 load_cmd;
Chris Lattner24943d22010-06-08 16:52:24 +0000789 for (i=0; i<m_header.ncmds; ++i)
790 {
791 const uint32_t load_cmd_offset = offset;
792 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
793 break;
794
Greg Clayton1674b122010-07-21 22:12:05 +0000795 if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
Chris Lattner24943d22010-06-08 16:52:24 +0000796 {
797 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
798 {
799 load_cmd.vmaddr = m_data.GetAddress(&offset);
800 load_cmd.vmsize = m_data.GetAddress(&offset);
801 load_cmd.fileoff = m_data.GetAddress(&offset);
802 load_cmd.filesize = m_data.GetAddress(&offset);
803 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
804 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000805
806 const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
807
Chris Lattner24943d22010-06-08 16:52:24 +0000808 // Keep a list of mach segments around in case we need to
809 // get at data that isn't stored in the abstracted Sections.
810 m_mach_segments.push_back (load_cmd);
811
812 ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
813 // Use a segment ID of the segment index shifted left by 8 so they
814 // never conflict with any of the sections.
815 SectionSP segment_sp;
Greg Clayton46c9a352012-02-09 06:16:32 +0000816 if (segment_name || is_core)
Chris Lattner24943d22010-06-08 16:52:24 +0000817 {
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000818 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
Chris Lattner24943d22010-06-08 16:52:24 +0000819 ++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
820 segment_name, // Name of this section
821 eSectionTypeContainer, // This section is a container of other sections.
822 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
823 load_cmd.vmsize, // VM size in bytes of this section
824 load_cmd.fileoff, // Offset to the data for this section in the file
825 load_cmd.filesize, // Size in bytes of this section as found in the the file
826 load_cmd.flags)); // Flags for this section
827
Greg Clayton68ca8232011-01-25 02:58:48 +0000828 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000829 m_sections_ap->AddSection(segment_sp);
830 }
831
832 struct section_64 sect64;
Greg Claytonddff7cc2011-02-04 21:13:05 +0000833 ::memset (&sect64, 0, sizeof(sect64));
Chris Lattner24943d22010-06-08 16:52:24 +0000834 // Push a section into our mach sections for the section at
Greg Clayton6af4fad2010-10-06 01:26:32 +0000835 // index zero (NListSectionNoSection) if we don't have any
836 // mach sections yet...
837 if (m_mach_sections.empty())
838 m_mach_sections.push_back(sect64);
Chris Lattner24943d22010-06-08 16:52:24 +0000839 uint32_t segment_sect_idx;
840 const lldb::user_id_t first_segment_sectID = sectID + 1;
841
842
Greg Clayton1674b122010-07-21 22:12:05 +0000843 const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
Chris Lattner24943d22010-06-08 16:52:24 +0000844 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
845 {
846 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
847 break;
848 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
849 break;
850 sect64.addr = m_data.GetAddress(&offset);
851 sect64.size = m_data.GetAddress(&offset);
852
853 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
854 break;
855
856 // Keep a list of mach sections around in case we need to
857 // get at data that isn't stored in the abstracted Sections.
858 m_mach_sections.push_back (sect64);
859
860 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
861 if (!segment_name)
862 {
863 // We have a segment with no name so we need to conjure up
864 // segments that correspond to the section's segname if there
865 // isn't already such a section. If there is such a section,
866 // we resize the section so that it spans all sections.
867 // We also mark these sections as fake so address matches don't
868 // hit if they land in the gaps between the child sections.
869 segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
870 segment_sp = m_sections_ap->FindSectionByName (segment_name);
871 if (segment_sp.get())
872 {
873 Section *segment = segment_sp.get();
874 // Grow the section size as needed.
875 const lldb::addr_t sect64_min_addr = sect64.addr;
876 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
877 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
878 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
879 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
880 if (sect64_min_addr >= curr_seg_min_addr)
881 {
882 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
883 // Only grow the section size if needed
884 if (new_seg_byte_size > curr_seg_byte_size)
885 segment->SetByteSize (new_seg_byte_size);
886 }
887 else
888 {
889 // We need to change the base address of the segment and
890 // adjust the child section offsets for all existing children.
891 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
892 segment->Slide(slide_amount, false);
Sean Callanan716a6642012-06-08 02:16:08 +0000893 segment->GetChildren().Slide(-slide_amount, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000894 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
895 }
Greg Clayton661825b2010-06-28 23:51:11 +0000896
897 // Grow the section size as needed.
898 if (sect64.offset)
899 {
900 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
901 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
902
903 const lldb::addr_t section_min_file_offset = sect64.offset;
904 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
905 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
906 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
907 segment->SetFileOffset (new_file_offset);
908 segment->SetFileSize (new_file_size);
909 }
Chris Lattner24943d22010-06-08 16:52:24 +0000910 }
911 else
912 {
913 // Create a fake section for the section's named segment
Greg Clayton3508c382012-02-24 01:59:29 +0000914 segment_sp.reset(new Section (segment_sp, // Parent section
915 module_sp, // Module to which this section belongs
916 ++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
917 segment_name, // Name of this section
918 eSectionTypeContainer, // This section is a container of other sections.
919 sect64.addr, // File VM address == addresses as they are found in the object file
920 sect64.size, // VM size in bytes of this section
921 sect64.offset, // Offset to the data for this section in the file
922 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
923 load_cmd.flags)); // Flags for this section
Chris Lattner24943d22010-06-08 16:52:24 +0000924 segment_sp->SetIsFake(true);
925 m_sections_ap->AddSection(segment_sp);
Greg Clayton68ca8232011-01-25 02:58:48 +0000926 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000927 }
928 }
929 assert (segment_sp.get());
930
Greg Clayton1674b122010-07-21 22:12:05 +0000931 uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
Chris Lattner24943d22010-06-08 16:52:24 +0000932 static ConstString g_sect_name_objc_data ("__objc_data");
933 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
934 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
935 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
936 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
937 static ConstString g_sect_name_objc_const ("__objc_const");
938 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
939 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000940
941 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
942 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
943 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
944 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
945 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
946 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
947 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
948 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
949 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
950 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
951 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
Greg Claytonf6e3de22011-09-28 17:06:40 +0000952 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
953 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
Greg Clayton00db2152011-10-04 22:41:51 +0000954 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
Greg Clayton24a6bd92011-10-27 17:55:14 +0000955 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000956 static ConstString g_sect_name_eh_frame ("__eh_frame");
Greg Clayton3fed8b92010-10-08 00:21:05 +0000957 static ConstString g_sect_name_DATA ("__DATA");
958 static ConstString g_sect_name_TEXT ("__TEXT");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000959
Chris Lattner24943d22010-06-08 16:52:24 +0000960 SectionType sect_type = eSectionTypeOther;
961
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000962 if (section_name == g_sect_name_dwarf_debug_abbrev)
963 sect_type = eSectionTypeDWARFDebugAbbrev;
964 else if (section_name == g_sect_name_dwarf_debug_aranges)
965 sect_type = eSectionTypeDWARFDebugAranges;
966 else if (section_name == g_sect_name_dwarf_debug_frame)
967 sect_type = eSectionTypeDWARFDebugFrame;
968 else if (section_name == g_sect_name_dwarf_debug_info)
969 sect_type = eSectionTypeDWARFDebugInfo;
970 else if (section_name == g_sect_name_dwarf_debug_line)
971 sect_type = eSectionTypeDWARFDebugLine;
972 else if (section_name == g_sect_name_dwarf_debug_loc)
973 sect_type = eSectionTypeDWARFDebugLoc;
974 else if (section_name == g_sect_name_dwarf_debug_macinfo)
975 sect_type = eSectionTypeDWARFDebugMacInfo;
976 else if (section_name == g_sect_name_dwarf_debug_pubnames)
977 sect_type = eSectionTypeDWARFDebugPubNames;
978 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
979 sect_type = eSectionTypeDWARFDebugPubTypes;
980 else if (section_name == g_sect_name_dwarf_debug_ranges)
981 sect_type = eSectionTypeDWARFDebugRanges;
982 else if (section_name == g_sect_name_dwarf_debug_str)
983 sect_type = eSectionTypeDWARFDebugStr;
Greg Claytonf6e3de22011-09-28 17:06:40 +0000984 else if (section_name == g_sect_name_dwarf_apple_names)
985 sect_type = eSectionTypeDWARFAppleNames;
986 else if (section_name == g_sect_name_dwarf_apple_types)
987 sect_type = eSectionTypeDWARFAppleTypes;
Greg Clayton00db2152011-10-04 22:41:51 +0000988 else if (section_name == g_sect_name_dwarf_apple_namespaces)
989 sect_type = eSectionTypeDWARFAppleNamespaces;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000990 else if (section_name == g_sect_name_dwarf_apple_objc)
991 sect_type = eSectionTypeDWARFAppleObjC;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000992 else if (section_name == g_sect_name_objc_selrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000993 sect_type = eSectionTypeDataCStringPointers;
Chris Lattner24943d22010-06-08 16:52:24 +0000994 else if (section_name == g_sect_name_objc_msgrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000995 sect_type = eSectionTypeDataObjCMessageRefs;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000996 else if (section_name == g_sect_name_eh_frame)
997 sect_type = eSectionTypeEHFrame;
998 else if (section_name == g_sect_name_cfstring)
999 sect_type = eSectionTypeDataObjCCFStrings;
Chris Lattner24943d22010-06-08 16:52:24 +00001000 else if (section_name == g_sect_name_objc_data ||
1001 section_name == g_sect_name_objc_classrefs ||
1002 section_name == g_sect_name_objc_superrefs ||
1003 section_name == g_sect_name_objc_const ||
1004 section_name == g_sect_name_objc_classlist)
1005 {
1006 sect_type = eSectionTypeDataPointers;
1007 }
Chris Lattner24943d22010-06-08 16:52:24 +00001008
1009 if (sect_type == eSectionTypeOther)
1010 {
1011 switch (mach_sect_type)
1012 {
1013 // TODO: categorize sections by other flags for regular sections
Greg Clayton3fed8b92010-10-08 00:21:05 +00001014 case SectionTypeRegular:
1015 if (segment_sp->GetName() == g_sect_name_TEXT)
1016 sect_type = eSectionTypeCode;
1017 else if (segment_sp->GetName() == g_sect_name_DATA)
1018 sect_type = eSectionTypeData;
1019 else
1020 sect_type = eSectionTypeOther;
1021 break;
Greg Clayton1674b122010-07-21 22:12:05 +00001022 case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
1023 case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1024 case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1025 case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1026 case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1027 case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1028 case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1029 case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1030 case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1031 case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1032 case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
1033 case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
1034 case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1035 case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1036 case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
1037 case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
Chris Lattner24943d22010-06-08 16:52:24 +00001038 default: break;
1039 }
1040 }
1041
Greg Clayton3508c382012-02-24 01:59:29 +00001042 SectionSP section_sp(new Section (segment_sp,
1043 module_sp,
1044 ++sectID,
1045 section_name,
1046 sect_type,
1047 sect64.addr - segment_sp->GetFileAddress(),
1048 sect64.size,
1049 sect64.offset,
1050 sect64.offset == 0 ? 0 : sect64.size,
1051 sect64.flags));
Greg Clayton68ca8232011-01-25 02:58:48 +00001052 // Set the section to be encrypted to match the segment
Greg Clayton6f7f8da2012-04-24 03:06:13 +00001053
1054 bool section_is_encrypted = false;
1055 if (!segment_is_encrypted && load_cmd.filesize != 0)
1056 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
Greg Clayton68ca8232011-01-25 02:58:48 +00001057
Greg Clayton6f7f8da2012-04-24 03:06:13 +00001058 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +00001059 segment_sp->GetChildren().AddSection(section_sp);
1060
1061 if (segment_sp->IsFake())
1062 {
1063 segment_sp.reset();
1064 segment_name.Clear();
1065 }
1066 }
Greg Clayton0fa51242011-07-19 03:57:15 +00001067 if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
Chris Lattner24943d22010-06-08 16:52:24 +00001068 {
1069 if (first_segment_sectID <= sectID)
1070 {
1071 lldb::user_id_t sect_uid;
1072 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
1073 {
1074 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1075 SectionSP next_section_sp;
1076 if (sect_uid + 1 <= sectID)
1077 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1078
1079 if (curr_section_sp.get())
1080 {
1081 if (curr_section_sp->GetByteSize() == 0)
1082 {
1083 if (next_section_sp.get() != NULL)
1084 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1085 else
1086 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1087 }
1088 }
1089 }
1090 }
1091 }
1092 }
1093 }
1094 }
Greg Clayton1674b122010-07-21 22:12:05 +00001095 else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
Chris Lattner24943d22010-06-08 16:52:24 +00001096 {
1097 m_dysymtab.cmd = load_cmd.cmd;
1098 m_dysymtab.cmdsize = load_cmd.cmdsize;
1099 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1100 }
1101
1102 offset = load_cmd_offset + load_cmd.cmdsize;
1103 }
1104// if (dump_sections)
1105// {
1106// StreamFile s(stdout);
1107// m_sections_ap->Dump(&s, true);
1108// }
1109 return sectID; // Return the number of sections we registered with the module
1110}
1111
1112class MachSymtabSectionInfo
1113{
1114public:
1115
1116 MachSymtabSectionInfo (SectionList *section_list) :
1117 m_section_list (section_list),
1118 m_section_infos()
1119 {
1120 // Get the number of sections down to a depth of 1 to include
1121 // all segments and their sections, but no other sections that
1122 // may be added for debug map or
1123 m_section_infos.resize(section_list->GetNumSections(1));
1124 }
1125
1126
Greg Clayton3508c382012-02-24 01:59:29 +00001127 SectionSP
Chris Lattner24943d22010-06-08 16:52:24 +00001128 GetSection (uint8_t n_sect, addr_t file_addr)
1129 {
1130 if (n_sect == 0)
Greg Clayton3508c382012-02-24 01:59:29 +00001131 return SectionSP();
Chris Lattner24943d22010-06-08 16:52:24 +00001132 if (n_sect < m_section_infos.size())
1133 {
Greg Clayton3508c382012-02-24 01:59:29 +00001134 if (!m_section_infos[n_sect].section_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001135 {
Greg Clayton3508c382012-02-24 01:59:29 +00001136 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1137 m_section_infos[n_sect].section_sp = section_sp;
Sean Callananb386d822012-08-09 00:50:26 +00001138 if (section_sp)
Greg Clayton5638d2c2011-07-10 17:32:33 +00001139 {
Greg Clayton3508c382012-02-24 01:59:29 +00001140 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1141 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Clayton5638d2c2011-07-10 17:32:33 +00001142 }
1143 else
1144 {
Greg Claytondf6dc882012-01-05 03:57:59 +00001145 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Clayton5638d2c2011-07-10 17:32:33 +00001146 }
Chris Lattner24943d22010-06-08 16:52:24 +00001147 }
1148 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton811b9c52011-08-26 20:01:35 +00001149 {
1150 // Symbol is in section.
Greg Clayton3508c382012-02-24 01:59:29 +00001151 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001152 }
1153 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1154 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1155 {
1156 // Symbol is in section with zero size, but has the same start
1157 // address as the section. This can happen with linker symbols
1158 // (symbols that start with the letter 'l' or 'L'.
Greg Clayton3508c382012-02-24 01:59:29 +00001159 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001160 }
Chris Lattner24943d22010-06-08 16:52:24 +00001161 }
Greg Clayton3508c382012-02-24 01:59:29 +00001162 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner24943d22010-06-08 16:52:24 +00001163 }
1164
1165protected:
1166 struct SectionInfo
1167 {
1168 SectionInfo () :
1169 vm_range(),
Greg Clayton3508c382012-02-24 01:59:29 +00001170 section_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +00001171 {
1172 }
1173
1174 VMRange vm_range;
Greg Clayton3508c382012-02-24 01:59:29 +00001175 SectionSP section_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001176 };
1177 SectionList *m_section_list;
1178 std::vector<SectionInfo> m_section_infos;
1179};
1180
Chris Lattner24943d22010-06-08 16:52:24 +00001181size_t
1182ObjectFileMachO::ParseSymtab (bool minimize)
1183{
1184 Timer scoped_timer(__PRETTY_FUNCTION__,
1185 "ObjectFileMachO::ParseSymtab () module = %s",
1186 m_file.GetFilename().AsCString(""));
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001187 ModuleSP module_sp (GetModule());
1188 if (!module_sp)
1189 return 0;
1190
1191 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
1192 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
1193 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
1194 FunctionStarts function_starts;
Chris Lattner24943d22010-06-08 16:52:24 +00001195 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1196 uint32_t i;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001197
Greg Clayton0fea0512011-12-30 00:32:24 +00001198 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
1199
Chris Lattner24943d22010-06-08 16:52:24 +00001200 for (i=0; i<m_header.ncmds; ++i)
1201 {
1202 const uint32_t cmd_offset = offset;
1203 // Read in the load command and load command size
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001204 struct load_command lc;
1205 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001206 break;
1207 // Watch for the symbol table load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001208 switch (lc.cmd)
Chris Lattner24943d22010-06-08 16:52:24 +00001209 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001210 case LoadCommandSymtab:
1211 symtab_load_command.cmd = lc.cmd;
1212 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00001213 // Read in the rest of the symtab load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001214 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
1215 return 0;
1216 if (symtab_load_command.symoff == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001217 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001218 if (log)
1219 module_sp->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
1220 return 0;
1221 }
1222
1223 if (symtab_load_command.stroff == 0)
1224 {
1225 if (log)
1226 module_sp->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
1227 return 0;
1228 }
1229
1230 if (symtab_load_command.nsyms == 0)
1231 {
1232 if (log)
1233 module_sp->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
1234 return 0;
1235 }
1236
1237 if (symtab_load_command.strsize == 0)
1238 {
1239 if (log)
1240 module_sp->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
1241 return 0;
1242 }
1243 break;
1244
1245 case LoadCommandFunctionStarts:
1246 function_starts_load_command.cmd = lc.cmd;
1247 function_starts_load_command.cmdsize = lc.cmdsize;
1248 if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
1249 bzero (&function_starts_load_command, sizeof(function_starts_load_command));
1250 break;
1251
1252 default:
1253 break;
1254 }
1255 offset = cmd_offset + lc.cmdsize;
1256 }
1257
1258 if (symtab_load_command.cmd)
1259 {
1260 Symtab *symtab = m_symtab_ap.get();
1261 SectionList *section_list = GetSectionList();
1262 if (section_list == NULL)
1263 return 0;
1264
1265 ProcessSP process_sp (m_process_wp.lock());
Greg Claytondd29b972012-05-18 23:20:01 +00001266 Process *process = process_sp.get();
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001267
1268 const size_t addr_byte_size = m_data.GetAddressByteSize();
1269 bool bit_width_32 = addr_byte_size == 4;
1270 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
1271
1272 DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1273 DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1274 DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1275
1276 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
1277 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Claytondd29b972012-05-18 23:20:01 +00001278 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
1279 if (process)
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001280 {
Greg Claytondd29b972012-05-18 23:20:01 +00001281 Target &target = process->GetTarget();
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001282 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
1283 // Reading mach file from memory in a process or core file...
1284
1285 if (linkedit_section_sp)
1286 {
1287 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
1288 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
1289 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Claytondd29b972012-05-18 23:20:01 +00001290 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton29021d32012-04-18 05:19:20 +00001291
1292 bool data_was_read = false;
1293
1294#if defined (__APPLE__) && defined (__arm__)
1295 if (m_header.flags & 0x80000000u)
Greg Clayton0fea0512011-12-30 00:32:24 +00001296 {
Greg Clayton29021d32012-04-18 05:19:20 +00001297 // This mach-o memory file is in the dyld shared cache. If this
1298 // program is not remote and this is iOS, then this process will
1299 // share the same shared cache as the process we are debugging and
1300 // we can read the entire __LINKEDIT from the address space in this
1301 // process. This is a needed optimization that is used for local iOS
1302 // debugging only since all shared libraries in the shared cache do
1303 // not have corresponding files that exist in the file system of the
1304 // device. They have been combined into a single file. This means we
1305 // always have to load these files from memory. All of the symbol and
1306 // string tables from all of the __LINKEDIT sections from the shared
1307 // libraries in the shared cache have been merged into a single large
1308 // symbol and string table. Reading all of this symbol and string table
1309 // data across can slow down debug launch times, so we optimize this by
1310 // reading the memory for the __LINKEDIT section from this process.
1311 PlatformSP platform_sp (target.GetPlatform());
1312 if (platform_sp && platform_sp->IsHost())
1313 {
1314 data_was_read = true;
1315 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Claytondd29b972012-05-18 23:20:01 +00001316 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton29021d32012-04-18 05:19:20 +00001317 if (function_starts_load_command.cmd)
1318 {
1319 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1320 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
1321 }
1322 }
1323 }
1324#endif
1325
1326 if (!data_was_read)
1327 {
1328 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
1329 if (nlist_data_sp)
1330 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
Greg Claytondd29b972012-05-18 23:20:01 +00001331 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
1332 //if (strtab_data_sp)
1333 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
Greg Clayton29021d32012-04-18 05:19:20 +00001334 if (function_starts_load_command.cmd)
1335 {
1336 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1337 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
1338 if (func_start_data_sp)
1339 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
1340 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001341 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001342 }
1343 }
1344 else
1345 {
1346 nlist_data.SetData (m_data,
1347 symtab_load_command.symoff,
1348 nlist_data_byte_size);
1349 strtab_data.SetData (m_data,
1350 symtab_load_command.stroff,
1351 strtab_data_byte_size);
1352 if (function_starts_load_command.cmd)
1353 {
1354 function_starts_data.SetData (m_data,
1355 function_starts_load_command.dataoff,
1356 function_starts_load_command.datasize);
1357 }
1358 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001359
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001360 if (nlist_data.GetByteSize() == 0)
1361 {
1362 if (log)
1363 module_sp->LogMessage(log.get(), "failed to read nlist data");
1364 return 0;
1365 }
1366
1367
Greg Clayton3a5dc012012-05-25 17:04:00 +00001368 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
1369 if (!have_strtab_data)
Greg Claytondd29b972012-05-18 23:20:01 +00001370 {
Greg Clayton3a5dc012012-05-25 17:04:00 +00001371 if (process)
1372 {
1373 if (strtab_addr == LLDB_INVALID_ADDRESS)
1374 {
1375 if (log)
1376 module_sp->LogMessage(log.get(), "failed to locate the strtab in memory");
1377 return 0;
1378 }
1379 }
1380 else
Greg Claytondd29b972012-05-18 23:20:01 +00001381 {
1382 if (log)
Greg Clayton3a5dc012012-05-25 17:04:00 +00001383 module_sp->LogMessage(log.get(), "failed to read strtab data");
Greg Claytondd29b972012-05-18 23:20:01 +00001384 return 0;
1385 }
1386 }
Greg Claytondd29b972012-05-18 23:20:01 +00001387
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001388 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
1389 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
1390 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
1391 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
1392 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
1393 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
1394 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
1395 SectionSP eh_frame_section_sp;
1396 if (text_section_sp.get())
1397 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
1398 else
1399 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
1400
Greg Claytond2653c22012-03-14 01:53:24 +00001401 const bool is_arm = (m_header.cputype == llvm::MachO::CPUTypeARM);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001402 if (text_section_sp && function_starts_data.GetByteSize())
1403 {
1404 FunctionStarts::Entry function_start_entry;
1405 function_start_entry.data = false;
1406 uint32_t function_start_offset = 0;
1407 function_start_entry.addr = text_section_sp->GetFileAddress();
1408 uint64_t delta;
1409 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
1410 {
1411 // Now append the current entry
1412 function_start_entry.addr += delta;
1413 function_starts.Append(function_start_entry);
1414 }
1415 }
1416
1417 const uint32_t function_starts_count = function_starts.GetSize();
1418
1419 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
1420
1421 uint32_t nlist_data_offset = 0;
1422
1423 uint32_t N_SO_index = UINT32_MAX;
1424
1425 MachSymtabSectionInfo section_info (section_list);
1426 std::vector<uint32_t> N_FUN_indexes;
1427 std::vector<uint32_t> N_NSYM_indexes;
1428 std::vector<uint32_t> N_INCL_indexes;
1429 std::vector<uint32_t> N_BRAC_indexes;
1430 std::vector<uint32_t> N_COMM_indexes;
1431 typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
1432 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
1433 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
1434 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
1435 // Any symbols that get merged into another will get an entry
1436 // in this map so we know
1437 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
1438 uint32_t nlist_idx = 0;
1439 Symbol *symbol_ptr = NULL;
1440
1441 uint32_t sym_idx = 0;
Jason Molendab62abd52012-06-21 01:51:02 +00001442 Symbol *sym = NULL;
1443 uint32_t num_syms = 0;
Greg Claytondd29b972012-05-18 23:20:01 +00001444 std::string memory_symbol_name;
Jason Molendab62abd52012-06-21 01:51:02 +00001445 uint32_t unmapped_local_symbols_found = 0;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001446
Jason Molendab62abd52012-06-21 01:51:02 +00001447#if defined (__APPLE__) && defined (__arm__)
1448
1449 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
1450 // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
1451 // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
1452 // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
1453 // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
1454 // nlist parser to ignore all LOCAL symbols.
1455
1456 if (m_header.flags & 0x80000000u)
1457 {
1458 // Before we can start mapping the DSC, we need to make certain the target process is actually
1459 // using the cache we can find.
1460
1461 /*
1462 * TODO (FIXME!)
1463 *
1464 * Consider the case of testing with a separate DSC file.
1465 * If we go through the normal code paths, we will give symbols for the wrong DSC, and
1466 * that is bad. We need to read the target process' all_image_infos struct, and look
1467 * at the values of the processDetachedFromSharedRegion field. If that is set, we should skip
1468 * this code section.
1469 */
1470
1471 // Next we need to determine the correct path for the dyld shared cache.
1472
1473 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
1474 char dsc_path[PATH_MAX];
1475
1476 snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
1477 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
1478 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
1479 header_arch.GetArchitectureName());
1480
1481 FileSpec dsc_filespec(dsc_path, false);
1482
1483 // We need definitions of two structures in the on-disk DSC, copy them here manually
Greg Claytonab77dcb2012-09-05 22:30:51 +00001484 struct lldb_copy_dyld_cache_header
1485 {
1486 char magic[16];
1487 uint32_t mappingOffset;
1488 uint32_t mappingCount;
1489 uint32_t imagesOffset;
1490 uint32_t imagesCount;
1491 uint64_t dyldBaseAddress;
1492 uint64_t codeSignatureOffset;
1493 uint64_t codeSignatureSize;
1494 uint64_t slideInfoOffset;
1495 uint64_t slideInfoSize;
1496 uint64_t localSymbolsOffset;
1497 uint64_t localSymbolsSize;
1498 };
1499 struct lldb_copy_dyld_cache_local_symbols_info
1500 {
1501 uint32_t nlistOffset;
1502 uint32_t nlistCount;
1503 uint32_t stringsOffset;
1504 uint32_t stringsSize;
1505 uint32_t entriesOffset;
1506 uint32_t entriesCount;
1507 };
1508 struct lldb_copy_dyld_cache_local_symbols_entry
1509 {
1510 uint32_t dylibOffset;
1511 uint32_t nlistStartIndex;
1512 uint32_t nlistCount;
1513 };
Jason Molendab62abd52012-06-21 01:51:02 +00001514
Jason Molendafd3b35d2012-06-22 03:28:35 +00001515 /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
1516 The dyld_cache_local_symbols_info structure gives us three things:
1517 1. The start and count of the nlist records in the dyld_shared_cache file
1518 2. The start and size of the strings for these nlist records
1519 3. The start and count of dyld_cache_local_symbols_entry entries
1520
1521 There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
1522 The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
1523 The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
1524 and the count of how many nlist records there are for this dylib/framework.
1525 */
1526
Jason Molendab62abd52012-06-21 01:51:02 +00001527 // Process the dsc header to find the unmapped symbols
1528 //
1529 // Save some VM space, do not map the entire cache in one shot.
1530
1531 if (DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header)))
1532 {
1533 DataExtractor dsc_header_data(dsc_data_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1534
Jason Molendafd3b35d2012-06-22 03:28:35 +00001535 uint32_t offset = offsetof (struct lldb_copy_dyld_cache_header, mappingOffset);
Jason Molendab62abd52012-06-21 01:51:02 +00001536 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
1537
1538 // If the mappingOffset points to a location inside the header, we've
1539 // opened an old dyld shared cache, and should not proceed further.
1540 if (mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header))
1541 {
1542
Jason Molendafd3b35d2012-06-22 03:28:35 +00001543 offset = offsetof (struct lldb_copy_dyld_cache_header, localSymbolsOffset);
Jason Molendab62abd52012-06-21 01:51:02 +00001544 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
1545 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
1546
1547 if (localSymbolsOffset && localSymbolsSize)
1548 {
1549 // Map the local symbols
1550 if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
1551 {
1552 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1553
1554 offset = 0;
1555
1556 // Read the local_symbols_infos struct in one shot
1557 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
1558 dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
1559
1560 // The local_symbols_infos offsets are offsets into local symbols memory, NOT file offsets!
1561 // We first need to identify the local "entry" that matches the current header.
1562 // The "entry" is stored as a file offset in the dyld_shared_cache, so we need to
1563 // adjust the raw m_header value by slide and 0x30000000.
1564
1565 SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
1566
1567 uint32_t header_file_offset = (text_section_sp->GetFileAddress() - 0x30000000);
1568
1569 offset = local_symbols_info.entriesOffset;
1570 for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
1571 {
1572 struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
1573 local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
1574 local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
1575 local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
1576
1577 if (header_file_offset == local_symbols_entry.dylibOffset)
1578 {
1579 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
1580
1581 // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
1582 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
1583 num_syms = symtab->GetNumSymbols();
1584
1585 nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
1586 uint32_t string_table_offset = local_symbols_info.stringsOffset;
1587
1588 for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
1589 {
1590 /////////////////////////////
1591 {
1592 struct nlist_64 nlist;
1593 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
1594 break;
1595
1596 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
1597 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
1598 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
1599 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
1600 nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
1601
1602 SymbolType type = eSymbolTypeInvalid;
1603 const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
1604
1605 if (symbol_name == NULL)
1606 {
1607 // No symbol should be NULL, even the symbols with no
1608 // string values should have an offset zero which points
1609 // to an empty C-string
1610 Host::SystemLog (Host::eSystemLogError,
1611 "error: DSC unmapped local symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
1612 entry_index,
1613 nlist.n_strx,
1614 module_sp->GetFileSpec().GetDirectory().GetCString(),
1615 module_sp->GetFileSpec().GetFilename().GetCString());
1616 continue;
1617 }
1618 if (symbol_name[0] == '\0')
1619 symbol_name = NULL;
1620
1621 const char *symbol_name_non_abi_mangled = NULL;
1622
1623 SectionSP symbol_section;
1624 uint32_t symbol_byte_size = 0;
1625 bool add_nlist = true;
1626 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
1627
1628 assert (sym_idx < num_syms);
1629
1630 sym[sym_idx].SetDebug (is_debug);
1631
1632 if (is_debug)
1633 {
1634 switch (nlist.n_type)
1635 {
1636 case StabGlobalSymbol:
1637 // N_GSYM -- global symbol: name,,NO_SECT,type,0
1638 // Sometimes the N_GSYM value contains the address.
1639
1640 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
1641 // have the same address, but we want to ensure that we always find only the real symbol,
1642 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
1643 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
1644 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
1645 // same address.
1646
1647 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
1648 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
1649 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
1650 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
1651 add_nlist = false;
1652 else
1653 {
1654 sym[sym_idx].SetExternal(true);
1655 if (nlist.n_value != 0)
1656 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1657 type = eSymbolTypeData;
1658 }
1659 break;
1660
1661 case StabFunctionName:
1662 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
1663 type = eSymbolTypeCompiler;
1664 break;
1665
1666 case StabFunction:
1667 // N_FUN -- procedure: name,,n_sect,linenumber,address
1668 if (symbol_name)
1669 {
1670 type = eSymbolTypeCode;
1671 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1672
1673 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
1674 // We use the current number of symbols in the symbol table in lieu of
1675 // using nlist_idx in case we ever start trimming entries out
1676 N_FUN_indexes.push_back(sym_idx);
1677 }
1678 else
1679 {
1680 type = eSymbolTypeCompiler;
1681
1682 if ( !N_FUN_indexes.empty() )
1683 {
1684 // Copy the size of the function into the original STAB entry so we don't have
1685 // to hunt for it later
1686 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
1687 N_FUN_indexes.pop_back();
1688 // We don't really need the end function STAB as it contains the size which
1689 // we already placed with the original symbol, so don't add it if we want a
1690 // minimal symbol table
1691 if (minimize)
1692 add_nlist = false;
1693 }
1694 }
1695 break;
1696
1697 case StabStaticSymbol:
1698 // N_STSYM -- static symbol: name,,n_sect,type,address
1699 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
1700 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1701 type = eSymbolTypeData;
1702 break;
1703
1704 case StabLocalCommon:
1705 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
1706 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1707 type = eSymbolTypeCommonBlock;
1708 break;
1709
1710 case StabBeginSymbol:
1711 // N_BNSYM
1712 // We use the current number of symbols in the symbol table in lieu of
1713 // using nlist_idx in case we ever start trimming entries out
1714 if (minimize)
1715 {
1716 // Skip these if we want minimal symbol tables
1717 add_nlist = false;
1718 }
1719 else
1720 {
1721 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1722 N_NSYM_indexes.push_back(sym_idx);
1723 type = eSymbolTypeScopeBegin;
1724 }
1725 break;
1726
1727 case StabEndSymbol:
1728 // N_ENSYM
1729 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
1730 // so that we can always skip the entire symbol if we need to navigate
1731 // more quickly at the source level when parsing STABS
1732 if (minimize)
1733 {
1734 // Skip these if we want minimal symbol tables
1735 add_nlist = false;
1736 }
1737 else
1738 {
1739 if ( !N_NSYM_indexes.empty() )
1740 {
1741 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
1742 symbol_ptr->SetByteSize(sym_idx + 1);
1743 symbol_ptr->SetSizeIsSibling(true);
1744 N_NSYM_indexes.pop_back();
1745 }
1746 type = eSymbolTypeScopeEnd;
1747 }
1748 break;
1749
1750
1751 case StabSourceFileOptions:
1752 // N_OPT - emitted with gcc2_compiled and in gcc source
1753 type = eSymbolTypeCompiler;
1754 break;
1755
1756 case StabRegisterSymbol:
1757 // N_RSYM - register sym: name,,NO_SECT,type,register
1758 type = eSymbolTypeVariable;
1759 break;
1760
1761 case StabSourceLine:
1762 // N_SLINE - src line: 0,,n_sect,linenumber,address
1763 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1764 type = eSymbolTypeLineEntry;
1765 break;
1766
1767 case StabStructureType:
1768 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
1769 type = eSymbolTypeVariableType;
1770 break;
1771
1772 case StabSourceFileName:
1773 // N_SO - source file name
1774 type = eSymbolTypeSourceFile;
1775 if (symbol_name == NULL)
1776 {
1777 if (minimize)
1778 add_nlist = false;
1779 if (N_SO_index != UINT32_MAX)
1780 {
1781 // Set the size of the N_SO to the terminating index of this N_SO
1782 // so that we can always skip the entire N_SO if we need to navigate
1783 // more quickly at the source level when parsing STABS
1784 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
1785 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
1786 symbol_ptr->SetSizeIsSibling(true);
1787 }
1788 N_NSYM_indexes.clear();
1789 N_INCL_indexes.clear();
1790 N_BRAC_indexes.clear();
1791 N_COMM_indexes.clear();
1792 N_FUN_indexes.clear();
1793 N_SO_index = UINT32_MAX;
1794 }
1795 else
1796 {
1797 // We use the current number of symbols in the symbol table in lieu of
1798 // using nlist_idx in case we ever start trimming entries out
1799 const bool N_SO_has_full_path = symbol_name[0] == '/';
1800 if (N_SO_has_full_path)
1801 {
1802 if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1803 {
1804 // We have two consecutive N_SO entries where the first contains a directory
1805 // and the second contains a full path.
Jason Molenda292cca82012-07-20 03:35:44 +00001806 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Jason Molendab62abd52012-06-21 01:51:02 +00001807 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1808 add_nlist = false;
1809 }
1810 else
1811 {
1812 // This is the first entry in a N_SO that contains a directory or
1813 // a full path to the source file
1814 N_SO_index = sym_idx;
1815 }
1816 }
1817 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1818 {
1819 // This is usually the second N_SO entry that contains just the filename,
1820 // so here we combine it with the first one if we are minimizing the symbol table
1821 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
1822 if (so_path && so_path[0])
1823 {
1824 std::string full_so_path (so_path);
Greg Clayton4df2b7f2012-09-07 20:29:13 +00001825 const size_t double_slash_pos = full_so_path.find("//");
1826 if (double_slash_pos != std::string::npos)
1827 {
1828 // The linker has been generating bad N_SO entries with doubled up paths
1829 // in the format "%s%s" where the first stirng in the DW_AT_comp_dir,
1830 // and the second is the directory for the source file so you end up with
1831 // a path that looks like "/tmp/src//tmp/src/"
1832 FileSpec so_dir(so_path, false);
1833 if (!so_dir.Exists())
1834 {
1835 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
1836 if (so_dir.Exists())
1837 {
1838 // Trim off the incorrect path
1839 full_so_path.erase(0, double_slash_pos + 1);
1840 }
1841 }
1842 }
Jason Molendab62abd52012-06-21 01:51:02 +00001843 if (*full_so_path.rbegin() != '/')
1844 full_so_path += '/';
1845 full_so_path += symbol_name;
Jason Molenda292cca82012-07-20 03:35:44 +00001846 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Jason Molendab62abd52012-06-21 01:51:02 +00001847 add_nlist = false;
1848 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1849 }
1850 }
Greg Claytonab77dcb2012-09-05 22:30:51 +00001851 else
1852 {
1853 // This could be a relative path to a N_SO
1854 N_SO_index = sym_idx;
1855 }
Jason Molendab62abd52012-06-21 01:51:02 +00001856 }
Jason Molendab62abd52012-06-21 01:51:02 +00001857 break;
1858
1859 case StabObjectFileName:
1860 // N_OSO - object file name: name,,0,0,st_mtime
1861 type = eSymbolTypeObjectFile;
1862 break;
1863
1864 case StabLocalSymbol:
1865 // N_LSYM - local sym: name,,NO_SECT,type,offset
1866 type = eSymbolTypeLocal;
1867 break;
1868
1869 //----------------------------------------------------------------------
1870 // INCL scopes
1871 //----------------------------------------------------------------------
1872 case StabBeginIncludeFileName:
1873 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
1874 // We use the current number of symbols in the symbol table in lieu of
1875 // using nlist_idx in case we ever start trimming entries out
1876 N_INCL_indexes.push_back(sym_idx);
1877 type = eSymbolTypeScopeBegin;
1878 break;
1879
1880 case StabEndIncludeFile:
1881 // N_EINCL - include file end: name,,NO_SECT,0,0
1882 // Set the size of the N_BINCL to the terminating index of this N_EINCL
1883 // so that we can always skip the entire symbol if we need to navigate
1884 // more quickly at the source level when parsing STABS
1885 if ( !N_INCL_indexes.empty() )
1886 {
1887 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
1888 symbol_ptr->SetByteSize(sym_idx + 1);
1889 symbol_ptr->SetSizeIsSibling(true);
1890 N_INCL_indexes.pop_back();
1891 }
1892 type = eSymbolTypeScopeEnd;
1893 break;
1894
1895 case StabIncludeFileName:
1896 // N_SOL - #included file name: name,,n_sect,0,address
1897 type = eSymbolTypeHeaderFile;
1898
1899 // We currently don't use the header files on darwin
1900 if (minimize)
1901 add_nlist = false;
1902 break;
1903
1904 case StabCompilerParameters:
1905 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
1906 type = eSymbolTypeCompiler;
1907 break;
1908
1909 case StabCompilerVersion:
1910 // N_VERSION - compiler version: name,,NO_SECT,0,0
1911 type = eSymbolTypeCompiler;
1912 break;
1913
1914 case StabCompilerOptLevel:
1915 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
1916 type = eSymbolTypeCompiler;
1917 break;
1918
1919 case StabParameter:
1920 // N_PSYM - parameter: name,,NO_SECT,type,offset
1921 type = eSymbolTypeVariable;
1922 break;
1923
1924 case StabAlternateEntry:
1925 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
1926 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1927 type = eSymbolTypeLineEntry;
1928 break;
1929
1930 //----------------------------------------------------------------------
1931 // Left and Right Braces
1932 //----------------------------------------------------------------------
1933 case StabLeftBracket:
1934 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
1935 // We use the current number of symbols in the symbol table in lieu of
1936 // using nlist_idx in case we ever start trimming entries out
1937 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1938 N_BRAC_indexes.push_back(sym_idx);
1939 type = eSymbolTypeScopeBegin;
1940 break;
1941
1942 case StabRightBracket:
1943 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
1944 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
1945 // so that we can always skip the entire symbol if we need to navigate
1946 // more quickly at the source level when parsing STABS
1947 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1948 if ( !N_BRAC_indexes.empty() )
1949 {
1950 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
1951 symbol_ptr->SetByteSize(sym_idx + 1);
1952 symbol_ptr->SetSizeIsSibling(true);
1953 N_BRAC_indexes.pop_back();
1954 }
1955 type = eSymbolTypeScopeEnd;
1956 break;
1957
1958 case StabDeletedIncludeFile:
1959 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
1960 type = eSymbolTypeHeaderFile;
1961 break;
1962
1963 //----------------------------------------------------------------------
1964 // COMM scopes
1965 //----------------------------------------------------------------------
1966 case StabBeginCommon:
1967 // N_BCOMM - begin common: name,,NO_SECT,0,0
1968 // We use the current number of symbols in the symbol table in lieu of
1969 // using nlist_idx in case we ever start trimming entries out
1970 type = eSymbolTypeScopeBegin;
1971 N_COMM_indexes.push_back(sym_idx);
1972 break;
1973
1974 case StabEndCommonLocal:
1975 // N_ECOML - end common (local name): 0,,n_sect,0,address
1976 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1977 // Fall through
1978
1979 case StabEndCommon:
1980 // N_ECOMM - end common: name,,n_sect,0,0
1981 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
1982 // so that we can always skip the entire symbol if we need to navigate
1983 // more quickly at the source level when parsing STABS
1984 if ( !N_COMM_indexes.empty() )
1985 {
1986 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
1987 symbol_ptr->SetByteSize(sym_idx + 1);
1988 symbol_ptr->SetSizeIsSibling(true);
1989 N_COMM_indexes.pop_back();
1990 }
1991 type = eSymbolTypeScopeEnd;
1992 break;
1993
1994 case StabLength:
1995 // N_LENG - second stab entry with length information
1996 type = eSymbolTypeAdditional;
1997 break;
1998
1999 default: break;
2000 }
2001 }
2002 else
2003 {
2004 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
2005 uint8_t n_type = NlistMaskType & nlist.n_type;
2006 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
2007
2008 switch (n_type)
2009 {
2010 case NListTypeIndirect: // N_INDR - Fall through
2011 case NListTypePreboundUndefined:// N_PBUD - Fall through
2012 case NListTypeUndefined: // N_UNDF
2013 type = eSymbolTypeUndefined;
2014 break;
2015
2016 case NListTypeAbsolute: // N_ABS
2017 type = eSymbolTypeAbsolute;
2018 break;
2019
2020 case NListTypeSection: // N_SECT
2021 {
2022 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2023
2024 if (symbol_section == NULL)
2025 {
2026 // TODO: warn about this?
2027 add_nlist = false;
2028 break;
2029 }
2030
2031 if (TEXT_eh_frame_sectID == nlist.n_sect)
2032 {
2033 type = eSymbolTypeException;
2034 }
2035 else
2036 {
2037 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
2038
2039 switch (section_type)
2040 {
2041 case SectionTypeRegular: break; // regular section
2042 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
2043 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
2044 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
2045 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
2046 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
2047 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
2048 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
2049 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
2050 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
2051 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
2052 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
2053 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
2054 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
2055 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
2056 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
2057 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
2058 default: break;
2059 }
2060
2061 if (type == eSymbolTypeInvalid)
2062 {
2063 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2064 if (symbol_section->IsDescendant (text_section_sp.get()))
2065 {
2066 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
2067 SectionAttrUserSelfModifyingCode |
2068 SectionAttrSytemSomeInstructions))
2069 type = eSymbolTypeData;
2070 else
2071 type = eSymbolTypeCode;
2072 }
2073 else
2074 if (symbol_section->IsDescendant(data_section_sp.get()))
2075 {
2076 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
2077 {
2078 type = eSymbolTypeRuntime;
2079
2080 if (symbol_name &&
2081 symbol_name[0] == '_' &&
2082 symbol_name[1] == 'O' &&
2083 symbol_name[2] == 'B')
2084 {
2085 llvm::StringRef symbol_name_ref(symbol_name);
2086 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2087 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2088 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
2089 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
2090 {
2091 symbol_name_non_abi_mangled = symbol_name + 1;
2092 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2093 type = eSymbolTypeObjCClass;
2094 }
2095 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
2096 {
2097 symbol_name_non_abi_mangled = symbol_name + 1;
2098 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2099 type = eSymbolTypeObjCMetaClass;
2100 }
2101 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
2102 {
2103 symbol_name_non_abi_mangled = symbol_name + 1;
2104 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2105 type = eSymbolTypeObjCIVar;
2106 }
2107 }
2108 }
2109 else
2110 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
2111 {
2112 type = eSymbolTypeException;
2113 }
2114 else
2115 {
2116 type = eSymbolTypeData;
2117 }
2118 }
2119 else
2120 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
2121 {
2122 type = eSymbolTypeTrampoline;
2123 }
2124 else
2125 if (symbol_section->IsDescendant(objc_section_sp.get()))
2126 {
2127 type = eSymbolTypeRuntime;
2128 if (symbol_name && symbol_name[0] == '.')
2129 {
2130 llvm::StringRef symbol_name_ref(symbol_name);
2131 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
2132 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
2133 {
2134 symbol_name_non_abi_mangled = symbol_name;
2135 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
2136 type = eSymbolTypeObjCClass;
2137 }
2138 }
2139 }
2140 }
2141 }
2142 }
2143 break;
2144 }
2145 }
2146
2147 if (add_nlist)
2148 {
2149 uint64_t symbol_value = nlist.n_value;
2150 bool symbol_name_is_mangled = false;
2151
2152 if (symbol_name_non_abi_mangled)
2153 {
Jason Molenda292cca82012-07-20 03:35:44 +00002154 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
2155 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Jason Molendab62abd52012-06-21 01:51:02 +00002156 }
2157 else
2158 {
2159 if (symbol_name && symbol_name[0] == '_')
2160 {
2161 symbol_name_is_mangled = symbol_name[1] == '_';
2162 symbol_name++; // Skip the leading underscore
2163 }
2164
2165 if (symbol_name)
2166 {
Jason Molenda292cca82012-07-20 03:35:44 +00002167 sym[sym_idx].GetMangled().SetValue(ConstString(symbol_name), symbol_name_is_mangled);
Jason Molendab62abd52012-06-21 01:51:02 +00002168 }
2169 }
2170
2171 if (is_debug == false)
2172 {
2173 if (type == eSymbolTypeCode)
2174 {
2175 // See if we can find a N_FUN entry for any code symbols.
2176 // If we do find a match, and the name matches, then we
2177 // can merge the two into just the function symbol to avoid
2178 // duplicate entries in the symbol table
2179 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
2180 if (pos != N_FUN_addr_to_sym_idx.end())
2181 {
2182 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2183 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2184 {
2185 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2186 // We just need the flags from the linker symbol, so put these flags
2187 // into the N_FUN flags to avoid duplicate symbols in the symbol table
2188 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2189 sym[sym_idx].Clear();
2190 continue;
2191 }
2192 }
2193 }
2194 else if (type == eSymbolTypeData)
2195 {
2196 // See if we can find a N_STSYM entry for any data symbols.
2197 // If we do find a match, and the name matches, then we
2198 // can merge the two into just the Static symbol to avoid
2199 // duplicate entries in the symbol table
2200 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
2201 if (pos != N_STSYM_addr_to_sym_idx.end())
2202 {
2203 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2204 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2205 {
2206 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2207 // We just need the flags from the linker symbol, so put these flags
2208 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
2209 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2210 sym[sym_idx].Clear();
2211 continue;
2212 }
2213 }
2214 }
2215 }
2216 if (symbol_section)
2217 {
2218 const addr_t section_file_addr = symbol_section->GetFileAddress();
2219 if (symbol_byte_size == 0 && function_starts_count > 0)
2220 {
2221 addr_t symbol_lookup_file_addr = nlist.n_value;
2222 // Do an exact address match for non-ARM addresses, else get the closest since
2223 // the symbol might be a thumb symbol which has an address with bit zero set
2224 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
2225 if (is_arm && func_start_entry)
2226 {
2227 // Verify that the function start address is the symbol address (ARM)
2228 // or the symbol address + 1 (thumb)
2229 if (func_start_entry->addr != symbol_lookup_file_addr &&
2230 func_start_entry->addr != (symbol_lookup_file_addr + 1))
2231 {
2232 // Not the right entry, NULL it out...
2233 func_start_entry = NULL;
2234 }
2235 }
2236 if (func_start_entry)
2237 {
2238 func_start_entry->data = true;
2239
2240 addr_t symbol_file_addr = func_start_entry->addr;
2241 uint32_t symbol_flags = 0;
2242 if (is_arm)
2243 {
2244 if (symbol_file_addr & 1)
2245 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
2246 symbol_file_addr &= 0xfffffffffffffffeull;
2247 }
2248
2249 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2250 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2251 if (next_func_start_entry)
2252 {
2253 addr_t next_symbol_file_addr = next_func_start_entry->addr;
2254 // Be sure the clear the Thumb address bit when we calculate the size
2255 // from the current and next address
2256 if (is_arm)
2257 next_symbol_file_addr &= 0xfffffffffffffffeull;
2258 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
2259 }
2260 else
2261 {
2262 symbol_byte_size = section_end_file_addr - symbol_file_addr;
2263 }
2264 }
2265 }
2266 symbol_value -= section_file_addr;
2267 }
2268
2269 sym[sym_idx].SetID (nlist_idx);
2270 sym[sym_idx].SetType (type);
2271 sym[sym_idx].GetAddress().SetSection (symbol_section);
2272 sym[sym_idx].GetAddress().SetOffset (symbol_value);
2273 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2274
2275 if (symbol_byte_size > 0)
2276 sym[sym_idx].SetByteSize(symbol_byte_size);
2277
2278 ++sym_idx;
2279 }
2280 else
2281 {
2282 sym[sym_idx].Clear();
2283 }
2284
2285 }
2286 /////////////////////////////
2287 }
2288 break; // No more entries to consider
2289 }
2290 }
2291 }
2292 }
2293 }
2294 }
2295 }
2296
2297 // Must reset this in case it was mutated above!
2298 nlist_data_offset = 0;
2299#endif
2300
2301 // If the sym array was not created while parsing the DSC unmapped
2302 // symbols, create it now.
2303 if (sym == NULL)
2304 {
2305 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
2306 num_syms = symtab->GetNumSymbols();
2307 }
2308
2309 if (unmapped_local_symbols_found)
2310 {
2311 assert(m_dysymtab.ilocalsym == 0);
2312 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
2313 nlist_idx = m_dysymtab.nlocalsym;
2314 }
2315 else
2316 {
2317 nlist_idx = 0;
2318 }
2319
2320 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002321 {
2322 struct nlist_64 nlist;
2323 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2324 break;
2325
2326 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
2327 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
2328 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
2329 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
2330 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
2331
2332 SymbolType type = eSymbolTypeInvalid;
Greg Claytondd29b972012-05-18 23:20:01 +00002333 const char *symbol_name = NULL;
2334
Greg Clayton3a5dc012012-05-25 17:04:00 +00002335 if (have_strtab_data)
Greg Claytondd29b972012-05-18 23:20:01 +00002336 {
2337 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
2338
2339 if (symbol_name == NULL)
2340 {
2341 // No symbol should be NULL, even the symbols with no
2342 // string values should have an offset zero which points
2343 // to an empty C-string
2344 Host::SystemLog (Host::eSystemLogError,
2345 "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
2346 nlist_idx,
2347 nlist.n_strx,
2348 module_sp->GetFileSpec().GetDirectory().GetCString(),
2349 module_sp->GetFileSpec().GetFilename().GetCString());
2350 continue;
2351 }
2352 if (symbol_name[0] == '\0')
2353 symbol_name = NULL;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002354 }
Greg Clayton3a5dc012012-05-25 17:04:00 +00002355 else
2356 {
2357 const addr_t str_addr = strtab_addr + nlist.n_strx;
2358 Error str_error;
2359 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
2360 symbol_name = memory_symbol_name.c_str();
2361 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002362 const char *symbol_name_non_abi_mangled = NULL;
2363
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002364 SectionSP symbol_section;
2365 uint32_t symbol_byte_size = 0;
2366 bool add_nlist = true;
2367 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
2368
2369 assert (sym_idx < num_syms);
2370
2371 sym[sym_idx].SetDebug (is_debug);
2372
2373 if (is_debug)
2374 {
2375 switch (nlist.n_type)
Greg Clayton0fea0512011-12-30 00:32:24 +00002376 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002377 case StabGlobalSymbol:
2378 // N_GSYM -- global symbol: name,,NO_SECT,type,0
2379 // Sometimes the N_GSYM value contains the address.
2380
2381 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
2382 // have the same address, but we want to ensure that we always find only the real symbol,
2383 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
2384 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
2385 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
2386 // same address.
2387
2388 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
2389 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
2390 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
2391 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
2392 add_nlist = false;
2393 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00002394 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002395 sym[sym_idx].SetExternal(true);
2396 if (nlist.n_value != 0)
2397 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2398 type = eSymbolTypeData;
Greg Claytonb5a8f142012-02-05 02:38:54 +00002399 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002400 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +00002401
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002402 case StabFunctionName:
2403 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
2404 type = eSymbolTypeCompiler;
2405 break;
Greg Clayton0fea0512011-12-30 00:32:24 +00002406
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002407 case StabFunction:
2408 // N_FUN -- procedure: name,,n_sect,linenumber,address
2409 if (symbol_name)
Greg Claytona9c4f312011-10-31 20:50:40 +00002410 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002411 type = eSymbolTypeCode;
2412 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2413
2414 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
2415 // We use the current number of symbols in the symbol table in lieu of
2416 // using nlist_idx in case we ever start trimming entries out
2417 N_FUN_indexes.push_back(sym_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002418 }
2419 else
2420 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002421 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00002422
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002423 if ( !N_FUN_indexes.empty() )
Chris Lattner24943d22010-06-08 16:52:24 +00002424 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002425 // Copy the size of the function into the original STAB entry so we don't have
2426 // to hunt for it later
2427 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
2428 N_FUN_indexes.pop_back();
2429 // We don't really need the end function STAB as it contains the size which
2430 // we already placed with the original symbol, so don't add it if we want a
2431 // minimal symbol table
2432 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00002433 add_nlist = false;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002434 }
Greg Clayton3f69eac2011-12-03 02:30:59 +00002435 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002436 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00002437
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002438 case StabStaticSymbol:
2439 // N_STSYM -- static symbol: name,,n_sect,type,address
2440 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
2441 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2442 type = eSymbolTypeData;
2443 break;
2444
2445 case StabLocalCommon:
2446 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
2447 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2448 type = eSymbolTypeCommonBlock;
2449 break;
2450
2451 case StabBeginSymbol:
2452 // N_BNSYM
2453 // We use the current number of symbols in the symbol table in lieu of
2454 // using nlist_idx in case we ever start trimming entries out
2455 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00002456 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002457 // Skip these if we want minimal symbol tables
2458 add_nlist = false;
2459 }
2460 else
2461 {
2462 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2463 N_NSYM_indexes.push_back(sym_idx);
2464 type = eSymbolTypeScopeBegin;
2465 }
2466 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00002467
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002468 case StabEndSymbol:
2469 // N_ENSYM
2470 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
2471 // so that we can always skip the entire symbol if we need to navigate
2472 // more quickly at the source level when parsing STABS
2473 if (minimize)
2474 {
2475 // Skip these if we want minimal symbol tables
2476 add_nlist = false;
2477 }
2478 else
2479 {
2480 if ( !N_NSYM_indexes.empty() )
Greg Clayton3f69eac2011-12-03 02:30:59 +00002481 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002482 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
2483 symbol_ptr->SetByteSize(sym_idx + 1);
2484 symbol_ptr->SetSizeIsSibling(true);
2485 N_NSYM_indexes.pop_back();
2486 }
2487 type = eSymbolTypeScopeEnd;
2488 }
2489 break;
2490
2491
2492 case StabSourceFileOptions:
2493 // N_OPT - emitted with gcc2_compiled and in gcc source
2494 type = eSymbolTypeCompiler;
2495 break;
2496
2497 case StabRegisterSymbol:
2498 // N_RSYM - register sym: name,,NO_SECT,type,register
2499 type = eSymbolTypeVariable;
2500 break;
2501
2502 case StabSourceLine:
2503 // N_SLINE - src line: 0,,n_sect,linenumber,address
2504 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2505 type = eSymbolTypeLineEntry;
2506 break;
2507
2508 case StabStructureType:
2509 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
2510 type = eSymbolTypeVariableType;
2511 break;
2512
2513 case StabSourceFileName:
2514 // N_SO - source file name
2515 type = eSymbolTypeSourceFile;
2516 if (symbol_name == NULL)
2517 {
2518 if (minimize)
2519 add_nlist = false;
2520 if (N_SO_index != UINT32_MAX)
2521 {
2522 // Set the size of the N_SO to the terminating index of this N_SO
2523 // so that we can always skip the entire N_SO if we need to navigate
2524 // more quickly at the source level when parsing STABS
2525 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
2526 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
2527 symbol_ptr->SetSizeIsSibling(true);
2528 }
2529 N_NSYM_indexes.clear();
2530 N_INCL_indexes.clear();
2531 N_BRAC_indexes.clear();
2532 N_COMM_indexes.clear();
2533 N_FUN_indexes.clear();
2534 N_SO_index = UINT32_MAX;
2535 }
2536 else
2537 {
2538 // We use the current number of symbols in the symbol table in lieu of
2539 // using nlist_idx in case we ever start trimming entries out
Greg Clayton5fa6cd32012-05-30 20:20:34 +00002540 const bool N_SO_has_full_path = symbol_name[0] == '/';
2541 if (N_SO_has_full_path)
2542 {
2543 if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
2544 {
2545 // We have two consecutive N_SO entries where the first contains a directory
2546 // and the second contains a full path.
Greg Claytonc0240042012-07-18 23:18:10 +00002547 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Greg Clayton5fa6cd32012-05-30 20:20:34 +00002548 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2549 add_nlist = false;
2550 }
2551 else
2552 {
2553 // This is the first entry in a N_SO that contains a directory or
2554 // a full path to the source file
2555 N_SO_index = sym_idx;
2556 }
2557 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002558 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
2559 {
Greg Clayton5fa6cd32012-05-30 20:20:34 +00002560 // This is usually the second N_SO entry that contains just the filename,
2561 // so here we combine it with the first one if we are minimizing the symbol table
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002562 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
2563 if (so_path && so_path[0])
2564 {
2565 std::string full_so_path (so_path);
Greg Clayton4df2b7f2012-09-07 20:29:13 +00002566 const size_t double_slash_pos = full_so_path.find("//");
2567 if (double_slash_pos != std::string::npos)
2568 {
2569 // The linker has been generating bad N_SO entries with doubled up paths
2570 // in the format "%s%s" where the first stirng in the DW_AT_comp_dir,
2571 // and the second is the directory for the source file so you end up with
2572 // a path that looks like "/tmp/src//tmp/src/"
2573 FileSpec so_dir(so_path, false);
2574 if (!so_dir.Exists())
2575 {
2576 so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
2577 if (so_dir.Exists())
2578 {
2579 // Trim off the incorrect path
2580 full_so_path.erase(0, double_slash_pos + 1);
2581 }
2582 }
2583 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002584 if (*full_so_path.rbegin() != '/')
2585 full_so_path += '/';
2586 full_so_path += symbol_name;
Greg Claytonc0240042012-07-18 23:18:10 +00002587 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002588 add_nlist = false;
2589 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2590 }
2591 }
Greg Claytonab77dcb2012-09-05 22:30:51 +00002592 else
2593 {
2594 // This could be a relative path to a N_SO
2595 N_SO_index = sym_idx;
2596 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002597 }
2598
2599 break;
2600
2601 case StabObjectFileName:
2602 // N_OSO - object file name: name,,0,0,st_mtime
2603 type = eSymbolTypeObjectFile;
2604 break;
2605
2606 case StabLocalSymbol:
2607 // N_LSYM - local sym: name,,NO_SECT,type,offset
2608 type = eSymbolTypeLocal;
2609 break;
2610
2611 //----------------------------------------------------------------------
2612 // INCL scopes
2613 //----------------------------------------------------------------------
2614 case StabBeginIncludeFileName:
2615 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
2616 // We use the current number of symbols in the symbol table in lieu of
2617 // using nlist_idx in case we ever start trimming entries out
2618 N_INCL_indexes.push_back(sym_idx);
2619 type = eSymbolTypeScopeBegin;
2620 break;
2621
2622 case StabEndIncludeFile:
2623 // N_EINCL - include file end: name,,NO_SECT,0,0
2624 // Set the size of the N_BINCL to the terminating index of this N_EINCL
2625 // so that we can always skip the entire symbol if we need to navigate
2626 // more quickly at the source level when parsing STABS
2627 if ( !N_INCL_indexes.empty() )
2628 {
2629 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
2630 symbol_ptr->SetByteSize(sym_idx + 1);
2631 symbol_ptr->SetSizeIsSibling(true);
2632 N_INCL_indexes.pop_back();
2633 }
2634 type = eSymbolTypeScopeEnd;
2635 break;
2636
2637 case StabIncludeFileName:
2638 // N_SOL - #included file name: name,,n_sect,0,address
2639 type = eSymbolTypeHeaderFile;
2640
2641 // We currently don't use the header files on darwin
2642 if (minimize)
2643 add_nlist = false;
2644 break;
2645
2646 case StabCompilerParameters:
2647 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
2648 type = eSymbolTypeCompiler;
2649 break;
2650
2651 case StabCompilerVersion:
2652 // N_VERSION - compiler version: name,,NO_SECT,0,0
2653 type = eSymbolTypeCompiler;
2654 break;
2655
2656 case StabCompilerOptLevel:
2657 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
2658 type = eSymbolTypeCompiler;
2659 break;
2660
2661 case StabParameter:
2662 // N_PSYM - parameter: name,,NO_SECT,type,offset
2663 type = eSymbolTypeVariable;
2664 break;
2665
2666 case StabAlternateEntry:
2667 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
2668 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2669 type = eSymbolTypeLineEntry;
2670 break;
2671
2672 //----------------------------------------------------------------------
2673 // Left and Right Braces
2674 //----------------------------------------------------------------------
2675 case StabLeftBracket:
2676 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
2677 // We use the current number of symbols in the symbol table in lieu of
2678 // using nlist_idx in case we ever start trimming entries out
2679 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2680 N_BRAC_indexes.push_back(sym_idx);
2681 type = eSymbolTypeScopeBegin;
2682 break;
2683
2684 case StabRightBracket:
2685 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
2686 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
2687 // so that we can always skip the entire symbol if we need to navigate
2688 // more quickly at the source level when parsing STABS
2689 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2690 if ( !N_BRAC_indexes.empty() )
2691 {
2692 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
2693 symbol_ptr->SetByteSize(sym_idx + 1);
2694 symbol_ptr->SetSizeIsSibling(true);
2695 N_BRAC_indexes.pop_back();
2696 }
2697 type = eSymbolTypeScopeEnd;
2698 break;
2699
2700 case StabDeletedIncludeFile:
2701 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
2702 type = eSymbolTypeHeaderFile;
2703 break;
2704
2705 //----------------------------------------------------------------------
2706 // COMM scopes
2707 //----------------------------------------------------------------------
2708 case StabBeginCommon:
2709 // N_BCOMM - begin common: name,,NO_SECT,0,0
2710 // We use the current number of symbols in the symbol table in lieu of
2711 // using nlist_idx in case we ever start trimming entries out
2712 type = eSymbolTypeScopeBegin;
2713 N_COMM_indexes.push_back(sym_idx);
2714 break;
2715
2716 case StabEndCommonLocal:
2717 // N_ECOML - end common (local name): 0,,n_sect,0,address
2718 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2719 // Fall through
2720
2721 case StabEndCommon:
2722 // N_ECOMM - end common: name,,n_sect,0,0
2723 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
2724 // so that we can always skip the entire symbol if we need to navigate
2725 // more quickly at the source level when parsing STABS
2726 if ( !N_COMM_indexes.empty() )
2727 {
2728 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
2729 symbol_ptr->SetByteSize(sym_idx + 1);
2730 symbol_ptr->SetSizeIsSibling(true);
2731 N_COMM_indexes.pop_back();
2732 }
2733 type = eSymbolTypeScopeEnd;
2734 break;
2735
2736 case StabLength:
2737 // N_LENG - second stab entry with length information
2738 type = eSymbolTypeAdditional;
2739 break;
2740
2741 default: break;
2742 }
2743 }
2744 else
2745 {
2746 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
2747 uint8_t n_type = NlistMaskType & nlist.n_type;
2748 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
2749
2750 switch (n_type)
2751 {
2752 case NListTypeIndirect: // N_INDR - Fall through
2753 case NListTypePreboundUndefined:// N_PBUD - Fall through
2754 case NListTypeUndefined: // N_UNDF
2755 type = eSymbolTypeUndefined;
2756 break;
2757
2758 case NListTypeAbsolute: // N_ABS
2759 type = eSymbolTypeAbsolute;
2760 break;
2761
2762 case NListTypeSection: // N_SECT
2763 {
2764 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2765
Sean Callananb386d822012-08-09 00:50:26 +00002766 if (!symbol_section)
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002767 {
2768 // TODO: warn about this?
2769 add_nlist = false;
2770 break;
2771 }
2772
2773 if (TEXT_eh_frame_sectID == nlist.n_sect)
2774 {
2775 type = eSymbolTypeException;
Chris Lattner24943d22010-06-08 16:52:24 +00002776 }
2777 else
2778 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002779 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
2780
2781 switch (section_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002782 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002783 case SectionTypeRegular: break; // regular section
2784 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
2785 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
2786 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
2787 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
2788 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
2789 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
2790 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
2791 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
2792 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
2793 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
2794 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
2795 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
2796 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
2797 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
2798 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
2799 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
2800 default: break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00002801 }
Chris Lattner24943d22010-06-08 16:52:24 +00002802
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002803 if (type == eSymbolTypeInvalid)
Greg Clayton3f69eac2011-12-03 02:30:59 +00002804 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002805 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2806 if (symbol_section->IsDescendant (text_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00002807 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002808 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
2809 SectionAttrUserSelfModifyingCode |
2810 SectionAttrSytemSomeInstructions))
2811 type = eSymbolTypeData;
2812 else
2813 type = eSymbolTypeCode;
Greg Clayton576a68b2010-09-08 16:38:06 +00002814 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002815 else
2816 if (symbol_section->IsDescendant(data_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00002817 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002818 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
Greg Clayton7c36fa02010-09-11 03:13:28 +00002819 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002820 type = eSymbolTypeRuntime;
Chris Lattner24943d22010-06-08 16:52:24 +00002821
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002822 if (symbol_name &&
2823 symbol_name[0] == '_' &&
2824 symbol_name[1] == 'O' &&
2825 symbol_name[2] == 'B')
Greg Clayton637029b2010-09-12 05:25:16 +00002826 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002827 llvm::StringRef symbol_name_ref(symbol_name);
2828 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2829 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2830 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
2831 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
Chris Lattner24943d22010-06-08 16:52:24 +00002832 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002833 symbol_name_non_abi_mangled = symbol_name + 1;
2834 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2835 type = eSymbolTypeObjCClass;
Chris Lattner24943d22010-06-08 16:52:24 +00002836 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002837 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
Chris Lattner24943d22010-06-08 16:52:24 +00002838 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002839 symbol_name_non_abi_mangled = symbol_name + 1;
2840 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2841 type = eSymbolTypeObjCMetaClass;
2842 }
2843 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
2844 {
2845 symbol_name_non_abi_mangled = symbol_name + 1;
2846 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2847 type = eSymbolTypeObjCIVar;
Chris Lattner24943d22010-06-08 16:52:24 +00002848 }
2849 }
2850 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002851 else
2852 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
2853 {
2854 type = eSymbolTypeException;
2855 }
2856 else
2857 {
2858 type = eSymbolTypeData;
2859 }
2860 }
2861 else
2862 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
2863 {
2864 type = eSymbolTypeTrampoline;
2865 }
2866 else
2867 if (symbol_section->IsDescendant(objc_section_sp.get()))
2868 {
2869 type = eSymbolTypeRuntime;
2870 if (symbol_name && symbol_name[0] == '.')
2871 {
2872 llvm::StringRef symbol_name_ref(symbol_name);
2873 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
2874 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
2875 {
2876 symbol_name_non_abi_mangled = symbol_name;
2877 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
2878 type = eSymbolTypeObjCClass;
2879 }
2880 }
Chris Lattner24943d22010-06-08 16:52:24 +00002881 }
2882 }
2883 }
2884 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002885 break;
2886 }
2887 }
2888
2889 if (add_nlist)
2890 {
2891 uint64_t symbol_value = nlist.n_value;
2892 bool symbol_name_is_mangled = false;
2893
2894 if (symbol_name_non_abi_mangled)
2895 {
Greg Claytonc0240042012-07-18 23:18:10 +00002896 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
2897 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Chris Lattner24943d22010-06-08 16:52:24 +00002898 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002899 else
2900 {
2901 if (symbol_name && symbol_name[0] == '_')
2902 {
2903 symbol_name_is_mangled = symbol_name[1] == '_';
2904 symbol_name++; // Skip the leading underscore
2905 }
2906
2907 if (symbol_name)
2908 {
Greg Claytonc0240042012-07-18 23:18:10 +00002909 sym[sym_idx].GetMangled().SetValue(ConstString(symbol_name), symbol_name_is_mangled);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002910 }
2911 }
2912
2913 if (is_debug == false)
2914 {
2915 if (type == eSymbolTypeCode)
2916 {
2917 // See if we can find a N_FUN entry for any code symbols.
2918 // If we do find a match, and the name matches, then we
2919 // can merge the two into just the function symbol to avoid
2920 // duplicate entries in the symbol table
2921 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
2922 if (pos != N_FUN_addr_to_sym_idx.end())
2923 {
2924 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2925 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2926 {
2927 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2928 // We just need the flags from the linker symbol, so put these flags
2929 // into the N_FUN flags to avoid duplicate symbols in the symbol table
2930 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2931 sym[sym_idx].Clear();
2932 continue;
2933 }
2934 }
2935 }
2936 else if (type == eSymbolTypeData)
2937 {
2938 // See if we can find a N_STSYM entry for any data symbols.
2939 // If we do find a match, and the name matches, then we
2940 // can merge the two into just the Static symbol to avoid
2941 // duplicate entries in the symbol table
2942 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
2943 if (pos != N_STSYM_addr_to_sym_idx.end())
2944 {
2945 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2946 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2947 {
2948 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2949 // We just need the flags from the linker symbol, so put these flags
2950 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
2951 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2952 sym[sym_idx].Clear();
2953 continue;
2954 }
2955 }
2956 }
2957 }
2958 if (symbol_section)
2959 {
2960 const addr_t section_file_addr = symbol_section->GetFileAddress();
2961 if (symbol_byte_size == 0 && function_starts_count > 0)
2962 {
Greg Claytond2653c22012-03-14 01:53:24 +00002963 addr_t symbol_lookup_file_addr = nlist.n_value;
2964 // Do an exact address match for non-ARM addresses, else get the closest since
2965 // the symbol might be a thumb symbol which has an address with bit zero set
2966 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
2967 if (is_arm && func_start_entry)
2968 {
2969 // Verify that the function start address is the symbol address (ARM)
2970 // or the symbol address + 1 (thumb)
2971 if (func_start_entry->addr != symbol_lookup_file_addr &&
2972 func_start_entry->addr != (symbol_lookup_file_addr + 1))
2973 {
2974 // Not the right entry, NULL it out...
2975 func_start_entry = NULL;
2976 }
2977 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002978 if (func_start_entry)
2979 {
2980 func_start_entry->data = true;
Greg Claytond2653c22012-03-14 01:53:24 +00002981
2982 addr_t symbol_file_addr = func_start_entry->addr;
Greg Claytond2653c22012-03-14 01:53:24 +00002983 if (is_arm)
Greg Claytond2653c22012-03-14 01:53:24 +00002984 symbol_file_addr &= 0xfffffffffffffffeull;
Greg Claytond2653c22012-03-14 01:53:24 +00002985
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002986 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2987 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2988 if (next_func_start_entry)
2989 {
Greg Claytond2653c22012-03-14 01:53:24 +00002990 addr_t next_symbol_file_addr = next_func_start_entry->addr;
2991 // Be sure the clear the Thumb address bit when we calculate the size
2992 // from the current and next address
2993 if (is_arm)
2994 next_symbol_file_addr &= 0xfffffffffffffffeull;
2995 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002996 }
2997 else
2998 {
Greg Claytond2653c22012-03-14 01:53:24 +00002999 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003000 }
3001 }
3002 }
3003 symbol_value -= section_file_addr;
3004 }
3005
3006 sym[sym_idx].SetID (nlist_idx);
3007 sym[sym_idx].SetType (type);
3008 sym[sym_idx].GetAddress().SetSection (symbol_section);
3009 sym[sym_idx].GetAddress().SetOffset (symbol_value);
3010 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
3011
3012 if (symbol_byte_size > 0)
3013 sym[sym_idx].SetByteSize(symbol_byte_size);
3014
3015 ++sym_idx;
3016 }
3017 else
3018 {
3019 sym[sym_idx].Clear();
3020 }
3021
3022 }
3023
3024 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
3025 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
3026 // such entries by figuring out what the address for the global is by looking up this non-STAB
3027 // entry and copying the value into the debug symbol's value to save us the hassle in the
3028 // debug symbol parser.
3029
3030 Symbol *global_symbol = NULL;
3031 for (nlist_idx = 0;
3032 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
3033 nlist_idx++)
3034 {
3035 if (global_symbol->GetAddress().GetFileAddress() == 0)
3036 {
3037 std::vector<uint32_t> indexes;
3038 if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
3039 {
3040 std::vector<uint32_t>::const_iterator pos;
3041 std::vector<uint32_t>::const_iterator end = indexes.end();
3042 for (pos = indexes.begin(); pos != end; ++pos)
3043 {
3044 symbol_ptr = symtab->SymbolAtIndex(*pos);
3045 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
3046 {
3047 global_symbol->GetAddress() = symbol_ptr->GetAddress();
3048 break;
3049 }
3050 }
3051 }
Chris Lattner24943d22010-06-08 16:52:24 +00003052 }
3053 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003054
3055 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
3056
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003057 if (function_starts_count > 0)
3058 {
3059 char synthetic_function_symbol[PATH_MAX];
3060 uint32_t num_synthetic_function_symbols = 0;
3061 for (i=0; i<function_starts_count; ++i)
3062 {
3063 if (function_starts.GetEntryRef (i).data == false)
3064 ++num_synthetic_function_symbols;
3065 }
3066
3067 if (num_synthetic_function_symbols > 0)
3068 {
3069 if (num_syms < sym_idx + num_synthetic_function_symbols)
3070 {
3071 num_syms = sym_idx + num_synthetic_function_symbols;
3072 sym = symtab->Resize (num_syms);
3073 }
3074 uint32_t synthetic_function_symbol_idx = 0;
3075 for (i=0; i<function_starts_count; ++i)
3076 {
3077 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
3078 if (func_start_entry->data == false)
3079 {
Greg Claytond2653c22012-03-14 01:53:24 +00003080 addr_t symbol_file_addr = func_start_entry->addr;
3081 uint32_t symbol_flags = 0;
3082 if (is_arm)
3083 {
3084 if (symbol_file_addr & 1)
3085 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
3086 symbol_file_addr &= 0xfffffffffffffffeull;
3087 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003088 Address symbol_addr;
Greg Claytond2653c22012-03-14 01:53:24 +00003089 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003090 {
3091 SectionSP symbol_section (symbol_addr.GetSection());
3092 uint32_t symbol_byte_size = 0;
3093 if (symbol_section)
3094 {
3095 const addr_t section_file_addr = symbol_section->GetFileAddress();
3096 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3097 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3098 if (next_func_start_entry)
3099 {
Greg Claytond2653c22012-03-14 01:53:24 +00003100 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3101 if (is_arm)
3102 next_symbol_file_addr &= 0xfffffffffffffffeull;
3103 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003104 }
3105 else
3106 {
Greg Claytond2653c22012-03-14 01:53:24 +00003107 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003108 }
3109 snprintf (synthetic_function_symbol,
3110 sizeof(synthetic_function_symbol),
3111 "___lldb_unnamed_function%u$$%s",
3112 ++synthetic_function_symbol_idx,
3113 module_sp->GetFileSpec().GetFilename().GetCString());
3114 sym[sym_idx].SetID (synthetic_sym_id++);
Greg Claytonc0240042012-07-18 23:18:10 +00003115 sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003116 sym[sym_idx].SetType (eSymbolTypeCode);
3117 sym[sym_idx].SetIsSynthetic (true);
3118 sym[sym_idx].GetAddress() = symbol_addr;
Greg Claytond2653c22012-03-14 01:53:24 +00003119 if (symbol_flags)
3120 sym[sym_idx].SetFlags (symbol_flags);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003121 if (symbol_byte_size)
3122 sym[sym_idx].SetByteSize (symbol_byte_size);
3123 ++sym_idx;
3124 }
3125 }
3126 }
3127 }
3128 }
3129 }
3130
3131 // Trim our symbols down to just what we ended up with after
3132 // removing any symbols.
3133 if (sym_idx < num_syms)
3134 {
3135 num_syms = sym_idx;
3136 sym = symtab->Resize (num_syms);
3137 }
3138
3139 // Now synthesize indirect symbols
3140 if (m_dysymtab.nindirectsyms != 0)
3141 {
3142 DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
3143
3144 if (indirect_symbol_index_data.GetByteSize())
3145 {
3146 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
3147
3148 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
3149 {
3150 if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
3151 {
3152 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
3153 if (symbol_stub_byte_size == 0)
3154 continue;
3155
3156 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
3157
3158 if (num_symbol_stubs == 0)
3159 continue;
3160
3161 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
3162 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
3163 {
3164 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
3165 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
3166 uint32_t symbol_stub_offset = symbol_stub_index * 4;
3167 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
3168 {
3169 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
3170 if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
3171 continue;
3172
3173 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
3174 Symbol *stub_symbol = NULL;
3175 if (index_pos != end_index_pos)
3176 {
3177 // We have a remapping from the original nlist index to
3178 // a current symbol index, so just look this up by index
3179 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
3180 }
3181 else
3182 {
3183 // We need to lookup a symbol using the original nlist
3184 // symbol index since this index is coming from the
3185 // S_SYMBOL_STUBS
3186 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
3187 }
3188
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003189 if (stub_symbol)
3190 {
3191 Address so_addr(symbol_stub_addr, section_list);
3192
3193 if (stub_symbol->GetType() == eSymbolTypeUndefined)
3194 {
3195 // Change the external symbol into a trampoline that makes sense
3196 // These symbols were N_UNDF N_EXT, and are useless to us, so we
3197 // can re-use them so we don't have to make up a synthetic symbol
3198 // for no good reason.
3199 stub_symbol->SetType (eSymbolTypeTrampoline);
3200 stub_symbol->SetExternal (false);
3201 stub_symbol->GetAddress() = so_addr;
3202 stub_symbol->SetByteSize (symbol_stub_byte_size);
3203 }
3204 else
3205 {
3206 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda2a76fbf2012-04-24 02:09:58 +00003207 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003208 if (sym_idx >= num_syms)
Jason Molenda2a76fbf2012-04-24 02:09:58 +00003209 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003210 sym = symtab->Resize (++num_syms);
Jason Molenda2a76fbf2012-04-24 02:09:58 +00003211 stub_symbol = NULL; // this pointer no longer valid
3212 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003213 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda2a76fbf2012-04-24 02:09:58 +00003214 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003215 sym[sym_idx].SetType (eSymbolTypeTrampoline);
3216 sym[sym_idx].SetIsSynthetic (true);
3217 sym[sym_idx].GetAddress() = so_addr;
3218 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
3219 ++sym_idx;
3220 }
3221 }
Greg Claytond4330e62012-09-05 01:38:55 +00003222 else
3223 {
3224 if (log)
3225 log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
3226 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003227 }
3228 }
3229 }
3230 }
3231 }
3232 }
3233 return symtab->GetNumSymbols();
Chris Lattner24943d22010-06-08 16:52:24 +00003234 }
3235 return 0;
3236}
3237
3238
3239void
3240ObjectFileMachO::Dump (Stream *s)
3241{
Greg Clayton9482f052012-03-13 23:14:29 +00003242 ModuleSP module_sp(GetModule());
3243 if (module_sp)
3244 {
3245 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3246 s->Printf("%p: ", this);
3247 s->Indent();
3248 if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped)
3249 s->PutCString("ObjectFileMachO64");
3250 else
3251 s->PutCString("ObjectFileMachO32");
Chris Lattner24943d22010-06-08 16:52:24 +00003252
Greg Clayton9482f052012-03-13 23:14:29 +00003253 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +00003254
Greg Clayton9482f052012-03-13 23:14:29 +00003255 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner24943d22010-06-08 16:52:24 +00003256
Greg Clayton9482f052012-03-13 23:14:29 +00003257 if (m_sections_ap.get())
3258 m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00003259
Greg Clayton9482f052012-03-13 23:14:29 +00003260 if (m_symtab_ap.get())
3261 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
3262 }
Chris Lattner24943d22010-06-08 16:52:24 +00003263}
3264
3265
3266bool
Greg Clayton0467c782011-02-04 18:53:10 +00003267ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner24943d22010-06-08 16:52:24 +00003268{
Greg Clayton9482f052012-03-13 23:14:29 +00003269 ModuleSP module_sp(GetModule());
3270 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00003271 {
Greg Clayton9482f052012-03-13 23:14:29 +00003272 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3273 struct uuid_command load_cmd;
3274 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3275 uint32_t i;
3276 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00003277 {
Greg Clayton9482f052012-03-13 23:14:29 +00003278 const uint32_t cmd_offset = offset;
3279 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
3280 break;
3281
3282 if (load_cmd.cmd == LoadCommandUUID)
Chris Lattner24943d22010-06-08 16:52:24 +00003283 {
Greg Clayton9482f052012-03-13 23:14:29 +00003284 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
Sean Callanana5689d52012-07-12 18:04:03 +00003285
Greg Clayton9482f052012-03-13 23:14:29 +00003286 if (uuid_bytes)
3287 {
Sean Callanana5689d52012-07-12 18:04:03 +00003288 // OpenCL on Mac OS X uses the same UUID for each of its object files.
3289 // We pretend these object files have no UUID to prevent crashing.
3290
3291 const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
3292 0x3b, 0xa8,
3293 0x4b, 0x16,
3294 0xb6, 0xa4,
3295 0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
3296
3297 if (!memcmp(uuid_bytes, opencl_uuid, 16))
3298 return false;
3299
Greg Clayton9482f052012-03-13 23:14:29 +00003300 uuid->SetBytes (uuid_bytes);
3301 return true;
3302 }
3303 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00003304 }
Greg Clayton9482f052012-03-13 23:14:29 +00003305 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00003306 }
Chris Lattner24943d22010-06-08 16:52:24 +00003307 }
3308 return false;
3309}
3310
3311
3312uint32_t
3313ObjectFileMachO::GetDependentModules (FileSpecList& files)
3314{
Chris Lattner24943d22010-06-08 16:52:24 +00003315 uint32_t count = 0;
Greg Clayton9482f052012-03-13 23:14:29 +00003316 ModuleSP module_sp(GetModule());
3317 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00003318 {
Greg Clayton9482f052012-03-13 23:14:29 +00003319 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3320 struct load_command load_cmd;
3321 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3322 const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
3323 uint32_t i;
3324 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00003325 {
Greg Clayton9482f052012-03-13 23:14:29 +00003326 const uint32_t cmd_offset = offset;
3327 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
3328 break;
Chris Lattner24943d22010-06-08 16:52:24 +00003329
Greg Clayton9482f052012-03-13 23:14:29 +00003330 switch (load_cmd.cmd)
3331 {
3332 case LoadCommandDylibLoad:
3333 case LoadCommandDylibLoadWeak:
3334 case LoadCommandDylibReexport:
3335 case LoadCommandDynamicLinkerLoad:
3336 case LoadCommandFixedVMShlibLoad:
3337 case LoadCommandDylibLoadUpward:
3338 {
3339 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
3340 const char *path = m_data.PeekCStr(name_offset);
3341 // Skip any path that starts with '@' since these are usually:
3342 // @executable_path/.../file
3343 // @rpath/.../file
3344 if (path && path[0] != '@')
3345 {
3346 FileSpec file_spec(path, resolve_path);
3347 if (files.AppendIfUnique(file_spec))
3348 count++;
3349 }
3350 }
3351 break;
3352
3353 default:
3354 break;
3355 }
3356 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00003357 }
Chris Lattner24943d22010-06-08 16:52:24 +00003358 }
3359 return count;
3360}
3361
Jim Ingham28775942011-03-07 23:44:08 +00003362lldb_private::Address
3363ObjectFileMachO::GetEntryPointAddress ()
3364{
3365 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
3366 // is initialized to an invalid address, so we can just return that.
3367 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
3368
3369 if (!IsExecutable() || m_entry_point_address.IsValid())
3370 return m_entry_point_address;
3371
3372 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
3373 // /usr/include/mach-o.h, but it is basically:
3374 //
3375 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
3376 // uint32_t count - this is the count of longs in the thread state data
3377 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
3378 // <repeat this trio>
3379 //
3380 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
3381 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
3382 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
3383 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
3384 //
3385 // For now we hard-code the offsets and flavors we need:
3386 //
3387 //
3388
Greg Clayton9482f052012-03-13 23:14:29 +00003389 ModuleSP module_sp(GetModule());
3390 if (module_sp)
Jim Ingham28775942011-03-07 23:44:08 +00003391 {
Greg Clayton9482f052012-03-13 23:14:29 +00003392 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3393 struct load_command load_cmd;
3394 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3395 uint32_t i;
3396 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
3397 bool done = false;
3398
3399 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham28775942011-03-07 23:44:08 +00003400 {
Greg Clayton9482f052012-03-13 23:14:29 +00003401 const uint32_t cmd_offset = offset;
3402 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
3403 break;
3404
3405 switch (load_cmd.cmd)
Jim Ingham28775942011-03-07 23:44:08 +00003406 {
Greg Clayton9482f052012-03-13 23:14:29 +00003407 case LoadCommandUnixThread:
3408 case LoadCommandThread:
Jim Ingham28775942011-03-07 23:44:08 +00003409 {
Greg Clayton9482f052012-03-13 23:14:29 +00003410 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham28775942011-03-07 23:44:08 +00003411 {
Greg Clayton9482f052012-03-13 23:14:29 +00003412 uint32_t flavor = m_data.GetU32(&offset);
3413 uint32_t count = m_data.GetU32(&offset);
3414 if (count == 0)
3415 {
3416 // We've gotten off somehow, log and exit;
3417 return m_entry_point_address;
Jim Ingham28775942011-03-07 23:44:08 +00003418 }
Greg Clayton9482f052012-03-13 23:14:29 +00003419
3420 switch (m_header.cputype)
3421 {
3422 case llvm::MachO::CPUTypeARM:
3423 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
3424 {
3425 offset += 60; // This is the offset of pc in the GPR thread state data structure.
3426 start_address = m_data.GetU32(&offset);
3427 done = true;
3428 }
Jim Ingham28775942011-03-07 23:44:08 +00003429 break;
Greg Clayton9482f052012-03-13 23:14:29 +00003430 case llvm::MachO::CPUTypeI386:
3431 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
3432 {
3433 offset += 40; // This is the offset of eip in the GPR thread state data structure.
3434 start_address = m_data.GetU32(&offset);
3435 done = true;
3436 }
3437 break;
3438 case llvm::MachO::CPUTypeX86_64:
3439 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
3440 {
3441 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
3442 start_address = m_data.GetU64(&offset);
3443 done = true;
3444 }
3445 break;
3446 default:
3447 return m_entry_point_address;
3448 }
3449 // Haven't found the GPR flavor yet, skip over the data for this flavor:
3450 if (done)
3451 break;
3452 offset += count * 4;
3453 }
Jim Ingham28775942011-03-07 23:44:08 +00003454 }
Greg Clayton9482f052012-03-13 23:14:29 +00003455 break;
3456 case LoadCommandMain:
Sean Callanan6e12c7a2012-03-08 02:39:03 +00003457 {
Greg Clayton9482f052012-03-13 23:14:29 +00003458 ConstString text_segment_name ("__TEXT");
3459 uint64_t entryoffset = m_data.GetU64(&offset);
3460 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
3461 if (text_segment_sp)
3462 {
3463 done = true;
3464 start_address = text_segment_sp->GetFileAddress() + entryoffset;
3465 }
Sean Callanan6e12c7a2012-03-08 02:39:03 +00003466 }
Greg Clayton9482f052012-03-13 23:14:29 +00003467
3468 default:
3469 break;
Sean Callanan6e12c7a2012-03-08 02:39:03 +00003470 }
Greg Clayton9482f052012-03-13 23:14:29 +00003471 if (done)
3472 break;
Jim Ingham28775942011-03-07 23:44:08 +00003473
Greg Clayton9482f052012-03-13 23:14:29 +00003474 // Go to the next load command:
3475 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham28775942011-03-07 23:44:08 +00003476 }
Jim Ingham28775942011-03-07 23:44:08 +00003477
Greg Clayton9482f052012-03-13 23:14:29 +00003478 if (start_address != LLDB_INVALID_ADDRESS)
Greg Clayton3508c382012-02-24 01:59:29 +00003479 {
Greg Clayton9482f052012-03-13 23:14:29 +00003480 // We got the start address from the load commands, so now resolve that address in the sections
3481 // of this ObjectFile:
3482 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Clayton3508c382012-02-24 01:59:29 +00003483 {
Greg Clayton9482f052012-03-13 23:14:29 +00003484 m_entry_point_address.Clear();
3485 }
3486 }
3487 else
3488 {
3489 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
3490 // "start" symbol in the main executable.
3491
3492 ModuleSP module_sp (GetModule());
3493
3494 if (module_sp)
3495 {
3496 SymbolContextList contexts;
3497 SymbolContext context;
3498 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
3499 {
3500 if (contexts.GetContextAtIndex(0, context))
3501 m_entry_point_address = context.symbol->GetAddress();
3502 }
Greg Clayton3508c382012-02-24 01:59:29 +00003503 }
3504 }
Jim Ingham28775942011-03-07 23:44:08 +00003505 }
3506
3507 return m_entry_point_address;
3508
3509}
3510
Greg Claytonb5a8f142012-02-05 02:38:54 +00003511lldb_private::Address
3512ObjectFileMachO::GetHeaderAddress ()
3513{
3514 lldb_private::Address header_addr;
3515 SectionList *section_list = GetSectionList();
3516 if (section_list)
3517 {
3518 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
3519 if (text_segment_sp)
3520 {
Greg Clayton3508c382012-02-24 01:59:29 +00003521 header_addr.SetSection (text_segment_sp);
Greg Claytonb5a8f142012-02-05 02:38:54 +00003522 header_addr.SetOffset (0);
3523 }
3524 }
3525 return header_addr;
3526}
3527
Greg Clayton46c9a352012-02-09 06:16:32 +00003528uint32_t
3529ObjectFileMachO::GetNumThreadContexts ()
3530{
Greg Clayton9482f052012-03-13 23:14:29 +00003531 ModuleSP module_sp(GetModule());
3532 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00003533 {
Greg Clayton9482f052012-03-13 23:14:29 +00003534 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3535 if (!m_thread_context_offsets_valid)
Greg Clayton46c9a352012-02-09 06:16:32 +00003536 {
Greg Clayton9482f052012-03-13 23:14:29 +00003537 m_thread_context_offsets_valid = true;
3538 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3539 FileRangeArray::Entry file_range;
3540 thread_command thread_cmd;
3541 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton46c9a352012-02-09 06:16:32 +00003542 {
Greg Clayton9482f052012-03-13 23:14:29 +00003543 const uint32_t cmd_offset = offset;
3544 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
3545 break;
3546
3547 if (thread_cmd.cmd == LoadCommandThread)
3548 {
3549 file_range.SetRangeBase (offset);
3550 file_range.SetByteSize (thread_cmd.cmdsize - 8);
3551 m_thread_context_offsets.Append (file_range);
3552 }
3553 offset = cmd_offset + thread_cmd.cmdsize;
Greg Clayton46c9a352012-02-09 06:16:32 +00003554 }
Greg Clayton46c9a352012-02-09 06:16:32 +00003555 }
3556 }
3557 return m_thread_context_offsets.GetSize();
3558}
3559
3560lldb::RegisterContextSP
3561ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
3562{
Greg Clayton46c9a352012-02-09 06:16:32 +00003563 lldb::RegisterContextSP reg_ctx_sp;
Greg Clayton9ce95382012-02-13 23:10:39 +00003564
Greg Clayton9482f052012-03-13 23:14:29 +00003565 ModuleSP module_sp(GetModule());
3566 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00003567 {
Greg Clayton9482f052012-03-13 23:14:29 +00003568 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3569 if (!m_thread_context_offsets_valid)
3570 GetNumThreadContexts ();
3571
3572 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
3573
3574 DataExtractor data (m_data,
3575 thread_context_file_range->GetRangeBase(),
3576 thread_context_file_range->GetByteSize());
3577
3578 switch (m_header.cputype)
3579 {
3580 case llvm::MachO::CPUTypeARM:
3581 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
3582 break;
3583
3584 case llvm::MachO::CPUTypeI386:
3585 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
3586 break;
3587
3588 case llvm::MachO::CPUTypeX86_64:
3589 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
3590 break;
3591 }
Greg Clayton46c9a352012-02-09 06:16:32 +00003592 }
3593 return reg_ctx_sp;
3594}
3595
Greg Claytonb5a8f142012-02-05 02:38:54 +00003596
Greg Claytonca319972011-07-09 00:41:34 +00003597ObjectFile::Type
3598ObjectFileMachO::CalculateType()
3599{
3600 switch (m_header.filetype)
3601 {
3602 case HeaderFileTypeObject: // 0x1u MH_OBJECT
3603 if (GetAddressByteSize () == 4)
3604 {
3605 // 32 bit kexts are just object files, but they do have a valid
3606 // UUID load command.
3607 UUID uuid;
3608 if (GetUUID(&uuid))
3609 {
3610 // this checking for the UUID load command is not enough
3611 // we could eventually look for the symbol named
3612 // "OSKextGetCurrentIdentifier" as this is required of kexts
3613 if (m_strata == eStrataInvalid)
3614 m_strata = eStrataKernel;
3615 return eTypeSharedLibrary;
3616 }
3617 }
3618 return eTypeObjectFile;
3619
3620 case HeaderFileTypeExecutable: return eTypeExecutable; // 0x2u MH_EXECUTE
3621 case HeaderFileTypeFixedVMShlib: return eTypeSharedLibrary; // 0x3u MH_FVMLIB
3622 case HeaderFileTypeCore: return eTypeCoreFile; // 0x4u MH_CORE
3623 case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary; // 0x5u MH_PRELOAD
3624 case HeaderFileTypeDynamicShlib: return eTypeSharedLibrary; // 0x6u MH_DYLIB
3625 case HeaderFileTypeDynamicLinkEditor: return eTypeDynamicLinker; // 0x7u MH_DYLINKER
3626 case HeaderFileTypeBundle: return eTypeSharedLibrary; // 0x8u MH_BUNDLE
3627 case HeaderFileTypeDynamicShlibStub: return eTypeStubLibrary; // 0x9u MH_DYLIB_STUB
3628 case HeaderFileTypeDSYM: return eTypeDebugInfo; // 0xAu MH_DSYM
3629 case HeaderFileTypeKextBundle: return eTypeSharedLibrary; // 0xBu MH_KEXT_BUNDLE
3630 default:
3631 break;
3632 }
3633 return eTypeUnknown;
3634}
3635
3636ObjectFile::Strata
3637ObjectFileMachO::CalculateStrata()
3638{
3639 switch (m_header.filetype)
3640 {
3641 case HeaderFileTypeObject: // 0x1u MH_OBJECT
3642 {
3643 // 32 bit kexts are just object files, but they do have a valid
3644 // UUID load command.
3645 UUID uuid;
3646 if (GetUUID(&uuid))
3647 {
3648 // this checking for the UUID load command is not enough
3649 // we could eventually look for the symbol named
3650 // "OSKextGetCurrentIdentifier" as this is required of kexts
3651 if (m_type == eTypeInvalid)
3652 m_type = eTypeSharedLibrary;
3653
3654 return eStrataKernel;
3655 }
3656 }
3657 return eStrataUnknown;
3658
3659 case HeaderFileTypeExecutable: // 0x2u MH_EXECUTE
3660 // Check for the MH_DYLDLINK bit in the flags
3661 if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
Sean Callananac725af2012-02-10 20:22:35 +00003662 {
Greg Claytonca319972011-07-09 00:41:34 +00003663 return eStrataUser;
Sean Callananac725af2012-02-10 20:22:35 +00003664 }
3665 else
3666 {
3667 SectionList *section_list = GetSectionList();
3668 if (section_list)
3669 {
3670 static ConstString g_kld_section_name ("__KLD");
3671 if (section_list->FindSectionByName(g_kld_section_name))
3672 return eStrataKernel;
3673 }
3674 }
3675 return eStrataRawImage;
Greg Claytonca319972011-07-09 00:41:34 +00003676
3677 case HeaderFileTypeFixedVMShlib: return eStrataUser; // 0x3u MH_FVMLIB
3678 case HeaderFileTypeCore: return eStrataUnknown; // 0x4u MH_CORE
Sean Callananac725af2012-02-10 20:22:35 +00003679 case HeaderFileTypePreloadedExecutable: return eStrataRawImage; // 0x5u MH_PRELOAD
Greg Claytonca319972011-07-09 00:41:34 +00003680 case HeaderFileTypeDynamicShlib: return eStrataUser; // 0x6u MH_DYLIB
3681 case HeaderFileTypeDynamicLinkEditor: return eStrataUser; // 0x7u MH_DYLINKER
3682 case HeaderFileTypeBundle: return eStrataUser; // 0x8u MH_BUNDLE
3683 case HeaderFileTypeDynamicShlibStub: return eStrataUser; // 0x9u MH_DYLIB_STUB
3684 case HeaderFileTypeDSYM: return eStrataUnknown; // 0xAu MH_DSYM
3685 case HeaderFileTypeKextBundle: return eStrataKernel; // 0xBu MH_KEXT_BUNDLE
3686 default:
3687 break;
3688 }
3689 return eStrataUnknown;
3690}
3691
3692
Greg Clayton49f4bf22012-02-22 19:41:02 +00003693uint32_t
3694ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
3695{
Greg Clayton9482f052012-03-13 23:14:29 +00003696 ModuleSP module_sp(GetModule());
3697 if (module_sp)
Greg Clayton49f4bf22012-02-22 19:41:02 +00003698 {
Greg Clayton9482f052012-03-13 23:14:29 +00003699 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3700 struct dylib_command load_cmd;
3701 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3702 uint32_t version_cmd = 0;
3703 uint64_t version = 0;
3704 uint32_t i;
3705 for (i=0; i<m_header.ncmds; ++i)
Greg Clayton49f4bf22012-02-22 19:41:02 +00003706 {
Greg Clayton9482f052012-03-13 23:14:29 +00003707 const uint32_t cmd_offset = offset;
3708 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
3709 break;
3710
3711 if (load_cmd.cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00003712 {
Greg Clayton9482f052012-03-13 23:14:29 +00003713 if (version_cmd == 0)
3714 {
3715 version_cmd = load_cmd.cmd;
3716 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
3717 break;
3718 version = load_cmd.dylib.current_version;
3719 }
3720 break; // Break for now unless there is another more complete version
3721 // number load command in the future.
Greg Clayton49f4bf22012-02-22 19:41:02 +00003722 }
Greg Clayton9482f052012-03-13 23:14:29 +00003723 offset = cmd_offset + load_cmd.cmdsize;
Greg Clayton49f4bf22012-02-22 19:41:02 +00003724 }
Greg Clayton9482f052012-03-13 23:14:29 +00003725
3726 if (version_cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00003727 {
Greg Clayton9482f052012-03-13 23:14:29 +00003728 if (versions != NULL && num_versions > 0)
3729 {
3730 if (num_versions > 0)
3731 versions[0] = (version & 0xFFFF0000ull) >> 16;
3732 if (num_versions > 1)
3733 versions[1] = (version & 0x0000FF00ull) >> 8;
3734 if (num_versions > 2)
3735 versions[2] = (version & 0x000000FFull);
3736 // Fill in an remaining version numbers with invalid values
3737 for (i=3; i<num_versions; ++i)
3738 versions[i] = UINT32_MAX;
3739 }
3740 // The LC_ID_DYLIB load command has a version with 3 version numbers
3741 // in it, so always return 3
3742 return 3;
Greg Clayton49f4bf22012-02-22 19:41:02 +00003743 }
Greg Clayton49f4bf22012-02-22 19:41:02 +00003744 }
3745 return false;
3746}
3747
Chris Lattner24943d22010-06-08 16:52:24 +00003748bool
Greg Clayton395fc332011-02-15 21:59:32 +00003749ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +00003750{
Greg Clayton9482f052012-03-13 23:14:29 +00003751 ModuleSP module_sp(GetModule());
3752 if (module_sp)
Greg Clayton6a64bbf2011-09-21 03:57:31 +00003753 {
Greg Clayton9482f052012-03-13 23:14:29 +00003754 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3755 arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
3756
3757 // Files with type MH_PRELOAD are currently used in cases where the image
3758 // debugs at the addresses in the file itself. Below we set the OS to
3759 // unknown to make sure we use the DynamicLoaderStatic()...
3760 if (m_header.filetype == HeaderFileTypePreloadedExecutable)
3761 {
3762 arch.GetTriple().setOS (llvm::Triple::UnknownOS);
3763 }
3764 return true;
Greg Clayton6a64bbf2011-09-21 03:57:31 +00003765 }
Greg Clayton9482f052012-03-13 23:14:29 +00003766 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00003767}
3768
3769
3770//------------------------------------------------------------------
3771// PluginInterface protocol
3772//------------------------------------------------------------------
3773const char *
3774ObjectFileMachO::GetPluginName()
3775{
3776 return "ObjectFileMachO";
3777}
3778
3779const char *
3780ObjectFileMachO::GetShortPluginName()
3781{
3782 return GetPluginNameStatic();
3783}
3784
3785uint32_t
3786ObjectFileMachO::GetPluginVersion()
3787{
3788 return 1;
3789}
3790