blob: ac03b177c1b9d6edf01b0926871ae0a8c6b29a15 [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
Chris Lattner24943d22010-06-08 16:52:24 +000015#include "lldb/Core/ArchSpec.h"
16#include "lldb/Core/DataBuffer.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/FileSpecList.h"
18#include "lldb/Core/Module.h"
19#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/Section.h"
21#include "lldb/Core/StreamFile.h"
22#include "lldb/Core/StreamString.h"
23#include "lldb/Core/Timer.h"
24#include "lldb/Core/UUID.h"
Greg Claytondf6dc882012-01-05 03:57:59 +000025#include "lldb/Host/Host.h"
26#include "lldb/Host/FileSpec.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000027#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Symbol/ObjectFile.h"
Greg Claytonb5a8f142012-02-05 02:38:54 +000029#include "lldb/Target/Process.h"
Greg Clayton9ce95382012-02-13 23:10:39 +000030#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
31#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
Greg Clayton46c9a352012-02-09 06:16:32 +000032#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner24943d22010-06-08 16:52:24 +000033
Chris Lattner24943d22010-06-08 16:52:24 +000034
35using namespace lldb;
36using namespace lldb_private;
Greg Clayton1674b122010-07-21 22:12:05 +000037using namespace llvm::MachO;
Chris Lattner24943d22010-06-08 16:52:24 +000038
Greg Clayton46c9a352012-02-09 06:16:32 +000039class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
40{
41public:
42 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
43 RegisterContextDarwin_x86_64 (thread, 0)
44 {
45 SetRegisterDataFrom_LC_THREAD (data);
46 }
47
48 virtual void
49 InvalidateAllRegisters ()
50 {
51 // Do nothing... registers are always valid...
52 }
53
54 void
55 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
56 {
Greg Clayton46c9a352012-02-09 06:16:32 +000057 uint32_t offset = 0;
58 SetError (GPRRegSet, Read, -1);
59 SetError (FPURegSet, Read, -1);
60 SetError (EXCRegSet, Read, -1);
Greg Clayton9ce95382012-02-13 23:10:39 +000061 bool done = false;
62
63 while (!done)
Greg Clayton46c9a352012-02-09 06:16:32 +000064 {
Greg Clayton9ce95382012-02-13 23:10:39 +000065 int flavor = data.GetU32 (&offset);
66 if (flavor == 0)
67 done = true;
68 else
Greg Clayton46c9a352012-02-09 06:16:32 +000069 {
Greg Clayton9ce95382012-02-13 23:10:39 +000070 uint32_t i;
71 uint32_t count = data.GetU32 (&offset);
72 switch (flavor)
73 {
74 case GPRRegSet:
75 for (i=0; i<count; ++i)
76 (&gpr.rax)[i] = data.GetU64(&offset);
77 SetError (GPRRegSet, Read, 0);
78 done = true;
79
80 break;
81 case FPURegSet:
82 // TODO: fill in FPU regs....
83 //SetError (FPURegSet, Read, -1);
84 done = true;
85
86 break;
87 case EXCRegSet:
88 exc.trapno = data.GetU32(&offset);
89 exc.err = data.GetU32(&offset);
90 exc.faultvaddr = data.GetU64(&offset);
91 SetError (EXCRegSet, Read, 0);
92 done = true;
93 break;
94 case 7:
95 case 8:
96 case 9:
97 // fancy flavors that encapsulate of the the above
98 // falvors...
99 break;
100
101 default:
102 done = true;
103 break;
104 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000105 }
Greg Clayton9ce95382012-02-13 23:10:39 +0000106 }
107 }
108protected:
109 virtual int
110 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
111 {
112 return 0;
113 }
114
115 virtual int
116 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
117 {
118 return 0;
119 }
120
121 virtual int
122 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
123 {
124 return 0;
125 }
126
127 virtual int
128 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
129 {
130 return 0;
131 }
132
133 virtual int
134 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
135 {
136 return 0;
137 }
138
139 virtual int
140 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
141 {
142 return 0;
143 }
144};
Greg Clayton46c9a352012-02-09 06:16:32 +0000145
Greg Clayton9ce95382012-02-13 23:10:39 +0000146
147class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
148{
149public:
150 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
151 RegisterContextDarwin_i386 (thread, 0)
152 {
153 SetRegisterDataFrom_LC_THREAD (data);
154 }
155
156 virtual void
157 InvalidateAllRegisters ()
158 {
159 // Do nothing... registers are always valid...
160 }
161
162 void
163 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
164 {
165 uint32_t offset = 0;
166 SetError (GPRRegSet, Read, -1);
167 SetError (FPURegSet, Read, -1);
168 SetError (EXCRegSet, Read, -1);
169 bool done = false;
170
171 while (!done)
172 {
173 int flavor = data.GetU32 (&offset);
174 if (flavor == 0)
175 done = true;
176 else
Greg Clayton46c9a352012-02-09 06:16:32 +0000177 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000178 uint32_t i;
179 uint32_t count = data.GetU32 (&offset);
180 switch (flavor)
181 {
182 case GPRRegSet:
183 for (i=0; i<count; ++i)
184 (&gpr.eax)[i] = data.GetU32(&offset);
185 SetError (GPRRegSet, Read, 0);
186 done = true;
187
188 break;
189 case FPURegSet:
190 // TODO: fill in FPU regs....
191 //SetError (FPURegSet, Read, -1);
192 done = true;
193
194 break;
195 case EXCRegSet:
196 exc.trapno = data.GetU32(&offset);
197 exc.err = data.GetU32(&offset);
198 exc.faultvaddr = data.GetU32(&offset);
199 SetError (EXCRegSet, Read, 0);
200 done = true;
201 break;
202 case 7:
203 case 8:
204 case 9:
205 // fancy flavors that encapsulate of the the above
206 // falvors...
207 break;
208
209 default:
210 done = true;
211 break;
212 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000213 }
214 }
215 }
216protected:
217 virtual int
218 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
219 {
220 return 0;
221 }
222
223 virtual int
224 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
225 {
226 return 0;
227 }
228
229 virtual int
230 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
231 {
232 return 0;
233 }
234
235 virtual int
236 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
237 {
238 return 0;
239 }
240
241 virtual int
242 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
243 {
244 return 0;
245 }
246
247 virtual int
248 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
249 {
250 return 0;
251 }
252};
253
Greg Clayton9ce95382012-02-13 23:10:39 +0000254class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
255{
256public:
257 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
258 RegisterContextDarwin_arm (thread, 0)
259 {
260 SetRegisterDataFrom_LC_THREAD (data);
261 }
262
263 virtual void
264 InvalidateAllRegisters ()
265 {
266 // Do nothing... registers are always valid...
267 }
268
269 void
270 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
271 {
272 uint32_t offset = 0;
273 SetError (GPRRegSet, Read, -1);
274 SetError (FPURegSet, Read, -1);
275 SetError (EXCRegSet, Read, -1);
276 int flavor = data.GetU32 (&offset);
277 uint32_t count = data.GetU32 (&offset);
278 switch (flavor)
279 {
280 case GPRRegSet:
281 for (uint32_t i=0; i<count; ++i)
282 gpr.r[i] = data.GetU32(&offset);
283 SetError (GPRRegSet, Read, 0);
284 break;
285 case FPURegSet:
286 // TODO: fill in FPU regs....
287 //SetError (FPURegSet, Read, -1);
288 break;
289 case EXCRegSet:
290 exc.exception = data.GetU32(&offset);
291 exc.fsr = data.GetU32(&offset);
292 exc.far = data.GetU32(&offset);
293 SetError (EXCRegSet, Read, 0);
294 break;
295 }
296 }
297protected:
298 virtual int
299 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
300 {
301 return 0;
302 }
303
304 virtual int
305 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
306 {
307 return 0;
308 }
309
310 virtual int
311 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
312 {
313 return 0;
314 }
315
316 virtual int
317 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
318 {
319 return 0;
320 }
321
322 virtual int
323 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
324 {
325 return 0;
326 }
327
328 virtual int
329 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
330 {
331 return 0;
332 }
333};
334
Greg Claytonb1888f22011-03-19 01:12:21 +0000335#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner24943d22010-06-08 16:52:24 +0000336
337void
338ObjectFileMachO::Initialize()
339{
340 PluginManager::RegisterPlugin (GetPluginNameStatic(),
341 GetPluginDescriptionStatic(),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000342 CreateInstance,
343 CreateMemoryInstance);
Chris Lattner24943d22010-06-08 16:52:24 +0000344}
345
346void
347ObjectFileMachO::Terminate()
348{
349 PluginManager::UnregisterPlugin (CreateInstance);
350}
351
352
353const char *
354ObjectFileMachO::GetPluginNameStatic()
355{
356 return "object-file.mach-o";
357}
358
359const char *
360ObjectFileMachO::GetPluginDescriptionStatic()
361{
362 return "Mach-o object file reader (32 and 64 bit)";
363}
364
365
366ObjectFile *
Greg Clayton3508c382012-02-24 01:59:29 +0000367ObjectFileMachO::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 +0000368{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000369 if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length))
Chris Lattner24943d22010-06-08 16:52:24 +0000370 {
Greg Clayton3508c382012-02-24 01:59:29 +0000371 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, file, offset, length));
Chris Lattner24943d22010-06-08 16:52:24 +0000372 if (objfile_ap.get() && objfile_ap->ParseHeader())
373 return objfile_ap.release();
374 }
375 return NULL;
376}
377
Greg Claytonb5a8f142012-02-05 02:38:54 +0000378ObjectFile *
Greg Clayton3508c382012-02-24 01:59:29 +0000379ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000380 DataBufferSP& data_sp,
381 const ProcessSP &process_sp,
382 lldb::addr_t header_addr)
383{
384 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
385 {
Greg Clayton3508c382012-02-24 01:59:29 +0000386 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonb5a8f142012-02-05 02:38:54 +0000387 if (objfile_ap.get() && objfile_ap->ParseHeader())
388 return objfile_ap.release();
389 }
390 return NULL;
391}
392
393
394const ConstString &
395ObjectFileMachO::GetSegmentNameTEXT()
396{
397 static ConstString g_segment_name_TEXT ("__TEXT");
398 return g_segment_name_TEXT;
399}
400
401const ConstString &
402ObjectFileMachO::GetSegmentNameDATA()
403{
404 static ConstString g_segment_name_DATA ("__DATA");
405 return g_segment_name_DATA;
406}
407
408const ConstString &
409ObjectFileMachO::GetSegmentNameOBJC()
410{
411 static ConstString g_segment_name_OBJC ("__OBJC");
412 return g_segment_name_OBJC;
413}
414
415const ConstString &
416ObjectFileMachO::GetSegmentNameLINKEDIT()
417{
418 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
419 return g_section_name_LINKEDIT;
420}
421
422const ConstString &
423ObjectFileMachO::GetSectionNameEHFrame()
424{
425 static ConstString g_section_name_eh_frame ("__eh_frame");
426 return g_section_name_eh_frame;
427}
428
429
Chris Lattner24943d22010-06-08 16:52:24 +0000430
431static uint32_t
432MachHeaderSizeFromMagic(uint32_t magic)
433{
434 switch (magic)
435 {
Greg Clayton1674b122010-07-21 22:12:05 +0000436 case HeaderMagic32:
437 case HeaderMagic32Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000438 return sizeof(struct mach_header);
439
Greg Clayton1674b122010-07-21 22:12:05 +0000440 case HeaderMagic64:
441 case HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000442 return sizeof(struct mach_header_64);
443 break;
444
445 default:
446 break;
447 }
448 return 0;
449}
450
451
452bool
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000453ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
454 lldb::addr_t data_offset,
455 lldb::addr_t data_length)
Chris Lattner24943d22010-06-08 16:52:24 +0000456{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000457 DataExtractor data;
458 data.SetData (data_sp, data_offset, data_length);
Chris Lattner24943d22010-06-08 16:52:24 +0000459 uint32_t offset = 0;
460 uint32_t magic = data.GetU32(&offset);
461 return MachHeaderSizeFromMagic(magic) != 0;
462}
463
464
Greg Clayton3508c382012-02-24 01:59:29 +0000465ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) :
466 ObjectFile(module_sp, file, offset, length, data_sp),
Chris Lattner24943d22010-06-08 16:52:24 +0000467 m_mutex (Mutex::eMutexTypeRecursive),
Chris Lattner24943d22010-06-08 16:52:24 +0000468 m_sections_ap(),
Jim Ingham28775942011-03-07 23:44:08 +0000469 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000470 m_mach_segments(),
471 m_mach_sections(),
472 m_entry_point_address(),
473 m_thread_context_offsets(),
474 m_thread_context_offsets_valid(false)
Chris Lattner24943d22010-06-08 16:52:24 +0000475{
Greg Claytonddff7cc2011-02-04 21:13:05 +0000476 ::memset (&m_header, 0, sizeof(m_header));
477 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner24943d22010-06-08 16:52:24 +0000478}
479
Greg Clayton3508c382012-02-24 01:59:29 +0000480ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000481 lldb::DataBufferSP& header_data_sp,
482 const lldb::ProcessSP &process_sp,
483 lldb::addr_t header_addr) :
Greg Clayton3508c382012-02-24 01:59:29 +0000484 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000485 m_mutex (Mutex::eMutexTypeRecursive),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000486 m_sections_ap(),
487 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000488 m_mach_segments(),
489 m_mach_sections(),
490 m_entry_point_address(),
491 m_thread_context_offsets(),
492 m_thread_context_offsets_valid(false)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000493{
494 ::memset (&m_header, 0, sizeof(m_header));
495 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
496}
Chris Lattner24943d22010-06-08 16:52:24 +0000497
498ObjectFileMachO::~ObjectFileMachO()
499{
500}
501
502
503bool
504ObjectFileMachO::ParseHeader ()
505{
506 lldb_private::Mutex::Locker locker(m_mutex);
507 bool can_parse = false;
508 uint32_t offset = 0;
Greg Claytoncd548032011-02-01 01:31:41 +0000509 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000510 // Leave magic in the original byte order
511 m_header.magic = m_data.GetU32(&offset);
512 switch (m_header.magic)
513 {
Greg Clayton1674b122010-07-21 22:12:05 +0000514 case HeaderMagic32:
Greg Claytoncd548032011-02-01 01:31:41 +0000515 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000516 m_data.SetAddressByteSize(4);
517 can_parse = true;
518 break;
519
Greg Clayton1674b122010-07-21 22:12:05 +0000520 case HeaderMagic64:
Greg Claytoncd548032011-02-01 01:31:41 +0000521 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000522 m_data.SetAddressByteSize(8);
523 can_parse = true;
524 break;
525
Greg Clayton1674b122010-07-21 22:12:05 +0000526 case HeaderMagic32Swapped:
Greg Claytoncd548032011-02-01 01:31:41 +0000527 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Chris Lattner24943d22010-06-08 16:52:24 +0000528 m_data.SetAddressByteSize(4);
529 can_parse = true;
530 break;
531
Greg Clayton1674b122010-07-21 22:12:05 +0000532 case HeaderMagic64Swapped:
Greg Claytoncd548032011-02-01 01:31:41 +0000533 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Chris Lattner24943d22010-06-08 16:52:24 +0000534 m_data.SetAddressByteSize(8);
535 can_parse = true;
536 break;
537
538 default:
539 break;
540 }
541
542 if (can_parse)
543 {
544 m_data.GetU32(&offset, &m_header.cputype, 6);
545
Greg Claytoncf015052010-06-11 03:25:34 +0000546 ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Jim Ingham7508e732010-08-09 23:31:02 +0000547
548 if (SetModulesArchitecture (mach_arch))
Greg Claytonb5a8f142012-02-05 02:38:54 +0000549 {
550 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
551 if (m_data.GetByteSize() < header_and_lc_size)
552 {
553 DataBufferSP data_sp;
554 ProcessSP process_sp (m_process_wp.lock());
555 if (process_sp)
556 {
557 data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
558 }
559 else
560 {
561 // Read in all only the load command data from the file on disk
562 data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
563 if (data_sp->GetByteSize() != header_and_lc_size)
564 return false;
565 }
566 if (data_sp)
567 m_data.SetData (data_sp);
568 }
569 }
570 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000571 }
572 else
573 {
574 memset(&m_header, 0, sizeof(struct mach_header));
575 }
576 return false;
577}
578
579
580ByteOrder
581ObjectFileMachO::GetByteOrder () const
582{
583 lldb_private::Mutex::Locker locker(m_mutex);
584 return m_data.GetByteOrder ();
585}
586
Jim Ingham7508e732010-08-09 23:31:02 +0000587bool
588ObjectFileMachO::IsExecutable() const
589{
590 return m_header.filetype == HeaderFileTypeExecutable;
591}
Chris Lattner24943d22010-06-08 16:52:24 +0000592
593size_t
594ObjectFileMachO::GetAddressByteSize () const
595{
596 lldb_private::Mutex::Locker locker(m_mutex);
597 return m_data.GetAddressByteSize ();
598}
599
Greg Claytonb3448432011-03-24 21:19:54 +0000600AddressClass
Greg Claytonb1888f22011-03-19 01:12:21 +0000601ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
602{
603 Symtab *symtab = GetSymtab();
604 if (symtab)
605 {
606 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
607 if (symbol)
608 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000609 if (symbol->ValueIsAddress())
Greg Claytonb1888f22011-03-19 01:12:21 +0000610 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000611 SectionSP section_sp (symbol->GetAddress().GetSection());
Greg Clayton3508c382012-02-24 01:59:29 +0000612 if (section_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000613 {
Greg Clayton3508c382012-02-24 01:59:29 +0000614 const SectionType section_type = section_sp->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000615 switch (section_type)
616 {
617 case eSectionTypeInvalid: return eAddressClassUnknown;
618 case eSectionTypeCode:
619 if (m_header.cputype == llvm::MachO::CPUTypeARM)
620 {
621 // For ARM we have a bit in the n_desc field of the symbol
622 // that tells us ARM/Thumb which is bit 0x0008.
623 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
624 return eAddressClassCodeAlternateISA;
625 }
626 return eAddressClassCode;
627
628 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000629 case eSectionTypeData:
630 case eSectionTypeDataCString:
631 case eSectionTypeDataCStringPointers:
632 case eSectionTypeDataSymbolAddress:
633 case eSectionTypeData4:
634 case eSectionTypeData8:
635 case eSectionTypeData16:
636 case eSectionTypeDataPointers:
637 case eSectionTypeZeroFill:
638 case eSectionTypeDataObjCMessageRefs:
639 case eSectionTypeDataObjCCFStrings:
640 return eAddressClassData;
641 case eSectionTypeDebug:
642 case eSectionTypeDWARFDebugAbbrev:
643 case eSectionTypeDWARFDebugAranges:
644 case eSectionTypeDWARFDebugFrame:
645 case eSectionTypeDWARFDebugInfo:
646 case eSectionTypeDWARFDebugLine:
647 case eSectionTypeDWARFDebugLoc:
648 case eSectionTypeDWARFDebugMacInfo:
649 case eSectionTypeDWARFDebugPubNames:
650 case eSectionTypeDWARFDebugPubTypes:
651 case eSectionTypeDWARFDebugRanges:
652 case eSectionTypeDWARFDebugStr:
653 case eSectionTypeDWARFAppleNames:
654 case eSectionTypeDWARFAppleTypes:
655 case eSectionTypeDWARFAppleNamespaces:
656 case eSectionTypeDWARFAppleObjC:
657 return eAddressClassDebug;
Greg Claytonb1888f22011-03-19 01:12:21 +0000658 case eSectionTypeEHFrame: return eAddressClassRuntime;
659 case eSectionTypeOther: return eAddressClassUnknown;
660 }
661 }
662 }
663
Greg Claytonb3448432011-03-24 21:19:54 +0000664 const SymbolType symbol_type = symbol->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000665 switch (symbol_type)
666 {
667 case eSymbolTypeAny: return eAddressClassUnknown;
668 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Greg Claytonb1888f22011-03-19 01:12:21 +0000669
670 case eSymbolTypeCode:
671 case eSymbolTypeTrampoline:
672 if (m_header.cputype == llvm::MachO::CPUTypeARM)
673 {
674 // For ARM we have a bit in the n_desc field of the symbol
675 // that tells us ARM/Thumb which is bit 0x0008.
676 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
677 return eAddressClassCodeAlternateISA;
678 }
679 return eAddressClassCode;
680
681 case eSymbolTypeData: return eAddressClassData;
682 case eSymbolTypeRuntime: return eAddressClassRuntime;
683 case eSymbolTypeException: return eAddressClassRuntime;
684 case eSymbolTypeSourceFile: return eAddressClassDebug;
685 case eSymbolTypeHeaderFile: return eAddressClassDebug;
686 case eSymbolTypeObjectFile: return eAddressClassDebug;
687 case eSymbolTypeCommonBlock: return eAddressClassDebug;
688 case eSymbolTypeBlock: return eAddressClassDebug;
689 case eSymbolTypeLocal: return eAddressClassData;
690 case eSymbolTypeParam: return eAddressClassData;
691 case eSymbolTypeVariable: return eAddressClassData;
692 case eSymbolTypeVariableType: return eAddressClassDebug;
693 case eSymbolTypeLineEntry: return eAddressClassDebug;
694 case eSymbolTypeLineHeader: return eAddressClassDebug;
695 case eSymbolTypeScopeBegin: return eAddressClassDebug;
696 case eSymbolTypeScopeEnd: return eAddressClassDebug;
697 case eSymbolTypeAdditional: return eAddressClassUnknown;
698 case eSymbolTypeCompiler: return eAddressClassDebug;
699 case eSymbolTypeInstrumentation:return eAddressClassDebug;
700 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton3f69eac2011-12-03 02:30:59 +0000701 case eSymbolTypeObjCClass: return eAddressClassRuntime;
702 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
703 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Claytonb1888f22011-03-19 01:12:21 +0000704 }
705 }
706 }
707 return eAddressClassUnknown;
708}
Chris Lattner24943d22010-06-08 16:52:24 +0000709
710Symtab *
711ObjectFileMachO::GetSymtab()
712{
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000713 lldb_private::Mutex::Locker symfile_locker(m_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000714 if (m_symtab_ap.get() == NULL)
715 {
716 m_symtab_ap.reset(new Symtab(this));
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000717 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
Greg Clayton7c36fa02010-09-11 03:13:28 +0000718 ParseSymtab (true);
Greg Clayton0c496cd2011-11-22 18:47:24 +0000719 m_symtab_ap->Finalize ();
Chris Lattner24943d22010-06-08 16:52:24 +0000720 }
721 return m_symtab_ap.get();
722}
723
724
725SectionList *
726ObjectFileMachO::GetSectionList()
727{
728 lldb_private::Mutex::Locker locker(m_mutex);
729 if (m_sections_ap.get() == NULL)
730 {
731 m_sections_ap.reset(new SectionList());
732 ParseSections();
733 }
734 return m_sections_ap.get();
735}
736
737
738size_t
739ObjectFileMachO::ParseSections ()
740{
741 lldb::user_id_t segID = 0;
742 lldb::user_id_t sectID = 0;
743 struct segment_command_64 load_cmd;
744 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
745 uint32_t i;
Greg Clayton46c9a352012-02-09 06:16:32 +0000746 const bool is_core = GetType() == eTypeCoreFile;
Chris Lattner24943d22010-06-08 16:52:24 +0000747 //bool dump_sections = false;
Greg Clayton3508c382012-02-24 01:59:29 +0000748 ModuleSP module_sp (GetModule());
Chris Lattner24943d22010-06-08 16:52:24 +0000749 for (i=0; i<m_header.ncmds; ++i)
750 {
751 const uint32_t load_cmd_offset = offset;
752 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
753 break;
754
Greg Clayton1674b122010-07-21 22:12:05 +0000755 if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
Chris Lattner24943d22010-06-08 16:52:24 +0000756 {
757 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
758 {
759 load_cmd.vmaddr = m_data.GetAddress(&offset);
760 load_cmd.vmsize = m_data.GetAddress(&offset);
761 load_cmd.fileoff = m_data.GetAddress(&offset);
762 load_cmd.filesize = m_data.GetAddress(&offset);
763 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
764 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000765
766 const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
767
Chris Lattner24943d22010-06-08 16:52:24 +0000768 // Keep a list of mach segments around in case we need to
769 // get at data that isn't stored in the abstracted Sections.
770 m_mach_segments.push_back (load_cmd);
771
772 ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
773 // Use a segment ID of the segment index shifted left by 8 so they
774 // never conflict with any of the sections.
775 SectionSP segment_sp;
Greg Clayton46c9a352012-02-09 06:16:32 +0000776 if (segment_name || is_core)
Chris Lattner24943d22010-06-08 16:52:24 +0000777 {
Greg Clayton3508c382012-02-24 01:59:29 +0000778 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
Chris Lattner24943d22010-06-08 16:52:24 +0000779 ++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
780 segment_name, // Name of this section
781 eSectionTypeContainer, // This section is a container of other sections.
782 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
783 load_cmd.vmsize, // VM size in bytes of this section
784 load_cmd.fileoff, // Offset to the data for this section in the file
785 load_cmd.filesize, // Size in bytes of this section as found in the the file
786 load_cmd.flags)); // Flags for this section
787
Greg Clayton68ca8232011-01-25 02:58:48 +0000788 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000789 m_sections_ap->AddSection(segment_sp);
790 }
791
792 struct section_64 sect64;
Greg Claytonddff7cc2011-02-04 21:13:05 +0000793 ::memset (&sect64, 0, sizeof(sect64));
Chris Lattner24943d22010-06-08 16:52:24 +0000794 // Push a section into our mach sections for the section at
Greg Clayton6af4fad2010-10-06 01:26:32 +0000795 // index zero (NListSectionNoSection) if we don't have any
796 // mach sections yet...
797 if (m_mach_sections.empty())
798 m_mach_sections.push_back(sect64);
Chris Lattner24943d22010-06-08 16:52:24 +0000799 uint32_t segment_sect_idx;
800 const lldb::user_id_t first_segment_sectID = sectID + 1;
801
802
Greg Clayton1674b122010-07-21 22:12:05 +0000803 const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
Chris Lattner24943d22010-06-08 16:52:24 +0000804 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
805 {
806 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
807 break;
808 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
809 break;
810 sect64.addr = m_data.GetAddress(&offset);
811 sect64.size = m_data.GetAddress(&offset);
812
813 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
814 break;
815
816 // Keep a list of mach sections around in case we need to
817 // get at data that isn't stored in the abstracted Sections.
818 m_mach_sections.push_back (sect64);
819
820 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
821 if (!segment_name)
822 {
823 // We have a segment with no name so we need to conjure up
824 // segments that correspond to the section's segname if there
825 // isn't already such a section. If there is such a section,
826 // we resize the section so that it spans all sections.
827 // We also mark these sections as fake so address matches don't
828 // hit if they land in the gaps between the child sections.
829 segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
830 segment_sp = m_sections_ap->FindSectionByName (segment_name);
831 if (segment_sp.get())
832 {
833 Section *segment = segment_sp.get();
834 // Grow the section size as needed.
835 const lldb::addr_t sect64_min_addr = sect64.addr;
836 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
837 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
838 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
839 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
840 if (sect64_min_addr >= curr_seg_min_addr)
841 {
842 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
843 // Only grow the section size if needed
844 if (new_seg_byte_size > curr_seg_byte_size)
845 segment->SetByteSize (new_seg_byte_size);
846 }
847 else
848 {
849 // We need to change the base address of the segment and
850 // adjust the child section offsets for all existing children.
851 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
852 segment->Slide(slide_amount, false);
853 segment->GetChildren().Slide (-slide_amount, false);
854 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
855 }
Greg Clayton661825b2010-06-28 23:51:11 +0000856
857 // Grow the section size as needed.
858 if (sect64.offset)
859 {
860 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
861 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
862
863 const lldb::addr_t section_min_file_offset = sect64.offset;
864 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
865 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
866 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
867 segment->SetFileOffset (new_file_offset);
868 segment->SetFileSize (new_file_size);
869 }
Chris Lattner24943d22010-06-08 16:52:24 +0000870 }
871 else
872 {
873 // Create a fake section for the section's named segment
Greg Clayton3508c382012-02-24 01:59:29 +0000874 segment_sp.reset(new Section (segment_sp, // Parent section
875 module_sp, // Module to which this section belongs
876 ++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
877 segment_name, // Name of this section
878 eSectionTypeContainer, // This section is a container of other sections.
879 sect64.addr, // File VM address == addresses as they are found in the object file
880 sect64.size, // VM size in bytes of this section
881 sect64.offset, // Offset to the data for this section in the file
882 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
883 load_cmd.flags)); // Flags for this section
Chris Lattner24943d22010-06-08 16:52:24 +0000884 segment_sp->SetIsFake(true);
885 m_sections_ap->AddSection(segment_sp);
Greg Clayton68ca8232011-01-25 02:58:48 +0000886 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000887 }
888 }
889 assert (segment_sp.get());
890
Greg Clayton1674b122010-07-21 22:12:05 +0000891 uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
Chris Lattner24943d22010-06-08 16:52:24 +0000892 static ConstString g_sect_name_objc_data ("__objc_data");
893 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
894 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
895 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
896 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
897 static ConstString g_sect_name_objc_const ("__objc_const");
898 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
899 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000900
901 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
902 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
903 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
904 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
905 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
906 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
907 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
908 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
909 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
910 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
911 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
Greg Claytonf6e3de22011-09-28 17:06:40 +0000912 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
913 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
Greg Clayton00db2152011-10-04 22:41:51 +0000914 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
Greg Clayton24a6bd92011-10-27 17:55:14 +0000915 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000916 static ConstString g_sect_name_eh_frame ("__eh_frame");
Greg Clayton3fed8b92010-10-08 00:21:05 +0000917 static ConstString g_sect_name_DATA ("__DATA");
918 static ConstString g_sect_name_TEXT ("__TEXT");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000919
Chris Lattner24943d22010-06-08 16:52:24 +0000920 SectionType sect_type = eSectionTypeOther;
921
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000922 if (section_name == g_sect_name_dwarf_debug_abbrev)
923 sect_type = eSectionTypeDWARFDebugAbbrev;
924 else if (section_name == g_sect_name_dwarf_debug_aranges)
925 sect_type = eSectionTypeDWARFDebugAranges;
926 else if (section_name == g_sect_name_dwarf_debug_frame)
927 sect_type = eSectionTypeDWARFDebugFrame;
928 else if (section_name == g_sect_name_dwarf_debug_info)
929 sect_type = eSectionTypeDWARFDebugInfo;
930 else if (section_name == g_sect_name_dwarf_debug_line)
931 sect_type = eSectionTypeDWARFDebugLine;
932 else if (section_name == g_sect_name_dwarf_debug_loc)
933 sect_type = eSectionTypeDWARFDebugLoc;
934 else if (section_name == g_sect_name_dwarf_debug_macinfo)
935 sect_type = eSectionTypeDWARFDebugMacInfo;
936 else if (section_name == g_sect_name_dwarf_debug_pubnames)
937 sect_type = eSectionTypeDWARFDebugPubNames;
938 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
939 sect_type = eSectionTypeDWARFDebugPubTypes;
940 else if (section_name == g_sect_name_dwarf_debug_ranges)
941 sect_type = eSectionTypeDWARFDebugRanges;
942 else if (section_name == g_sect_name_dwarf_debug_str)
943 sect_type = eSectionTypeDWARFDebugStr;
Greg Claytonf6e3de22011-09-28 17:06:40 +0000944 else if (section_name == g_sect_name_dwarf_apple_names)
945 sect_type = eSectionTypeDWARFAppleNames;
946 else if (section_name == g_sect_name_dwarf_apple_types)
947 sect_type = eSectionTypeDWARFAppleTypes;
Greg Clayton00db2152011-10-04 22:41:51 +0000948 else if (section_name == g_sect_name_dwarf_apple_namespaces)
949 sect_type = eSectionTypeDWARFAppleNamespaces;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000950 else if (section_name == g_sect_name_dwarf_apple_objc)
951 sect_type = eSectionTypeDWARFAppleObjC;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000952 else if (section_name == g_sect_name_objc_selrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000953 sect_type = eSectionTypeDataCStringPointers;
Chris Lattner24943d22010-06-08 16:52:24 +0000954 else if (section_name == g_sect_name_objc_msgrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000955 sect_type = eSectionTypeDataObjCMessageRefs;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000956 else if (section_name == g_sect_name_eh_frame)
957 sect_type = eSectionTypeEHFrame;
958 else if (section_name == g_sect_name_cfstring)
959 sect_type = eSectionTypeDataObjCCFStrings;
Chris Lattner24943d22010-06-08 16:52:24 +0000960 else if (section_name == g_sect_name_objc_data ||
961 section_name == g_sect_name_objc_classrefs ||
962 section_name == g_sect_name_objc_superrefs ||
963 section_name == g_sect_name_objc_const ||
964 section_name == g_sect_name_objc_classlist)
965 {
966 sect_type = eSectionTypeDataPointers;
967 }
Chris Lattner24943d22010-06-08 16:52:24 +0000968
969 if (sect_type == eSectionTypeOther)
970 {
971 switch (mach_sect_type)
972 {
973 // TODO: categorize sections by other flags for regular sections
Greg Clayton3fed8b92010-10-08 00:21:05 +0000974 case SectionTypeRegular:
975 if (segment_sp->GetName() == g_sect_name_TEXT)
976 sect_type = eSectionTypeCode;
977 else if (segment_sp->GetName() == g_sect_name_DATA)
978 sect_type = eSectionTypeData;
979 else
980 sect_type = eSectionTypeOther;
981 break;
Greg Clayton1674b122010-07-21 22:12:05 +0000982 case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
983 case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
984 case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
985 case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
986 case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
987 case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
988 case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
989 case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
990 case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
991 case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
992 case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
993 case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
994 case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
995 case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
996 case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
997 case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
Chris Lattner24943d22010-06-08 16:52:24 +0000998 default: break;
999 }
1000 }
1001
Greg Clayton3508c382012-02-24 01:59:29 +00001002 SectionSP section_sp(new Section (segment_sp,
1003 module_sp,
1004 ++sectID,
1005 section_name,
1006 sect_type,
1007 sect64.addr - segment_sp->GetFileAddress(),
1008 sect64.size,
1009 sect64.offset,
1010 sect64.offset == 0 ? 0 : sect64.size,
1011 sect64.flags));
Greg Clayton68ca8232011-01-25 02:58:48 +00001012 // Set the section to be encrypted to match the segment
1013 section_sp->SetIsEncrypted (segment_is_encrypted);
1014
Chris Lattner24943d22010-06-08 16:52:24 +00001015 segment_sp->GetChildren().AddSection(section_sp);
1016
1017 if (segment_sp->IsFake())
1018 {
1019 segment_sp.reset();
1020 segment_name.Clear();
1021 }
1022 }
Greg Clayton0fa51242011-07-19 03:57:15 +00001023 if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
Chris Lattner24943d22010-06-08 16:52:24 +00001024 {
1025 if (first_segment_sectID <= sectID)
1026 {
1027 lldb::user_id_t sect_uid;
1028 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
1029 {
1030 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1031 SectionSP next_section_sp;
1032 if (sect_uid + 1 <= sectID)
1033 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1034
1035 if (curr_section_sp.get())
1036 {
1037 if (curr_section_sp->GetByteSize() == 0)
1038 {
1039 if (next_section_sp.get() != NULL)
1040 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1041 else
1042 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1043 }
1044 }
1045 }
1046 }
1047 }
1048 }
1049 }
1050 }
Greg Clayton1674b122010-07-21 22:12:05 +00001051 else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
Chris Lattner24943d22010-06-08 16:52:24 +00001052 {
1053 m_dysymtab.cmd = load_cmd.cmd;
1054 m_dysymtab.cmdsize = load_cmd.cmdsize;
1055 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1056 }
1057
1058 offset = load_cmd_offset + load_cmd.cmdsize;
1059 }
1060// if (dump_sections)
1061// {
1062// StreamFile s(stdout);
1063// m_sections_ap->Dump(&s, true);
1064// }
1065 return sectID; // Return the number of sections we registered with the module
1066}
1067
1068class MachSymtabSectionInfo
1069{
1070public:
1071
1072 MachSymtabSectionInfo (SectionList *section_list) :
1073 m_section_list (section_list),
1074 m_section_infos()
1075 {
1076 // Get the number of sections down to a depth of 1 to include
1077 // all segments and their sections, but no other sections that
1078 // may be added for debug map or
1079 m_section_infos.resize(section_list->GetNumSections(1));
1080 }
1081
1082
Greg Clayton3508c382012-02-24 01:59:29 +00001083 SectionSP
Chris Lattner24943d22010-06-08 16:52:24 +00001084 GetSection (uint8_t n_sect, addr_t file_addr)
1085 {
1086 if (n_sect == 0)
Greg Clayton3508c382012-02-24 01:59:29 +00001087 return SectionSP();
Chris Lattner24943d22010-06-08 16:52:24 +00001088 if (n_sect < m_section_infos.size())
1089 {
Greg Clayton3508c382012-02-24 01:59:29 +00001090 if (!m_section_infos[n_sect].section_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001091 {
Greg Clayton3508c382012-02-24 01:59:29 +00001092 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1093 m_section_infos[n_sect].section_sp = section_sp;
1094 if (section_sp != NULL)
Greg Clayton5638d2c2011-07-10 17:32:33 +00001095 {
Greg Clayton3508c382012-02-24 01:59:29 +00001096 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1097 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Clayton5638d2c2011-07-10 17:32:33 +00001098 }
1099 else
1100 {
Greg Claytondf6dc882012-01-05 03:57:59 +00001101 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Clayton5638d2c2011-07-10 17:32:33 +00001102 }
Chris Lattner24943d22010-06-08 16:52:24 +00001103 }
1104 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton811b9c52011-08-26 20:01:35 +00001105 {
1106 // Symbol is in section.
Greg Clayton3508c382012-02-24 01:59:29 +00001107 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001108 }
1109 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1110 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1111 {
1112 // Symbol is in section with zero size, but has the same start
1113 // address as the section. This can happen with linker symbols
1114 // (symbols that start with the letter 'l' or 'L'.
Greg Clayton3508c382012-02-24 01:59:29 +00001115 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001116 }
Chris Lattner24943d22010-06-08 16:52:24 +00001117 }
Greg Clayton3508c382012-02-24 01:59:29 +00001118 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner24943d22010-06-08 16:52:24 +00001119 }
1120
1121protected:
1122 struct SectionInfo
1123 {
1124 SectionInfo () :
1125 vm_range(),
Greg Clayton3508c382012-02-24 01:59:29 +00001126 section_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +00001127 {
1128 }
1129
1130 VMRange vm_range;
Greg Clayton3508c382012-02-24 01:59:29 +00001131 SectionSP section_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001132 };
1133 SectionList *m_section_list;
1134 std::vector<SectionInfo> m_section_infos;
1135};
1136
1137
1138
1139size_t
1140ObjectFileMachO::ParseSymtab (bool minimize)
1141{
1142 Timer scoped_timer(__PRETTY_FUNCTION__,
1143 "ObjectFileMachO::ParseSymtab () module = %s",
1144 m_file.GetFilename().AsCString(""));
1145 struct symtab_command symtab_load_command;
1146 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1147 uint32_t i;
Greg Clayton0fea0512011-12-30 00:32:24 +00001148
1149 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
1150
Chris Lattner24943d22010-06-08 16:52:24 +00001151 for (i=0; i<m_header.ncmds; ++i)
1152 {
1153 const uint32_t cmd_offset = offset;
1154 // Read in the load command and load command size
1155 if (m_data.GetU32(&offset, &symtab_load_command, 2) == NULL)
1156 break;
1157 // Watch for the symbol table load command
Greg Clayton1674b122010-07-21 22:12:05 +00001158 if (symtab_load_command.cmd == LoadCommandSymtab)
Chris Lattner24943d22010-06-08 16:52:24 +00001159 {
1160 // Read in the rest of the symtab load command
Jason Molendaccfba722010-07-06 22:38:03 +00001161 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4)) // fill in symoff, nsyms, stroff, strsize fields
Chris Lattner24943d22010-06-08 16:52:24 +00001162 {
Greg Clayton0fea0512011-12-30 00:32:24 +00001163 if (symtab_load_command.symoff == 0)
1164 {
1165 if (log)
1166 GetModule()->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
1167 return 0;
1168 }
1169
1170 if (symtab_load_command.stroff == 0)
1171 {
1172 if (log)
1173 GetModule()->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
1174 return 0;
1175 }
1176
1177 if (symtab_load_command.nsyms == 0)
1178 {
1179 if (log)
1180 GetModule()->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
1181 return 0;
1182 }
1183
1184 if (symtab_load_command.strsize == 0)
1185 {
1186 if (log)
1187 GetModule()->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
1188 return 0;
1189 }
1190
Chris Lattner24943d22010-06-08 16:52:24 +00001191 Symtab *symtab = m_symtab_ap.get();
1192 SectionList *section_list = GetSectionList();
Greg Clayton0fea0512011-12-30 00:32:24 +00001193 if (section_list == NULL)
1194 return 0;
Chris Lattner24943d22010-06-08 16:52:24 +00001195
Greg Claytonb5a8f142012-02-05 02:38:54 +00001196 ProcessSP process_sp (m_process_wp.lock());
1197
Greg Clayton0fea0512011-12-30 00:32:24 +00001198 const size_t addr_byte_size = m_data.GetAddressByteSize();
Greg Clayton0fea0512011-12-30 00:32:24 +00001199 bool bit_width_32 = addr_byte_size == 4;
1200 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
1201
Greg Claytonb5a8f142012-02-05 02:38:54 +00001202 DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1203 DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1204
1205 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
1206 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
1207 if (process_sp)
1208 {
1209 Target &target = process_sp->GetTarget();
1210 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
1211 // Reading mach file from memory in a process or core file...
1212
1213 if (linkedit_section_sp)
1214 {
1215 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
1216 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
1217 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
1218 const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
1219 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
Greg Clayton9ce95382012-02-13 23:10:39 +00001220 if (nlist_data_sp)
1221 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
Greg Claytonb5a8f142012-02-05 02:38:54 +00001222 DataBufferSP strtab_data_sp (ReadMemory (process_sp, stroff_addr, strtab_data_byte_size));
Greg Clayton9ce95382012-02-13 23:10:39 +00001223 if (strtab_data_sp)
1224 strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
Greg Claytonb5a8f142012-02-05 02:38:54 +00001225 }
1226 }
1227 else
1228 {
1229 nlist_data.SetData (m_data,
1230 symtab_load_command.symoff,
1231 nlist_data_byte_size);
1232 strtab_data.SetData (m_data,
1233 symtab_load_command.stroff,
1234 strtab_data_byte_size);
1235
1236 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001237
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001238 if (nlist_data.GetByteSize() == 0)
Greg Clayton0fea0512011-12-30 00:32:24 +00001239 {
1240 if (log)
1241 GetModule()->LogMessage(log.get(), "failed to read nlist data");
1242 return 0;
1243 }
1244
Greg Clayton0fea0512011-12-30 00:32:24 +00001245
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001246 if (strtab_data.GetByteSize() == 0)
Greg Clayton0fea0512011-12-30 00:32:24 +00001247 {
1248 if (log)
1249 GetModule()->LogMessage(log.get(), "failed to read strtab data");
1250 return 0;
1251 }
Chris Lattner24943d22010-06-08 16:52:24 +00001252
Greg Claytonb5a8f142012-02-05 02:38:54 +00001253 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
1254 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
1255 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
1256 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
Chris Lattner24943d22010-06-08 16:52:24 +00001257 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
1258 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
1259 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
1260 SectionSP eh_frame_section_sp;
1261 if (text_section_sp.get())
1262 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
1263 else
1264 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
1265
Greg Clayton1674b122010-07-21 22:12:05 +00001266 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
Chris Lattner24943d22010-06-08 16:52:24 +00001267
Greg Clayton0fea0512011-12-30 00:32:24 +00001268 uint32_t nlist_data_offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +00001269
Greg Clayton7c36fa02010-09-11 03:13:28 +00001270 uint32_t N_SO_index = UINT32_MAX;
Chris Lattner24943d22010-06-08 16:52:24 +00001271
1272 MachSymtabSectionInfo section_info (section_list);
1273 std::vector<uint32_t> N_FUN_indexes;
1274 std::vector<uint32_t> N_NSYM_indexes;
1275 std::vector<uint32_t> N_INCL_indexes;
1276 std::vector<uint32_t> N_BRAC_indexes;
1277 std::vector<uint32_t> N_COMM_indexes;
Greg Clayton576a68b2010-09-08 16:38:06 +00001278 typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
Greg Clayton637029b2010-09-12 05:25:16 +00001279 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
Greg Clayton576a68b2010-09-08 16:38:06 +00001280 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
1281 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001282 // Any symbols that get merged into another will get an entry
1283 // in this map so we know
Greg Clayton637029b2010-09-12 05:25:16 +00001284 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
Chris Lattner24943d22010-06-08 16:52:24 +00001285 uint32_t nlist_idx = 0;
1286 Symbol *symbol_ptr = NULL;
1287
1288 uint32_t sym_idx = 0;
1289 Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1290 uint32_t num_syms = symtab->GetNumSymbols();
1291
1292 //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1293 for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
1294 {
1295 struct nlist_64 nlist;
Greg Clayton0fea0512011-12-30 00:32:24 +00001296 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
1297 break;
1298
1299 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
1300 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
1301 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
1302 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
1303 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
Chris Lattner24943d22010-06-08 16:52:24 +00001304
1305 SymbolType type = eSymbolTypeInvalid;
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001306 const char *symbol_name = strtab_data.PeekCStr(nlist.n_strx);
1307 if (symbol_name == NULL)
Greg Claytona9c4f312011-10-31 20:50:40 +00001308 {
Greg Clayton3508c382012-02-24 01:59:29 +00001309 ModuleSP module_sp (GetModule());
Greg Claytona9c4f312011-10-31 20:50:40 +00001310 // No symbol should be NULL, even the symbols with no
1311 // string values should have an offset zero which points
1312 // to an empty C-string
Greg Clayton3508c382012-02-24 01:59:29 +00001313 if (module_sp)
1314 {
1315 Host::SystemLog (Host::eSystemLogError,
1316 "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
1317 nlist_idx,
1318 nlist.n_strx,
1319 module_sp->GetFileSpec().GetDirectory().GetCString(),
1320 module_sp->GetFileSpec().GetFilename().GetCString());
1321 }
Greg Claytona9c4f312011-10-31 20:50:40 +00001322 continue;
1323 }
Greg Clayton3f69eac2011-12-03 02:30:59 +00001324 const char *symbol_name_non_abi_mangled = NULL;
Greg Claytona9c4f312011-10-31 20:50:40 +00001325
Chris Lattner24943d22010-06-08 16:52:24 +00001326 if (symbol_name[0] == '\0')
1327 symbol_name = NULL;
Greg Clayton3508c382012-02-24 01:59:29 +00001328 SectionSP symbol_section;
Chris Lattner24943d22010-06-08 16:52:24 +00001329 bool add_nlist = true;
Greg Clayton1674b122010-07-21 22:12:05 +00001330 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
Chris Lattner24943d22010-06-08 16:52:24 +00001331
1332 assert (sym_idx < num_syms);
1333
1334 sym[sym_idx].SetDebug (is_debug);
1335
1336 if (is_debug)
1337 {
1338 switch (nlist.n_type)
1339 {
Greg Clayton1674b122010-07-21 22:12:05 +00001340 case StabGlobalSymbol:
1341 // N_GSYM -- global symbol: name,,NO_SECT,type,0
Chris Lattner24943d22010-06-08 16:52:24 +00001342 // Sometimes the N_GSYM value contains the address.
Jim Ingham115213c2011-12-16 00:05:58 +00001343
1344 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
1345 // have the same address, but we want to ensure that we always find only the real symbol,
1346 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
1347 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
1348 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
1349 // same address.
1350
1351 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
1352 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
1353 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
1354 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
1355 add_nlist = false;
1356 else
1357 {
1358 sym[sym_idx].SetExternal(true);
1359 if (nlist.n_value != 0)
1360 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1361 type = eSymbolTypeData;
1362 }
Chris Lattner24943d22010-06-08 16:52:24 +00001363 break;
1364
Greg Clayton1674b122010-07-21 22:12:05 +00001365 case StabFunctionName:
1366 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
Greg Clayton7c36fa02010-09-11 03:13:28 +00001367 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00001368 break;
1369
Greg Clayton1674b122010-07-21 22:12:05 +00001370 case StabFunction:
1371 // N_FUN -- procedure: name,,n_sect,linenumber,address
Chris Lattner24943d22010-06-08 16:52:24 +00001372 if (symbol_name)
1373 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001374 type = eSymbolTypeCode;
Chris Lattner24943d22010-06-08 16:52:24 +00001375 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Greg Clayton576a68b2010-09-08 16:38:06 +00001376
1377 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
Chris Lattner24943d22010-06-08 16:52:24 +00001378 // We use the current number of symbols in the symbol table in lieu of
1379 // using nlist_idx in case we ever start trimming entries out
1380 N_FUN_indexes.push_back(sym_idx);
1381 }
1382 else
1383 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001384 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00001385
1386 if ( !N_FUN_indexes.empty() )
1387 {
1388 // Copy the size of the function into the original STAB entry so we don't have
1389 // to hunt for it later
1390 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
1391 N_FUN_indexes.pop_back();
Jason Molendaccfba722010-07-06 22:38:03 +00001392 // We don't really need the end function STAB as it contains the size which
Chris Lattner24943d22010-06-08 16:52:24 +00001393 // we already placed with the original symbol, so don't add it if we want a
1394 // minimal symbol table
1395 if (minimize)
1396 add_nlist = false;
1397 }
1398 }
1399 break;
1400
Greg Clayton1674b122010-07-21 22:12:05 +00001401 case StabStaticSymbol:
1402 // N_STSYM -- static symbol: name,,n_sect,type,address
Greg Clayton576a68b2010-09-08 16:38:06 +00001403 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
Chris Lattner24943d22010-06-08 16:52:24 +00001404 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Greg Clayton7c36fa02010-09-11 03:13:28 +00001405 type = eSymbolTypeData;
Chris Lattner24943d22010-06-08 16:52:24 +00001406 break;
1407
Greg Clayton1674b122010-07-21 22:12:05 +00001408 case StabLocalCommon:
1409 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
Chris Lattner24943d22010-06-08 16:52:24 +00001410 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1411 type = eSymbolTypeCommonBlock;
1412 break;
1413
Greg Clayton1674b122010-07-21 22:12:05 +00001414 case StabBeginSymbol:
1415 // N_BNSYM
Chris Lattner24943d22010-06-08 16:52:24 +00001416 // We use the current number of symbols in the symbol table in lieu of
1417 // using nlist_idx in case we ever start trimming entries out
1418 if (minimize)
1419 {
1420 // Skip these if we want minimal symbol tables
1421 add_nlist = false;
1422 }
1423 else
1424 {
1425 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1426 N_NSYM_indexes.push_back(sym_idx);
1427 type = eSymbolTypeScopeBegin;
1428 }
1429 break;
1430
Greg Clayton1674b122010-07-21 22:12:05 +00001431 case StabEndSymbol:
1432 // N_ENSYM
Chris Lattner24943d22010-06-08 16:52:24 +00001433 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
1434 // so that we can always skip the entire symbol if we need to navigate
1435 // more quickly at the source level when parsing STABS
1436 if (minimize)
1437 {
1438 // Skip these if we want minimal symbol tables
1439 add_nlist = false;
1440 }
1441 else
1442 {
1443 if ( !N_NSYM_indexes.empty() )
1444 {
1445 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
1446 symbol_ptr->SetByteSize(sym_idx + 1);
1447 symbol_ptr->SetSizeIsSibling(true);
1448 N_NSYM_indexes.pop_back();
1449 }
1450 type = eSymbolTypeScopeEnd;
1451 }
1452 break;
1453
1454
Greg Clayton1674b122010-07-21 22:12:05 +00001455 case StabSourceFileOptions:
1456 // N_OPT - emitted with gcc2_compiled and in gcc source
Chris Lattner24943d22010-06-08 16:52:24 +00001457 type = eSymbolTypeCompiler;
1458 break;
1459
Greg Clayton1674b122010-07-21 22:12:05 +00001460 case StabRegisterSymbol:
1461 // N_RSYM - register sym: name,,NO_SECT,type,register
Chris Lattner24943d22010-06-08 16:52:24 +00001462 type = eSymbolTypeVariable;
1463 break;
1464
Greg Clayton1674b122010-07-21 22:12:05 +00001465 case StabSourceLine:
1466 // N_SLINE - src line: 0,,n_sect,linenumber,address
Chris Lattner24943d22010-06-08 16:52:24 +00001467 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1468 type = eSymbolTypeLineEntry;
1469 break;
1470
Greg Clayton1674b122010-07-21 22:12:05 +00001471 case StabStructureType:
1472 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
Chris Lattner24943d22010-06-08 16:52:24 +00001473 type = eSymbolTypeVariableType;
1474 break;
1475
Greg Clayton1674b122010-07-21 22:12:05 +00001476 case StabSourceFileName:
1477 // N_SO - source file name
Chris Lattner24943d22010-06-08 16:52:24 +00001478 type = eSymbolTypeSourceFile;
1479 if (symbol_name == NULL)
1480 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001481 if (minimize)
1482 add_nlist = false;
1483 if (N_SO_index != UINT32_MAX)
Chris Lattner24943d22010-06-08 16:52:24 +00001484 {
1485 // Set the size of the N_SO to the terminating index of this N_SO
1486 // so that we can always skip the entire N_SO if we need to navigate
1487 // more quickly at the source level when parsing STABS
1488 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
Greg Clayton7c36fa02010-09-11 03:13:28 +00001489 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
Chris Lattner24943d22010-06-08 16:52:24 +00001490 symbol_ptr->SetSizeIsSibling(true);
1491 }
1492 N_NSYM_indexes.clear();
1493 N_INCL_indexes.clear();
1494 N_BRAC_indexes.clear();
1495 N_COMM_indexes.clear();
1496 N_FUN_indexes.clear();
Greg Clayton7c36fa02010-09-11 03:13:28 +00001497 N_SO_index = UINT32_MAX;
Chris Lattner24943d22010-06-08 16:52:24 +00001498 }
Greg Clayton7c36fa02010-09-11 03:13:28 +00001499 else
Chris Lattner24943d22010-06-08 16:52:24 +00001500 {
1501 // We use the current number of symbols in the symbol table in lieu of
1502 // using nlist_idx in case we ever start trimming entries out
Greg Clayton7c36fa02010-09-11 03:13:28 +00001503 if (symbol_name[0] == '/')
1504 N_SO_index = sym_idx;
Greg Claytondab471f2011-06-19 04:26:01 +00001505 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Greg Clayton7c36fa02010-09-11 03:13:28 +00001506 {
1507 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
1508 if (so_path && so_path[0])
1509 {
1510 std::string full_so_path (so_path);
1511 if (*full_so_path.rbegin() != '/')
1512 full_so_path += '/';
1513 full_so_path += symbol_name;
1514 sym[sym_idx - 1].GetMangled().SetValue(full_so_path.c_str(), false);
1515 add_nlist = false;
Greg Clayton637029b2010-09-12 05:25:16 +00001516 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001517 }
1518 }
Chris Lattner24943d22010-06-08 16:52:24 +00001519 }
Greg Clayton7c36fa02010-09-11 03:13:28 +00001520
Chris Lattner24943d22010-06-08 16:52:24 +00001521 break;
1522
Greg Clayton1674b122010-07-21 22:12:05 +00001523 case StabObjectFileName:
1524 // N_OSO - object file name: name,,0,0,st_mtime
Chris Lattner24943d22010-06-08 16:52:24 +00001525 type = eSymbolTypeObjectFile;
1526 break;
1527
Greg Clayton1674b122010-07-21 22:12:05 +00001528 case StabLocalSymbol:
1529 // N_LSYM - local sym: name,,NO_SECT,type,offset
Chris Lattner24943d22010-06-08 16:52:24 +00001530 type = eSymbolTypeLocal;
1531 break;
1532
1533 //----------------------------------------------------------------------
1534 // INCL scopes
1535 //----------------------------------------------------------------------
Greg Clayton1674b122010-07-21 22:12:05 +00001536 case StabBeginIncludeFileName:
1537 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
Chris Lattner24943d22010-06-08 16:52:24 +00001538 // We use the current number of symbols in the symbol table in lieu of
1539 // using nlist_idx in case we ever start trimming entries out
1540 N_INCL_indexes.push_back(sym_idx);
1541 type = eSymbolTypeScopeBegin;
1542 break;
Chris Lattner24943d22010-06-08 16:52:24 +00001543
Greg Clayton1674b122010-07-21 22:12:05 +00001544 case StabEndIncludeFile:
1545 // N_EINCL - include file end: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001546 // Set the size of the N_BINCL to the terminating index of this N_EINCL
1547 // so that we can always skip the entire symbol if we need to navigate
1548 // more quickly at the source level when parsing STABS
1549 if ( !N_INCL_indexes.empty() )
1550 {
1551 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
1552 symbol_ptr->SetByteSize(sym_idx + 1);
1553 symbol_ptr->SetSizeIsSibling(true);
1554 N_INCL_indexes.pop_back();
1555 }
1556 type = eSymbolTypeScopeEnd;
1557 break;
1558
Greg Clayton1674b122010-07-21 22:12:05 +00001559 case StabIncludeFileName:
1560 // N_SOL - #included file name: name,,n_sect,0,address
Chris Lattner24943d22010-06-08 16:52:24 +00001561 type = eSymbolTypeHeaderFile;
Greg Clayton0ad086f2010-09-07 17:36:17 +00001562
1563 // We currently don't use the header files on darwin
1564 if (minimize)
1565 add_nlist = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001566 break;
1567
Greg Clayton1674b122010-07-21 22:12:05 +00001568 case StabCompilerParameters:
1569 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001570 type = eSymbolTypeCompiler;
1571 break;
1572
Greg Clayton1674b122010-07-21 22:12:05 +00001573 case StabCompilerVersion:
1574 // N_VERSION - compiler version: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001575 type = eSymbolTypeCompiler;
1576 break;
1577
Greg Clayton1674b122010-07-21 22:12:05 +00001578 case StabCompilerOptLevel:
1579 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001580 type = eSymbolTypeCompiler;
1581 break;
1582
Greg Clayton1674b122010-07-21 22:12:05 +00001583 case StabParameter:
1584 // N_PSYM - parameter: name,,NO_SECT,type,offset
Chris Lattner24943d22010-06-08 16:52:24 +00001585 type = eSymbolTypeVariable;
1586 break;
1587
Greg Clayton1674b122010-07-21 22:12:05 +00001588 case StabAlternateEntry:
1589 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
Chris Lattner24943d22010-06-08 16:52:24 +00001590 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1591 type = eSymbolTypeLineEntry;
1592 break;
1593
1594 //----------------------------------------------------------------------
1595 // Left and Right Braces
1596 //----------------------------------------------------------------------
Greg Clayton1674b122010-07-21 22:12:05 +00001597 case StabLeftBracket:
1598 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
Chris Lattner24943d22010-06-08 16:52:24 +00001599 // We use the current number of symbols in the symbol table in lieu of
1600 // using nlist_idx in case we ever start trimming entries out
1601 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1602 N_BRAC_indexes.push_back(sym_idx);
1603 type = eSymbolTypeScopeBegin;
1604 break;
1605
Greg Clayton1674b122010-07-21 22:12:05 +00001606 case StabRightBracket:
1607 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
Chris Lattner24943d22010-06-08 16:52:24 +00001608 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
1609 // so that we can always skip the entire symbol if we need to navigate
1610 // more quickly at the source level when parsing STABS
1611 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1612 if ( !N_BRAC_indexes.empty() )
1613 {
1614 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
1615 symbol_ptr->SetByteSize(sym_idx + 1);
1616 symbol_ptr->SetSizeIsSibling(true);
1617 N_BRAC_indexes.pop_back();
1618 }
1619 type = eSymbolTypeScopeEnd;
1620 break;
1621
Greg Clayton1674b122010-07-21 22:12:05 +00001622 case StabDeletedIncludeFile:
1623 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
Chris Lattner24943d22010-06-08 16:52:24 +00001624 type = eSymbolTypeHeaderFile;
1625 break;
1626
1627 //----------------------------------------------------------------------
1628 // COMM scopes
1629 //----------------------------------------------------------------------
Greg Clayton1674b122010-07-21 22:12:05 +00001630 case StabBeginCommon:
1631 // N_BCOMM - begin common: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001632 // We use the current number of symbols in the symbol table in lieu of
1633 // using nlist_idx in case we ever start trimming entries out
1634 type = eSymbolTypeScopeBegin;
1635 N_COMM_indexes.push_back(sym_idx);
1636 break;
1637
Greg Clayton1674b122010-07-21 22:12:05 +00001638 case StabEndCommonLocal:
1639 // N_ECOML - end common (local name): 0,,n_sect,0,address
Chris Lattner24943d22010-06-08 16:52:24 +00001640 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1641 // Fall through
1642
Greg Clayton1674b122010-07-21 22:12:05 +00001643 case StabEndCommon:
1644 // N_ECOMM - end common: name,,n_sect,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001645 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
1646 // so that we can always skip the entire symbol if we need to navigate
1647 // more quickly at the source level when parsing STABS
1648 if ( !N_COMM_indexes.empty() )
1649 {
1650 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
1651 symbol_ptr->SetByteSize(sym_idx + 1);
1652 symbol_ptr->SetSizeIsSibling(true);
1653 N_COMM_indexes.pop_back();
1654 }
1655 type = eSymbolTypeScopeEnd;
1656 break;
1657
Greg Clayton1674b122010-07-21 22:12:05 +00001658 case StabLength:
1659 // N_LENG - second stab entry with length information
Chris Lattner24943d22010-06-08 16:52:24 +00001660 type = eSymbolTypeAdditional;
1661 break;
1662
1663 default: break;
1664 }
1665 }
1666 else
1667 {
Greg Clayton1674b122010-07-21 22:12:05 +00001668 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
1669 uint8_t n_type = NlistMaskType & nlist.n_type;
1670 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
Chris Lattner24943d22010-06-08 16:52:24 +00001671
Greg Clayton3f69eac2011-12-03 02:30:59 +00001672 switch (n_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001673 {
Greg Clayton3f69eac2011-12-03 02:30:59 +00001674 case NListTypeIndirect: // N_INDR - Fall through
1675 case NListTypePreboundUndefined:// N_PBUD - Fall through
1676 case NListTypeUndefined: // N_UNDF
1677 type = eSymbolTypeUndefined;
1678 break;
1679
1680 case NListTypeAbsolute: // N_ABS
1681 type = eSymbolTypeAbsolute;
1682 break;
1683
1684 case NListTypeSection: // N_SECT
1685 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1686
1687 if (symbol_section == NULL)
1688 {
1689 // TODO: warn about this?
1690 add_nlist = false;
1691 break;
1692 }
1693
1694 if (TEXT_eh_frame_sectID == nlist.n_sect)
1695 {
1696 type = eSymbolTypeException;
1697 }
1698 else
1699 {
1700 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
1701
1702 switch (section_type)
1703 {
1704 case SectionTypeRegular: break; // regular section
1705 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
1706 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
1707 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
1708 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
1709 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
1710 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
1711 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
1712 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1713 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
1714 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
1715 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
1716 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
1717 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
1718 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
1719 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
1720 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
1721 default: break;
1722 }
1723
1724 if (type == eSymbolTypeInvalid)
1725 {
1726 const char *symbol_sect_name = symbol_section->GetName().AsCString();
1727 if (symbol_section->IsDescendant (text_section_sp.get()))
1728 {
1729 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
1730 SectionAttrUserSelfModifyingCode |
1731 SectionAttrSytemSomeInstructions))
1732 type = eSymbolTypeData;
1733 else
1734 type = eSymbolTypeCode;
1735 }
1736 else
1737 if (symbol_section->IsDescendant(data_section_sp.get()))
1738 {
1739 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
1740 {
1741 type = eSymbolTypeRuntime;
1742
1743 if (symbol_name &&
1744 symbol_name[0] == '_' &&
1745 symbol_name[1] == 'O' &&
1746 symbol_name[2] == 'B')
1747 {
1748 llvm::StringRef symbol_name_ref(symbol_name);
1749 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
1750 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
1751 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
1752 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
1753 {
Sean Callanand0b7cfa2011-12-03 04:38:43 +00001754 symbol_name_non_abi_mangled = symbol_name + 1;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001755 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
1756 type = eSymbolTypeObjCClass;
1757 }
1758 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
1759 {
Sean Callanand0b7cfa2011-12-03 04:38:43 +00001760 symbol_name_non_abi_mangled = symbol_name + 1;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001761 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
1762 type = eSymbolTypeObjCMetaClass;
1763 }
1764 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
1765 {
Sean Callanand0b7cfa2011-12-03 04:38:43 +00001766 symbol_name_non_abi_mangled = symbol_name + 1;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001767 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
1768 type = eSymbolTypeObjCIVar;
1769 }
1770 }
1771 }
1772 else
1773 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
1774 {
1775 type = eSymbolTypeException;
1776 }
1777 else
1778 {
1779 type = eSymbolTypeData;
1780 }
1781 }
1782 else
1783 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
1784 {
1785 type = eSymbolTypeTrampoline;
1786 }
1787 else
1788 if (symbol_section->IsDescendant(objc_section_sp.get()))
1789 {
1790 type = eSymbolTypeRuntime;
1791 if (symbol_name && symbol_name[0] == '.')
1792 {
1793 llvm::StringRef symbol_name_ref(symbol_name);
1794 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
1795 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
1796 {
1797 symbol_name_non_abi_mangled = symbol_name;
1798 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
1799 type = eSymbolTypeObjCClass;
1800 }
1801 }
1802 }
1803 }
1804 }
1805 break;
1806 }
1807 }
1808
1809 if (add_nlist)
1810 {
1811 uint64_t symbol_value = nlist.n_value;
1812 bool symbol_name_is_mangled = false;
1813
1814 if (symbol_name_non_abi_mangled)
1815 {
1816 sym[sym_idx].GetMangled().SetMangledName (symbol_name_non_abi_mangled);
1817 sym[sym_idx].GetMangled().SetDemangledName (symbol_name);
Chris Lattner24943d22010-06-08 16:52:24 +00001818 }
1819 else
1820 {
Greg Clayton3f69eac2011-12-03 02:30:59 +00001821 if (symbol_name && symbol_name[0] == '_')
Chris Lattner24943d22010-06-08 16:52:24 +00001822 {
Greg Clayton3f69eac2011-12-03 02:30:59 +00001823 symbol_name_is_mangled = symbol_name[1] == '_';
1824 symbol_name++; // Skip the leading underscore
1825 }
Chris Lattner24943d22010-06-08 16:52:24 +00001826
Greg Clayton038f1c02011-12-03 03:02:17 +00001827 if (symbol_name)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001828 {
1829 sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
1830 }
Chris Lattner24943d22010-06-08 16:52:24 +00001831 }
Greg Clayton576a68b2010-09-08 16:38:06 +00001832
Greg Clayton7c36fa02010-09-11 03:13:28 +00001833 if (is_debug == false)
Greg Clayton576a68b2010-09-08 16:38:06 +00001834 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001835 if (type == eSymbolTypeCode)
Greg Clayton576a68b2010-09-08 16:38:06 +00001836 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001837 // See if we can find a N_FUN entry for any code symbols.
1838 // If we do find a match, and the name matches, then we
1839 // can merge the two into just the function symbol to avoid
1840 // duplicate entries in the symbol table
1841 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
1842 if (pos != N_FUN_addr_to_sym_idx.end())
Greg Clayton576a68b2010-09-08 16:38:06 +00001843 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001844 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1845 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1846 {
Greg Clayton637029b2010-09-12 05:25:16 +00001847 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001848 // We just need the flags from the linker symbol, so put these flags
1849 // into the N_FUN flags to avoid duplicate symbols in the symbol table
1850 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1851 sym[sym_idx].Clear();
1852 continue;
1853 }
Greg Clayton576a68b2010-09-08 16:38:06 +00001854 }
1855 }
Greg Clayton7c36fa02010-09-11 03:13:28 +00001856 else if (type == eSymbolTypeData)
Greg Clayton576a68b2010-09-08 16:38:06 +00001857 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001858 // See if we can find a N_STSYM entry for any data symbols.
1859 // If we do find a match, and the name matches, then we
1860 // can merge the two into just the Static symbol to avoid
1861 // duplicate entries in the symbol table
1862 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
1863 if (pos != N_STSYM_addr_to_sym_idx.end())
Greg Clayton576a68b2010-09-08 16:38:06 +00001864 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001865 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1866 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1867 {
Greg Clayton637029b2010-09-12 05:25:16 +00001868 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001869 // We just need the flags from the linker symbol, so put these flags
1870 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
1871 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1872 sym[sym_idx].Clear();
1873 continue;
1874 }
Greg Clayton576a68b2010-09-08 16:38:06 +00001875 }
1876 }
1877 }
Chris Lattner24943d22010-06-08 16:52:24 +00001878 if (symbol_section != NULL)
1879 symbol_value -= symbol_section->GetFileAddress();
1880
1881 sym[sym_idx].SetID (nlist_idx);
1882 sym[sym_idx].SetType (type);
Greg Clayton0c31d3d2012-03-07 21:03:09 +00001883 sym[sym_idx].GetAddress().SetSection (symbol_section);
1884 sym[sym_idx].GetAddress().SetOffset (symbol_value);
Chris Lattner24943d22010-06-08 16:52:24 +00001885 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1886
1887 ++sym_idx;
1888 }
1889 else
1890 {
1891 sym[sym_idx].Clear();
1892 }
1893
1894 }
1895
Chris Lattner24943d22010-06-08 16:52:24 +00001896 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
1897 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
1898 // such entries by figuring out what the address for the global is by looking up this non-STAB
1899 // entry and copying the value into the debug symbol's value to save us the hassle in the
1900 // debug symbol parser.
1901
1902 Symbol *global_symbol = NULL;
1903 for (nlist_idx = 0;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001904 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001905 nlist_idx++)
1906 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +00001907 if (global_symbol->GetAddress().GetFileAddress() == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001908 {
1909 std::vector<uint32_t> indexes;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001910 if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001911 {
1912 std::vector<uint32_t>::const_iterator pos;
1913 std::vector<uint32_t>::const_iterator end = indexes.end();
1914 for (pos = indexes.begin(); pos != end; ++pos)
1915 {
1916 symbol_ptr = symtab->SymbolAtIndex(*pos);
1917 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
1918 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +00001919 global_symbol->GetAddress() = symbol_ptr->GetAddress();
Chris Lattner24943d22010-06-08 16:52:24 +00001920 break;
1921 }
1922 }
1923 }
1924 }
1925 }
Greg Clayton637029b2010-09-12 05:25:16 +00001926
1927 // Trim our symbols down to just what we ended up with after
1928 // removing any symbols.
1929 if (sym_idx < num_syms)
1930 {
1931 num_syms = sym_idx;
1932 sym = symtab->Resize (num_syms);
1933 }
1934
Chris Lattner24943d22010-06-08 16:52:24 +00001935 // Now synthesize indirect symbols
1936 if (m_dysymtab.nindirectsyms != 0)
1937 {
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001938 DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
Chris Lattner24943d22010-06-08 16:52:24 +00001939
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001940 if (indirect_symbol_index_data.GetByteSize())
Chris Lattner24943d22010-06-08 16:52:24 +00001941 {
Greg Clayton637029b2010-09-12 05:25:16 +00001942 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
Chris Lattner24943d22010-06-08 16:52:24 +00001943
1944 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
1945 {
Greg Clayton1674b122010-07-21 22:12:05 +00001946 if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
Chris Lattner24943d22010-06-08 16:52:24 +00001947 {
1948 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
1949 if (symbol_stub_byte_size == 0)
1950 continue;
1951
1952 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
1953
1954 if (num_symbol_stubs == 0)
1955 continue;
1956
1957 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
Greg Clayton637029b2010-09-12 05:25:16 +00001958 uint32_t synthetic_stub_sym_id = symtab_load_command.nsyms;
Chris Lattner24943d22010-06-08 16:52:24 +00001959 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
1960 {
1961 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
1962 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
1963 uint32_t symbol_stub_offset = symbol_stub_index * 4;
1964 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
1965 {
Greg Clayton637029b2010-09-12 05:25:16 +00001966 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
Greg Clayton6af4fad2010-10-06 01:26:32 +00001967 if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
1968 continue;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001969
Greg Clayton637029b2010-09-12 05:25:16 +00001970 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
1971 Symbol *stub_symbol = NULL;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001972 if (index_pos != end_index_pos)
Greg Clayton637029b2010-09-12 05:25:16 +00001973 {
1974 // We have a remapping from the original nlist index to
1975 // a current symbol index, so just look this up by index
1976 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
1977 }
1978 else
1979 {
1980 // We need to lookup a symbol using the original nlist
1981 // symbol index since this index is coming from the
1982 // S_SYMBOL_STUBS
1983 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
1984 }
Greg Clayton0ad086f2010-09-07 17:36:17 +00001985
1986 assert (stub_symbol);
Chris Lattner24943d22010-06-08 16:52:24 +00001987 if (stub_symbol)
1988 {
1989 Address so_addr(symbol_stub_addr, section_list);
1990
Greg Claytona1b9a902011-11-13 04:15:56 +00001991 if (stub_symbol->GetType() == eSymbolTypeUndefined)
Chris Lattner24943d22010-06-08 16:52:24 +00001992 {
1993 // Change the external symbol into a trampoline that makes sense
1994 // These symbols were N_UNDF N_EXT, and are useless to us, so we
1995 // can re-use them so we don't have to make up a synthetic symbol
1996 // for no good reason.
1997 stub_symbol->SetType (eSymbolTypeTrampoline);
1998 stub_symbol->SetExternal (false);
Greg Clayton0c31d3d2012-03-07 21:03:09 +00001999 stub_symbol->GetAddress() = so_addr;
2000 stub_symbol->SetByteSize (symbol_stub_byte_size);
Chris Lattner24943d22010-06-08 16:52:24 +00002001 }
2002 else
2003 {
2004 // Make a synthetic symbol to describe the trampoline stub
2005 if (sym_idx >= num_syms)
Greg Clayton637029b2010-09-12 05:25:16 +00002006 sym = symtab->Resize (++num_syms);
2007 sym[sym_idx].SetID (synthetic_stub_sym_id++);
Chris Lattner24943d22010-06-08 16:52:24 +00002008 sym[sym_idx].GetMangled() = stub_symbol->GetMangled();
2009 sym[sym_idx].SetType (eSymbolTypeTrampoline);
2010 sym[sym_idx].SetIsSynthetic (true);
Greg Clayton0c31d3d2012-03-07 21:03:09 +00002011 sym[sym_idx].GetAddress() = so_addr;
2012 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
Chris Lattner24943d22010-06-08 16:52:24 +00002013 ++sym_idx;
2014 }
2015 }
2016 }
2017 }
2018 }
2019 }
2020 }
2021 }
Chris Lattner24943d22010-06-08 16:52:24 +00002022 return symtab->GetNumSymbols();
2023 }
2024 }
2025 offset = cmd_offset + symtab_load_command.cmdsize;
2026 }
2027 return 0;
2028}
2029
2030
2031void
2032ObjectFileMachO::Dump (Stream *s)
2033{
2034 lldb_private::Mutex::Locker locker(m_mutex);
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00002035 s->Printf("%p: ", this);
Chris Lattner24943d22010-06-08 16:52:24 +00002036 s->Indent();
Greg Clayton1674b122010-07-21 22:12:05 +00002037 if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped)
Chris Lattner24943d22010-06-08 16:52:24 +00002038 s->PutCString("ObjectFileMachO64");
2039 else
2040 s->PutCString("ObjectFileMachO32");
2041
Greg Claytoncf015052010-06-11 03:25:34 +00002042 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +00002043
Greg Clayton940b1032011-02-23 00:35:02 +00002044 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner24943d22010-06-08 16:52:24 +00002045
2046 if (m_sections_ap.get())
Greg Clayton58e844b2010-12-08 05:08:21 +00002047 m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00002048
2049 if (m_symtab_ap.get())
Greg Clayton8d3802d2010-10-08 04:20:14 +00002050 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
Chris Lattner24943d22010-06-08 16:52:24 +00002051}
2052
2053
2054bool
Greg Clayton0467c782011-02-04 18:53:10 +00002055ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner24943d22010-06-08 16:52:24 +00002056{
2057 lldb_private::Mutex::Locker locker(m_mutex);
2058 struct uuid_command load_cmd;
2059 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2060 uint32_t i;
2061 for (i=0; i<m_header.ncmds; ++i)
2062 {
2063 const uint32_t cmd_offset = offset;
2064 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2065 break;
2066
Greg Clayton1674b122010-07-21 22:12:05 +00002067 if (load_cmd.cmd == LoadCommandUUID)
Chris Lattner24943d22010-06-08 16:52:24 +00002068 {
2069 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
2070 if (uuid_bytes)
2071 {
2072 uuid->SetBytes (uuid_bytes);
2073 return true;
2074 }
2075 return false;
2076 }
2077 offset = cmd_offset + load_cmd.cmdsize;
2078 }
2079 return false;
2080}
2081
2082
2083uint32_t
2084ObjectFileMachO::GetDependentModules (FileSpecList& files)
2085{
2086 lldb_private::Mutex::Locker locker(m_mutex);
2087 struct load_command load_cmd;
2088 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2089 uint32_t count = 0;
Greg Clayton54b38412011-05-24 23:06:02 +00002090 const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
Chris Lattner24943d22010-06-08 16:52:24 +00002091 uint32_t i;
2092 for (i=0; i<m_header.ncmds; ++i)
2093 {
2094 const uint32_t cmd_offset = offset;
2095 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2096 break;
2097
2098 switch (load_cmd.cmd)
2099 {
Greg Clayton1674b122010-07-21 22:12:05 +00002100 case LoadCommandDylibLoad:
2101 case LoadCommandDylibLoadWeak:
2102 case LoadCommandDylibReexport:
2103 case LoadCommandDynamicLinkerLoad:
2104 case LoadCommandFixedVMShlibLoad:
Greg Clayton08a73202010-10-09 00:48:53 +00002105 case LoadCommandDylibLoadUpward:
Chris Lattner24943d22010-06-08 16:52:24 +00002106 {
2107 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2108 const char *path = m_data.PeekCStr(name_offset);
2109 // Skip any path that starts with '@' since these are usually:
2110 // @executable_path/.../file
2111 // @rpath/.../file
2112 if (path && path[0] != '@')
2113 {
Greg Clayton54b38412011-05-24 23:06:02 +00002114 FileSpec file_spec(path, resolve_path);
Chris Lattner24943d22010-06-08 16:52:24 +00002115 if (files.AppendIfUnique(file_spec))
2116 count++;
2117 }
2118 }
2119 break;
2120
2121 default:
2122 break;
2123 }
2124 offset = cmd_offset + load_cmd.cmdsize;
2125 }
2126 return count;
2127}
2128
Jim Ingham28775942011-03-07 23:44:08 +00002129lldb_private::Address
2130ObjectFileMachO::GetEntryPointAddress ()
2131{
2132 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
2133 // is initialized to an invalid address, so we can just return that.
2134 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
2135
2136 if (!IsExecutable() || m_entry_point_address.IsValid())
2137 return m_entry_point_address;
2138
2139 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
2140 // /usr/include/mach-o.h, but it is basically:
2141 //
2142 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
2143 // uint32_t count - this is the count of longs in the thread state data
2144 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
2145 // <repeat this trio>
2146 //
2147 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
2148 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
2149 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
2150 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
2151 //
2152 // For now we hard-code the offsets and flavors we need:
2153 //
2154 //
2155
2156 lldb_private::Mutex::Locker locker(m_mutex);
2157 struct load_command load_cmd;
2158 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2159 uint32_t i;
2160 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
2161 bool done = false;
2162
2163 for (i=0; i<m_header.ncmds; ++i)
2164 {
2165 const uint32_t cmd_offset = offset;
2166 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2167 break;
2168
2169 switch (load_cmd.cmd)
2170 {
2171 case LoadCommandUnixThread:
2172 case LoadCommandThread:
2173 {
2174 while (offset < cmd_offset + load_cmd.cmdsize)
2175 {
2176 uint32_t flavor = m_data.GetU32(&offset);
2177 uint32_t count = m_data.GetU32(&offset);
2178 if (count == 0)
2179 {
2180 // We've gotten off somehow, log and exit;
2181 return m_entry_point_address;
2182 }
2183
2184 switch (m_header.cputype)
2185 {
2186 case llvm::MachO::CPUTypeARM:
2187 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
2188 {
2189 offset += 60; // This is the offset of pc in the GPR thread state data structure.
2190 start_address = m_data.GetU32(&offset);
2191 done = true;
2192 }
2193 break;
2194 case llvm::MachO::CPUTypeI386:
2195 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
2196 {
2197 offset += 40; // This is the offset of eip in the GPR thread state data structure.
2198 start_address = m_data.GetU32(&offset);
2199 done = true;
2200 }
2201 break;
2202 case llvm::MachO::CPUTypeX86_64:
2203 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
2204 {
2205 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
2206 start_address = m_data.GetU64(&offset);
2207 done = true;
2208 }
2209 break;
2210 default:
2211 return m_entry_point_address;
2212 }
2213 // Haven't found the GPR flavor yet, skip over the data for this flavor:
2214 if (done)
2215 break;
2216 offset += count * 4;
2217 }
2218 }
2219 break;
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002220 case LoadCommandMain:
2221 {
2222 ConstString text_segment_name ("__TEXT");
2223 uint64_t entryoffset = m_data.GetU64(&offset);
2224 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2225 if (text_segment_sp)
2226 {
2227 done = true;
2228 start_address = text_segment_sp->GetFileAddress() + entryoffset;
2229 }
2230 }
Jim Ingham28775942011-03-07 23:44:08 +00002231
2232 default:
2233 break;
2234 }
2235 if (done)
2236 break;
2237
2238 // Go to the next load command:
2239 offset = cmd_offset + load_cmd.cmdsize;
2240 }
2241
2242 if (start_address != LLDB_INVALID_ADDRESS)
2243 {
2244 // We got the start address from the load commands, so now resolve that address in the sections
2245 // of this ObjectFile:
2246 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
2247 {
2248 m_entry_point_address.Clear();
2249 }
2250 }
2251 else
2252 {
2253 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
2254 // "start" symbol in the main executable.
2255
Greg Clayton3508c382012-02-24 01:59:29 +00002256 ModuleSP module_sp (GetModule());
Jim Ingham28775942011-03-07 23:44:08 +00002257
Greg Clayton3508c382012-02-24 01:59:29 +00002258 if (module_sp)
2259 {
2260 SymbolContextList contexts;
2261 SymbolContext context;
2262 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
2263 {
2264 if (contexts.GetContextAtIndex(0, context))
Greg Clayton0c31d3d2012-03-07 21:03:09 +00002265 m_entry_point_address = context.symbol->GetAddress();
Greg Clayton3508c382012-02-24 01:59:29 +00002266 }
2267 }
Jim Ingham28775942011-03-07 23:44:08 +00002268 }
2269
2270 return m_entry_point_address;
2271
2272}
2273
Greg Claytonb5a8f142012-02-05 02:38:54 +00002274lldb_private::Address
2275ObjectFileMachO::GetHeaderAddress ()
2276{
2277 lldb_private::Address header_addr;
2278 SectionList *section_list = GetSectionList();
2279 if (section_list)
2280 {
2281 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
2282 if (text_segment_sp)
2283 {
Greg Clayton3508c382012-02-24 01:59:29 +00002284 header_addr.SetSection (text_segment_sp);
Greg Claytonb5a8f142012-02-05 02:38:54 +00002285 header_addr.SetOffset (0);
2286 }
2287 }
2288 return header_addr;
2289}
2290
Greg Clayton46c9a352012-02-09 06:16:32 +00002291uint32_t
2292ObjectFileMachO::GetNumThreadContexts ()
2293{
2294 lldb_private::Mutex::Locker locker(m_mutex);
2295 if (!m_thread_context_offsets_valid)
2296 {
2297 m_thread_context_offsets_valid = true;
2298 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2299 FileRangeArray::Entry file_range;
2300 thread_command thread_cmd;
2301 for (uint32_t i=0; i<m_header.ncmds; ++i)
2302 {
2303 const uint32_t cmd_offset = offset;
2304 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
2305 break;
2306
2307 if (thread_cmd.cmd == LoadCommandThread)
2308 {
2309 file_range.SetRangeBase (offset);
2310 file_range.SetByteSize (thread_cmd.cmdsize - 8);
2311 m_thread_context_offsets.Append (file_range);
2312 }
2313 offset = cmd_offset + thread_cmd.cmdsize;
2314 }
2315 }
2316 return m_thread_context_offsets.GetSize();
2317}
2318
2319lldb::RegisterContextSP
2320ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
2321{
2322 lldb_private::Mutex::Locker locker(m_mutex);
2323 if (!m_thread_context_offsets_valid)
2324 GetNumThreadContexts ();
2325
2326 lldb::RegisterContextSP reg_ctx_sp;
2327 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
Greg Clayton9ce95382012-02-13 23:10:39 +00002328
2329 DataExtractor data (m_data,
2330 thread_context_file_range->GetRangeBase(),
2331 thread_context_file_range->GetByteSize());
2332
2333 switch (m_header.cputype)
Greg Clayton46c9a352012-02-09 06:16:32 +00002334 {
Greg Clayton9ce95382012-02-13 23:10:39 +00002335 case llvm::MachO::CPUTypeARM:
2336 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
2337 break;
2338
2339 case llvm::MachO::CPUTypeI386:
2340 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
2341 break;
2342
2343 case llvm::MachO::CPUTypeX86_64:
2344 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
2345 break;
Greg Clayton46c9a352012-02-09 06:16:32 +00002346 }
2347 return reg_ctx_sp;
2348}
2349
Greg Claytonb5a8f142012-02-05 02:38:54 +00002350
Greg Claytonca319972011-07-09 00:41:34 +00002351ObjectFile::Type
2352ObjectFileMachO::CalculateType()
2353{
2354 switch (m_header.filetype)
2355 {
2356 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2357 if (GetAddressByteSize () == 4)
2358 {
2359 // 32 bit kexts are just object files, but they do have a valid
2360 // UUID load command.
2361 UUID uuid;
2362 if (GetUUID(&uuid))
2363 {
2364 // this checking for the UUID load command is not enough
2365 // we could eventually look for the symbol named
2366 // "OSKextGetCurrentIdentifier" as this is required of kexts
2367 if (m_strata == eStrataInvalid)
2368 m_strata = eStrataKernel;
2369 return eTypeSharedLibrary;
2370 }
2371 }
2372 return eTypeObjectFile;
2373
2374 case HeaderFileTypeExecutable: return eTypeExecutable; // 0x2u MH_EXECUTE
2375 case HeaderFileTypeFixedVMShlib: return eTypeSharedLibrary; // 0x3u MH_FVMLIB
2376 case HeaderFileTypeCore: return eTypeCoreFile; // 0x4u MH_CORE
2377 case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary; // 0x5u MH_PRELOAD
2378 case HeaderFileTypeDynamicShlib: return eTypeSharedLibrary; // 0x6u MH_DYLIB
2379 case HeaderFileTypeDynamicLinkEditor: return eTypeDynamicLinker; // 0x7u MH_DYLINKER
2380 case HeaderFileTypeBundle: return eTypeSharedLibrary; // 0x8u MH_BUNDLE
2381 case HeaderFileTypeDynamicShlibStub: return eTypeStubLibrary; // 0x9u MH_DYLIB_STUB
2382 case HeaderFileTypeDSYM: return eTypeDebugInfo; // 0xAu MH_DSYM
2383 case HeaderFileTypeKextBundle: return eTypeSharedLibrary; // 0xBu MH_KEXT_BUNDLE
2384 default:
2385 break;
2386 }
2387 return eTypeUnknown;
2388}
2389
2390ObjectFile::Strata
2391ObjectFileMachO::CalculateStrata()
2392{
2393 switch (m_header.filetype)
2394 {
2395 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2396 {
2397 // 32 bit kexts are just object files, but they do have a valid
2398 // UUID load command.
2399 UUID uuid;
2400 if (GetUUID(&uuid))
2401 {
2402 // this checking for the UUID load command is not enough
2403 // we could eventually look for the symbol named
2404 // "OSKextGetCurrentIdentifier" as this is required of kexts
2405 if (m_type == eTypeInvalid)
2406 m_type = eTypeSharedLibrary;
2407
2408 return eStrataKernel;
2409 }
2410 }
2411 return eStrataUnknown;
2412
2413 case HeaderFileTypeExecutable: // 0x2u MH_EXECUTE
2414 // Check for the MH_DYLDLINK bit in the flags
2415 if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
Sean Callananac725af2012-02-10 20:22:35 +00002416 {
Greg Claytonca319972011-07-09 00:41:34 +00002417 return eStrataUser;
Sean Callananac725af2012-02-10 20:22:35 +00002418 }
2419 else
2420 {
2421 SectionList *section_list = GetSectionList();
2422 if (section_list)
2423 {
2424 static ConstString g_kld_section_name ("__KLD");
2425 if (section_list->FindSectionByName(g_kld_section_name))
2426 return eStrataKernel;
2427 }
2428 }
2429 return eStrataRawImage;
Greg Claytonca319972011-07-09 00:41:34 +00002430
2431 case HeaderFileTypeFixedVMShlib: return eStrataUser; // 0x3u MH_FVMLIB
2432 case HeaderFileTypeCore: return eStrataUnknown; // 0x4u MH_CORE
Sean Callananac725af2012-02-10 20:22:35 +00002433 case HeaderFileTypePreloadedExecutable: return eStrataRawImage; // 0x5u MH_PRELOAD
Greg Claytonca319972011-07-09 00:41:34 +00002434 case HeaderFileTypeDynamicShlib: return eStrataUser; // 0x6u MH_DYLIB
2435 case HeaderFileTypeDynamicLinkEditor: return eStrataUser; // 0x7u MH_DYLINKER
2436 case HeaderFileTypeBundle: return eStrataUser; // 0x8u MH_BUNDLE
2437 case HeaderFileTypeDynamicShlibStub: return eStrataUser; // 0x9u MH_DYLIB_STUB
2438 case HeaderFileTypeDSYM: return eStrataUnknown; // 0xAu MH_DSYM
2439 case HeaderFileTypeKextBundle: return eStrataKernel; // 0xBu MH_KEXT_BUNDLE
2440 default:
2441 break;
2442 }
2443 return eStrataUnknown;
2444}
2445
2446
Greg Clayton49f4bf22012-02-22 19:41:02 +00002447uint32_t
2448ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
2449{
2450 lldb_private::Mutex::Locker locker(m_mutex);
2451 struct dylib_command load_cmd;
2452 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2453 uint32_t version_cmd = 0;
2454 uint64_t version = 0;
2455 uint32_t i;
2456 for (i=0; i<m_header.ncmds; ++i)
2457 {
2458 const uint32_t cmd_offset = offset;
2459 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2460 break;
2461
2462 if (load_cmd.cmd == LoadCommandDylibIdent)
2463 {
2464 if (version_cmd == 0)
2465 {
2466 version_cmd = load_cmd.cmd;
2467 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
2468 break;
2469 version = load_cmd.dylib.current_version;
2470 }
2471 break; // Break for now unless there is another more complete version
2472 // number load command in the future.
2473 }
2474 offset = cmd_offset + load_cmd.cmdsize;
2475 }
2476
2477 if (version_cmd == LoadCommandDylibIdent)
2478 {
2479 if (versions != NULL && num_versions > 0)
2480 {
2481 if (num_versions > 0)
2482 versions[0] = (version & 0xFFFF0000ull) >> 16;
2483 if (num_versions > 1)
2484 versions[1] = (version & 0x0000FF00ull) >> 8;
2485 if (num_versions > 2)
2486 versions[2] = (version & 0x000000FFull);
2487 // Fill in an remaining version numbers with invalid values
2488 for (i=3; i<num_versions; ++i)
2489 versions[i] = UINT32_MAX;
2490 }
2491 // The LC_ID_DYLIB load command has a version with 3 version numbers
2492 // in it, so always return 3
2493 return 3;
2494 }
2495 return false;
2496}
2497
Chris Lattner24943d22010-06-08 16:52:24 +00002498bool
Greg Clayton395fc332011-02-15 21:59:32 +00002499ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +00002500{
2501 lldb_private::Mutex::Locker locker(m_mutex);
Greg Claytonb3448432011-03-24 21:19:54 +00002502 arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002503
2504 // Files with type MH_PRELOAD are currently used in cases where the image
2505 // debugs at the addresses in the file itself. Below we set the OS to
2506 // unknown to make sure we use the DynamicLoaderStatic()...
2507 if (m_header.filetype == HeaderFileTypePreloadedExecutable)
2508 {
2509 arch.GetTriple().setOS (llvm::Triple::UnknownOS);
2510 }
2511
Greg Clayton395fc332011-02-15 21:59:32 +00002512 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00002513}
2514
2515
2516//------------------------------------------------------------------
2517// PluginInterface protocol
2518//------------------------------------------------------------------
2519const char *
2520ObjectFileMachO::GetPluginName()
2521{
2522 return "ObjectFileMachO";
2523}
2524
2525const char *
2526ObjectFileMachO::GetShortPluginName()
2527{
2528 return GetPluginNameStatic();
2529}
2530
2531uint32_t
2532ObjectFileMachO::GetPluginVersion()
2533{
2534 return 1;
2535}
2536