blob: 479d0d8287898c6de2af6354c94897449068b718 [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(""));
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001145 ModuleSP module_sp (GetModule());
1146 if (!module_sp)
1147 return 0;
1148
1149 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
1150 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
1151 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
1152 FunctionStarts function_starts;
Chris Lattner24943d22010-06-08 16:52:24 +00001153 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1154 uint32_t i;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001155
Greg Clayton0fea0512011-12-30 00:32:24 +00001156 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
1157
Chris Lattner24943d22010-06-08 16:52:24 +00001158 for (i=0; i<m_header.ncmds; ++i)
1159 {
1160 const uint32_t cmd_offset = offset;
1161 // Read in the load command and load command size
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001162 struct load_command lc;
1163 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001164 break;
1165 // Watch for the symbol table load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001166 switch (lc.cmd)
Chris Lattner24943d22010-06-08 16:52:24 +00001167 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001168 case LoadCommandSymtab:
1169 symtab_load_command.cmd = lc.cmd;
1170 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00001171 // Read in the rest of the symtab load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001172 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
1173 return 0;
1174 if (symtab_load_command.symoff == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001175 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001176 if (log)
1177 module_sp->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
1178 return 0;
1179 }
1180
1181 if (symtab_load_command.stroff == 0)
1182 {
1183 if (log)
1184 module_sp->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
1185 return 0;
1186 }
1187
1188 if (symtab_load_command.nsyms == 0)
1189 {
1190 if (log)
1191 module_sp->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
1192 return 0;
1193 }
1194
1195 if (symtab_load_command.strsize == 0)
1196 {
1197 if (log)
1198 module_sp->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
1199 return 0;
1200 }
1201 break;
1202
1203 case LoadCommandFunctionStarts:
1204 function_starts_load_command.cmd = lc.cmd;
1205 function_starts_load_command.cmdsize = lc.cmdsize;
1206 if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
1207 bzero (&function_starts_load_command, sizeof(function_starts_load_command));
1208 break;
1209
1210 default:
1211 break;
1212 }
1213 offset = cmd_offset + lc.cmdsize;
1214 }
1215
1216 if (symtab_load_command.cmd)
1217 {
1218 Symtab *symtab = m_symtab_ap.get();
1219 SectionList *section_list = GetSectionList();
1220 if (section_list == NULL)
1221 return 0;
1222
1223 ProcessSP process_sp (m_process_wp.lock());
1224
1225 const size_t addr_byte_size = m_data.GetAddressByteSize();
1226 bool bit_width_32 = addr_byte_size == 4;
1227 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
1228
1229 DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1230 DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1231 DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1232
1233 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
1234 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
1235 if (process_sp)
1236 {
1237 Target &target = process_sp->GetTarget();
1238 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
1239 // Reading mach file from memory in a process or core file...
1240
1241 if (linkedit_section_sp)
1242 {
1243 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
1244 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
1245 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
1246 const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
1247 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
1248 if (nlist_data_sp)
1249 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
1250 DataBufferSP strtab_data_sp (ReadMemory (process_sp, stroff_addr, strtab_data_byte_size));
1251 if (strtab_data_sp)
1252 strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
1253 if (function_starts_load_command.cmd)
Greg Clayton0fea0512011-12-30 00:32:24 +00001254 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001255 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1256 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
1257 if (func_start_data_sp)
1258 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
Greg Clayton0fea0512011-12-30 00:32:24 +00001259 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001260 }
1261 }
1262 else
1263 {
1264 nlist_data.SetData (m_data,
1265 symtab_load_command.symoff,
1266 nlist_data_byte_size);
1267 strtab_data.SetData (m_data,
1268 symtab_load_command.stroff,
1269 strtab_data_byte_size);
1270 if (function_starts_load_command.cmd)
1271 {
1272 function_starts_data.SetData (m_data,
1273 function_starts_load_command.dataoff,
1274 function_starts_load_command.datasize);
1275 }
1276 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001277
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001278 if (nlist_data.GetByteSize() == 0)
1279 {
1280 if (log)
1281 module_sp->LogMessage(log.get(), "failed to read nlist data");
1282 return 0;
1283 }
1284
1285
1286 if (strtab_data.GetByteSize() == 0)
1287 {
1288 if (log)
1289 module_sp->LogMessage(log.get(), "failed to read strtab data");
1290 return 0;
1291 }
1292
1293 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
1294 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
1295 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
1296 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
1297 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
1298 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
1299 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
1300 SectionSP eh_frame_section_sp;
1301 if (text_section_sp.get())
1302 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
1303 else
1304 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
1305
1306
1307 if (text_section_sp && function_starts_data.GetByteSize())
1308 {
1309 FunctionStarts::Entry function_start_entry;
1310 function_start_entry.data = false;
1311 uint32_t function_start_offset = 0;
1312 function_start_entry.addr = text_section_sp->GetFileAddress();
1313 uint64_t delta;
1314 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
1315 {
1316 // Now append the current entry
1317 function_start_entry.addr += delta;
1318 function_starts.Append(function_start_entry);
1319 }
1320 }
1321
1322 const uint32_t function_starts_count = function_starts.GetSize();
1323
1324 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
1325
1326 uint32_t nlist_data_offset = 0;
1327
1328 uint32_t N_SO_index = UINT32_MAX;
1329
1330 MachSymtabSectionInfo section_info (section_list);
1331 std::vector<uint32_t> N_FUN_indexes;
1332 std::vector<uint32_t> N_NSYM_indexes;
1333 std::vector<uint32_t> N_INCL_indexes;
1334 std::vector<uint32_t> N_BRAC_indexes;
1335 std::vector<uint32_t> N_COMM_indexes;
1336 typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
1337 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
1338 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
1339 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
1340 // Any symbols that get merged into another will get an entry
1341 // in this map so we know
1342 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
1343 uint32_t nlist_idx = 0;
1344 Symbol *symbol_ptr = NULL;
1345
1346 uint32_t sym_idx = 0;
1347 Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1348 uint32_t num_syms = symtab->GetNumSymbols();
1349
1350 //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1351 for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
1352 {
1353 struct nlist_64 nlist;
1354 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
1355 break;
1356
1357 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
1358 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
1359 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
1360 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
1361 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
1362
1363 SymbolType type = eSymbolTypeInvalid;
1364 const char *symbol_name = strtab_data.PeekCStr(nlist.n_strx);
1365 if (symbol_name == NULL)
1366 {
1367 // No symbol should be NULL, even the symbols with no
1368 // string values should have an offset zero which points
1369 // to an empty C-string
1370 Host::SystemLog (Host::eSystemLogError,
1371 "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
1372 nlist_idx,
1373 nlist.n_strx,
1374 module_sp->GetFileSpec().GetDirectory().GetCString(),
1375 module_sp->GetFileSpec().GetFilename().GetCString());
1376 continue;
1377 }
1378 const char *symbol_name_non_abi_mangled = NULL;
1379
1380 if (symbol_name[0] == '\0')
1381 symbol_name = NULL;
1382 SectionSP symbol_section;
1383 uint32_t symbol_byte_size = 0;
1384 bool add_nlist = true;
1385 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
1386
1387 assert (sym_idx < num_syms);
1388
1389 sym[sym_idx].SetDebug (is_debug);
1390
1391 if (is_debug)
1392 {
1393 switch (nlist.n_type)
Greg Clayton0fea0512011-12-30 00:32:24 +00001394 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001395 case StabGlobalSymbol:
1396 // N_GSYM -- global symbol: name,,NO_SECT,type,0
1397 // Sometimes the N_GSYM value contains the address.
1398
1399 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
1400 // have the same address, but we want to ensure that we always find only the real symbol,
1401 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
1402 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
1403 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
1404 // same address.
1405
1406 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
1407 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
1408 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
1409 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
1410 add_nlist = false;
1411 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00001412 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001413 sym[sym_idx].SetExternal(true);
1414 if (nlist.n_value != 0)
1415 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1416 type = eSymbolTypeData;
Greg Claytonb5a8f142012-02-05 02:38:54 +00001417 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001418 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +00001419
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001420 case StabFunctionName:
1421 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
1422 type = eSymbolTypeCompiler;
1423 break;
Greg Clayton0fea0512011-12-30 00:32:24 +00001424
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001425 case StabFunction:
1426 // N_FUN -- procedure: name,,n_sect,linenumber,address
1427 if (symbol_name)
Greg Claytona9c4f312011-10-31 20:50:40 +00001428 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001429 type = eSymbolTypeCode;
1430 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1431
1432 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
1433 // We use the current number of symbols in the symbol table in lieu of
1434 // using nlist_idx in case we ever start trimming entries out
1435 N_FUN_indexes.push_back(sym_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001436 }
1437 else
1438 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001439 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00001440
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001441 if ( !N_FUN_indexes.empty() )
Chris Lattner24943d22010-06-08 16:52:24 +00001442 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001443 // Copy the size of the function into the original STAB entry so we don't have
1444 // to hunt for it later
1445 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
1446 N_FUN_indexes.pop_back();
1447 // We don't really need the end function STAB as it contains the size which
1448 // we already placed with the original symbol, so don't add it if we want a
1449 // minimal symbol table
1450 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001451 add_nlist = false;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001452 }
Greg Clayton3f69eac2011-12-03 02:30:59 +00001453 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001454 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001455
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001456 case StabStaticSymbol:
1457 // N_STSYM -- static symbol: name,,n_sect,type,address
1458 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
1459 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1460 type = eSymbolTypeData;
1461 break;
1462
1463 case StabLocalCommon:
1464 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
1465 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1466 type = eSymbolTypeCommonBlock;
1467 break;
1468
1469 case StabBeginSymbol:
1470 // N_BNSYM
1471 // We use the current number of symbols in the symbol table in lieu of
1472 // using nlist_idx in case we ever start trimming entries out
1473 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001474 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001475 // Skip these if we want minimal symbol tables
1476 add_nlist = false;
1477 }
1478 else
1479 {
1480 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1481 N_NSYM_indexes.push_back(sym_idx);
1482 type = eSymbolTypeScopeBegin;
1483 }
1484 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001485
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001486 case StabEndSymbol:
1487 // N_ENSYM
1488 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
1489 // so that we can always skip the entire symbol if we need to navigate
1490 // more quickly at the source level when parsing STABS
1491 if (minimize)
1492 {
1493 // Skip these if we want minimal symbol tables
1494 add_nlist = false;
1495 }
1496 else
1497 {
1498 if ( !N_NSYM_indexes.empty() )
Greg Clayton3f69eac2011-12-03 02:30:59 +00001499 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001500 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
1501 symbol_ptr->SetByteSize(sym_idx + 1);
1502 symbol_ptr->SetSizeIsSibling(true);
1503 N_NSYM_indexes.pop_back();
1504 }
1505 type = eSymbolTypeScopeEnd;
1506 }
1507 break;
1508
1509
1510 case StabSourceFileOptions:
1511 // N_OPT - emitted with gcc2_compiled and in gcc source
1512 type = eSymbolTypeCompiler;
1513 break;
1514
1515 case StabRegisterSymbol:
1516 // N_RSYM - register sym: name,,NO_SECT,type,register
1517 type = eSymbolTypeVariable;
1518 break;
1519
1520 case StabSourceLine:
1521 // N_SLINE - src line: 0,,n_sect,linenumber,address
1522 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1523 type = eSymbolTypeLineEntry;
1524 break;
1525
1526 case StabStructureType:
1527 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
1528 type = eSymbolTypeVariableType;
1529 break;
1530
1531 case StabSourceFileName:
1532 // N_SO - source file name
1533 type = eSymbolTypeSourceFile;
1534 if (symbol_name == NULL)
1535 {
1536 if (minimize)
1537 add_nlist = false;
1538 if (N_SO_index != UINT32_MAX)
1539 {
1540 // Set the size of the N_SO to the terminating index of this N_SO
1541 // so that we can always skip the entire N_SO if we need to navigate
1542 // more quickly at the source level when parsing STABS
1543 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
1544 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
1545 symbol_ptr->SetSizeIsSibling(true);
1546 }
1547 N_NSYM_indexes.clear();
1548 N_INCL_indexes.clear();
1549 N_BRAC_indexes.clear();
1550 N_COMM_indexes.clear();
1551 N_FUN_indexes.clear();
1552 N_SO_index = UINT32_MAX;
1553 }
1554 else
1555 {
1556 // We use the current number of symbols in the symbol table in lieu of
1557 // using nlist_idx in case we ever start trimming entries out
1558 if (symbol_name[0] == '/')
1559 N_SO_index = sym_idx;
1560 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1561 {
1562 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
1563 if (so_path && so_path[0])
1564 {
1565 std::string full_so_path (so_path);
1566 if (*full_so_path.rbegin() != '/')
1567 full_so_path += '/';
1568 full_so_path += symbol_name;
1569 sym[sym_idx - 1].GetMangled().SetValue(full_so_path.c_str(), false);
1570 add_nlist = false;
1571 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1572 }
1573 }
1574 }
1575
1576 break;
1577
1578 case StabObjectFileName:
1579 // N_OSO - object file name: name,,0,0,st_mtime
1580 type = eSymbolTypeObjectFile;
1581 break;
1582
1583 case StabLocalSymbol:
1584 // N_LSYM - local sym: name,,NO_SECT,type,offset
1585 type = eSymbolTypeLocal;
1586 break;
1587
1588 //----------------------------------------------------------------------
1589 // INCL scopes
1590 //----------------------------------------------------------------------
1591 case StabBeginIncludeFileName:
1592 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
1593 // We use the current number of symbols in the symbol table in lieu of
1594 // using nlist_idx in case we ever start trimming entries out
1595 N_INCL_indexes.push_back(sym_idx);
1596 type = eSymbolTypeScopeBegin;
1597 break;
1598
1599 case StabEndIncludeFile:
1600 // N_EINCL - include file end: name,,NO_SECT,0,0
1601 // Set the size of the N_BINCL to the terminating index of this N_EINCL
1602 // so that we can always skip the entire symbol if we need to navigate
1603 // more quickly at the source level when parsing STABS
1604 if ( !N_INCL_indexes.empty() )
1605 {
1606 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
1607 symbol_ptr->SetByteSize(sym_idx + 1);
1608 symbol_ptr->SetSizeIsSibling(true);
1609 N_INCL_indexes.pop_back();
1610 }
1611 type = eSymbolTypeScopeEnd;
1612 break;
1613
1614 case StabIncludeFileName:
1615 // N_SOL - #included file name: name,,n_sect,0,address
1616 type = eSymbolTypeHeaderFile;
1617
1618 // We currently don't use the header files on darwin
1619 if (minimize)
1620 add_nlist = false;
1621 break;
1622
1623 case StabCompilerParameters:
1624 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
1625 type = eSymbolTypeCompiler;
1626 break;
1627
1628 case StabCompilerVersion:
1629 // N_VERSION - compiler version: name,,NO_SECT,0,0
1630 type = eSymbolTypeCompiler;
1631 break;
1632
1633 case StabCompilerOptLevel:
1634 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
1635 type = eSymbolTypeCompiler;
1636 break;
1637
1638 case StabParameter:
1639 // N_PSYM - parameter: name,,NO_SECT,type,offset
1640 type = eSymbolTypeVariable;
1641 break;
1642
1643 case StabAlternateEntry:
1644 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
1645 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1646 type = eSymbolTypeLineEntry;
1647 break;
1648
1649 //----------------------------------------------------------------------
1650 // Left and Right Braces
1651 //----------------------------------------------------------------------
1652 case StabLeftBracket:
1653 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
1654 // We use the current number of symbols in the symbol table in lieu of
1655 // using nlist_idx in case we ever start trimming entries out
1656 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1657 N_BRAC_indexes.push_back(sym_idx);
1658 type = eSymbolTypeScopeBegin;
1659 break;
1660
1661 case StabRightBracket:
1662 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
1663 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
1664 // so that we can always skip the entire symbol if we need to navigate
1665 // more quickly at the source level when parsing STABS
1666 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1667 if ( !N_BRAC_indexes.empty() )
1668 {
1669 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
1670 symbol_ptr->SetByteSize(sym_idx + 1);
1671 symbol_ptr->SetSizeIsSibling(true);
1672 N_BRAC_indexes.pop_back();
1673 }
1674 type = eSymbolTypeScopeEnd;
1675 break;
1676
1677 case StabDeletedIncludeFile:
1678 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
1679 type = eSymbolTypeHeaderFile;
1680 break;
1681
1682 //----------------------------------------------------------------------
1683 // COMM scopes
1684 //----------------------------------------------------------------------
1685 case StabBeginCommon:
1686 // N_BCOMM - begin common: name,,NO_SECT,0,0
1687 // We use the current number of symbols in the symbol table in lieu of
1688 // using nlist_idx in case we ever start trimming entries out
1689 type = eSymbolTypeScopeBegin;
1690 N_COMM_indexes.push_back(sym_idx);
1691 break;
1692
1693 case StabEndCommonLocal:
1694 // N_ECOML - end common (local name): 0,,n_sect,0,address
1695 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1696 // Fall through
1697
1698 case StabEndCommon:
1699 // N_ECOMM - end common: name,,n_sect,0,0
1700 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
1701 // so that we can always skip the entire symbol if we need to navigate
1702 // more quickly at the source level when parsing STABS
1703 if ( !N_COMM_indexes.empty() )
1704 {
1705 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
1706 symbol_ptr->SetByteSize(sym_idx + 1);
1707 symbol_ptr->SetSizeIsSibling(true);
1708 N_COMM_indexes.pop_back();
1709 }
1710 type = eSymbolTypeScopeEnd;
1711 break;
1712
1713 case StabLength:
1714 // N_LENG - second stab entry with length information
1715 type = eSymbolTypeAdditional;
1716 break;
1717
1718 default: break;
1719 }
1720 }
1721 else
1722 {
1723 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
1724 uint8_t n_type = NlistMaskType & nlist.n_type;
1725 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
1726
1727 switch (n_type)
1728 {
1729 case NListTypeIndirect: // N_INDR - Fall through
1730 case NListTypePreboundUndefined:// N_PBUD - Fall through
1731 case NListTypeUndefined: // N_UNDF
1732 type = eSymbolTypeUndefined;
1733 break;
1734
1735 case NListTypeAbsolute: // N_ABS
1736 type = eSymbolTypeAbsolute;
1737 break;
1738
1739 case NListTypeSection: // N_SECT
1740 {
1741 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1742
1743 if (symbol_section == NULL)
1744 {
1745 // TODO: warn about this?
1746 add_nlist = false;
1747 break;
1748 }
1749
1750 if (TEXT_eh_frame_sectID == nlist.n_sect)
1751 {
1752 type = eSymbolTypeException;
Chris Lattner24943d22010-06-08 16:52:24 +00001753 }
1754 else
1755 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001756 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
1757
1758 switch (section_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001759 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001760 case SectionTypeRegular: break; // regular section
1761 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
1762 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
1763 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
1764 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
1765 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
1766 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
1767 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
1768 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1769 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
1770 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
1771 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
1772 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
1773 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
1774 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
1775 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
1776 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
1777 default: break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001778 }
Chris Lattner24943d22010-06-08 16:52:24 +00001779
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001780 if (type == eSymbolTypeInvalid)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001781 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001782 const char *symbol_sect_name = symbol_section->GetName().AsCString();
1783 if (symbol_section->IsDescendant (text_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00001784 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001785 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
1786 SectionAttrUserSelfModifyingCode |
1787 SectionAttrSytemSomeInstructions))
1788 type = eSymbolTypeData;
1789 else
1790 type = eSymbolTypeCode;
Greg Clayton576a68b2010-09-08 16:38:06 +00001791 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001792 else
1793 if (symbol_section->IsDescendant(data_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00001794 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001795 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
Greg Clayton7c36fa02010-09-11 03:13:28 +00001796 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001797 type = eSymbolTypeRuntime;
Chris Lattner24943d22010-06-08 16:52:24 +00001798
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001799 if (symbol_name &&
1800 symbol_name[0] == '_' &&
1801 symbol_name[1] == 'O' &&
1802 symbol_name[2] == 'B')
Greg Clayton637029b2010-09-12 05:25:16 +00001803 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001804 llvm::StringRef symbol_name_ref(symbol_name);
1805 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
1806 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
1807 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
1808 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
Chris Lattner24943d22010-06-08 16:52:24 +00001809 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001810 symbol_name_non_abi_mangled = symbol_name + 1;
1811 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
1812 type = eSymbolTypeObjCClass;
Chris Lattner24943d22010-06-08 16:52:24 +00001813 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001814 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
Chris Lattner24943d22010-06-08 16:52:24 +00001815 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001816 symbol_name_non_abi_mangled = symbol_name + 1;
1817 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
1818 type = eSymbolTypeObjCMetaClass;
1819 }
1820 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
1821 {
1822 symbol_name_non_abi_mangled = symbol_name + 1;
1823 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
1824 type = eSymbolTypeObjCIVar;
Chris Lattner24943d22010-06-08 16:52:24 +00001825 }
1826 }
1827 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001828 else
1829 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
1830 {
1831 type = eSymbolTypeException;
1832 }
1833 else
1834 {
1835 type = eSymbolTypeData;
1836 }
1837 }
1838 else
1839 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
1840 {
1841 type = eSymbolTypeTrampoline;
1842 }
1843 else
1844 if (symbol_section->IsDescendant(objc_section_sp.get()))
1845 {
1846 type = eSymbolTypeRuntime;
1847 if (symbol_name && symbol_name[0] == '.')
1848 {
1849 llvm::StringRef symbol_name_ref(symbol_name);
1850 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
1851 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
1852 {
1853 symbol_name_non_abi_mangled = symbol_name;
1854 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
1855 type = eSymbolTypeObjCClass;
1856 }
1857 }
Chris Lattner24943d22010-06-08 16:52:24 +00001858 }
1859 }
1860 }
1861 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001862 break;
1863 }
1864 }
1865
1866 if (add_nlist)
1867 {
1868 uint64_t symbol_value = nlist.n_value;
1869 bool symbol_name_is_mangled = false;
1870
1871 if (symbol_name_non_abi_mangled)
1872 {
1873 sym[sym_idx].GetMangled().SetMangledName (symbol_name_non_abi_mangled);
1874 sym[sym_idx].GetMangled().SetDemangledName (symbol_name);
Chris Lattner24943d22010-06-08 16:52:24 +00001875 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001876 else
1877 {
1878 if (symbol_name && symbol_name[0] == '_')
1879 {
1880 symbol_name_is_mangled = symbol_name[1] == '_';
1881 symbol_name++; // Skip the leading underscore
1882 }
1883
1884 if (symbol_name)
1885 {
1886 sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
1887 }
1888 }
1889
1890 if (is_debug == false)
1891 {
1892 if (type == eSymbolTypeCode)
1893 {
1894 // See if we can find a N_FUN entry for any code symbols.
1895 // If we do find a match, and the name matches, then we
1896 // can merge the two into just the function symbol to avoid
1897 // duplicate entries in the symbol table
1898 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
1899 if (pos != N_FUN_addr_to_sym_idx.end())
1900 {
1901 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1902 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1903 {
1904 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
1905 // We just need the flags from the linker symbol, so put these flags
1906 // into the N_FUN flags to avoid duplicate symbols in the symbol table
1907 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1908 sym[sym_idx].Clear();
1909 continue;
1910 }
1911 }
1912 }
1913 else if (type == eSymbolTypeData)
1914 {
1915 // See if we can find a N_STSYM entry for any data symbols.
1916 // If we do find a match, and the name matches, then we
1917 // can merge the two into just the Static symbol to avoid
1918 // duplicate entries in the symbol table
1919 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
1920 if (pos != N_STSYM_addr_to_sym_idx.end())
1921 {
1922 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1923 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1924 {
1925 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
1926 // We just need the flags from the linker symbol, so put these flags
1927 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
1928 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1929 sym[sym_idx].Clear();
1930 continue;
1931 }
1932 }
1933 }
1934 }
1935 if (symbol_section)
1936 {
1937 const addr_t section_file_addr = symbol_section->GetFileAddress();
1938 if (symbol_byte_size == 0 && function_starts_count > 0)
1939 {
1940 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry(nlist.n_value, true);
1941 if (func_start_entry)
1942 {
1943 func_start_entry->data = true;
1944 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
1945 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
1946 if (next_func_start_entry)
1947 {
1948 symbol_byte_size = std::min<lldb::addr_t>(next_func_start_entry->addr - func_start_entry->addr, section_end_file_addr - func_start_entry->addr);
1949 }
1950 else
1951 {
1952 symbol_byte_size = section_end_file_addr - func_start_entry->addr;
1953 }
1954 }
1955 }
1956 symbol_value -= section_file_addr;
1957 }
1958
1959 sym[sym_idx].SetID (nlist_idx);
1960 sym[sym_idx].SetType (type);
1961 sym[sym_idx].GetAddress().SetSection (symbol_section);
1962 sym[sym_idx].GetAddress().SetOffset (symbol_value);
1963 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1964
1965 if (symbol_byte_size > 0)
1966 sym[sym_idx].SetByteSize(symbol_byte_size);
1967
1968 ++sym_idx;
1969 }
1970 else
1971 {
1972 sym[sym_idx].Clear();
1973 }
1974
1975 }
1976
1977 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
1978 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
1979 // such entries by figuring out what the address for the global is by looking up this non-STAB
1980 // entry and copying the value into the debug symbol's value to save us the hassle in the
1981 // debug symbol parser.
1982
1983 Symbol *global_symbol = NULL;
1984 for (nlist_idx = 0;
1985 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
1986 nlist_idx++)
1987 {
1988 if (global_symbol->GetAddress().GetFileAddress() == 0)
1989 {
1990 std::vector<uint32_t> indexes;
1991 if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
1992 {
1993 std::vector<uint32_t>::const_iterator pos;
1994 std::vector<uint32_t>::const_iterator end = indexes.end();
1995 for (pos = indexes.begin(); pos != end; ++pos)
1996 {
1997 symbol_ptr = symtab->SymbolAtIndex(*pos);
1998 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
1999 {
2000 global_symbol->GetAddress() = symbol_ptr->GetAddress();
2001 break;
2002 }
2003 }
2004 }
Chris Lattner24943d22010-06-08 16:52:24 +00002005 }
2006 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002007
2008 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
2009
2010
2011 if (function_starts_count > 0)
2012 {
2013 char synthetic_function_symbol[PATH_MAX];
2014 uint32_t num_synthetic_function_symbols = 0;
2015 for (i=0; i<function_starts_count; ++i)
2016 {
2017 if (function_starts.GetEntryRef (i).data == false)
2018 ++num_synthetic_function_symbols;
2019 }
2020
2021 if (num_synthetic_function_symbols > 0)
2022 {
2023 if (num_syms < sym_idx + num_synthetic_function_symbols)
2024 {
2025 num_syms = sym_idx + num_synthetic_function_symbols;
2026 sym = symtab->Resize (num_syms);
2027 }
2028 uint32_t synthetic_function_symbol_idx = 0;
2029 for (i=0; i<function_starts_count; ++i)
2030 {
2031 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
2032 if (func_start_entry->data == false)
2033 {
2034 Address symbol_addr;
2035 if (module_sp->ResolveFileAddress (func_start_entry->addr, symbol_addr))
2036 {
2037 SectionSP symbol_section (symbol_addr.GetSection());
2038 uint32_t symbol_byte_size = 0;
2039 if (symbol_section)
2040 {
2041 const addr_t section_file_addr = symbol_section->GetFileAddress();
2042 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2043 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2044 if (next_func_start_entry)
2045 {
2046 symbol_byte_size = std::min<lldb::addr_t>(next_func_start_entry->addr - func_start_entry->addr, section_end_file_addr - func_start_entry->addr);
2047 }
2048 else
2049 {
2050 symbol_byte_size = section_end_file_addr - func_start_entry->addr;
2051 }
2052 snprintf (synthetic_function_symbol,
2053 sizeof(synthetic_function_symbol),
2054 "___lldb_unnamed_function%u$$%s",
2055 ++synthetic_function_symbol_idx,
2056 module_sp->GetFileSpec().GetFilename().GetCString());
2057 sym[sym_idx].SetID (synthetic_sym_id++);
2058 sym[sym_idx].GetMangled().SetDemangledName(synthetic_function_symbol);
2059 sym[sym_idx].SetType (eSymbolTypeCode);
2060 sym[sym_idx].SetIsSynthetic (true);
2061 sym[sym_idx].GetAddress() = symbol_addr;
2062 if (symbol_byte_size)
2063 sym[sym_idx].SetByteSize (symbol_byte_size);
2064 ++sym_idx;
2065 }
2066 }
2067 }
2068 }
2069 }
2070 }
2071
2072 // Trim our symbols down to just what we ended up with after
2073 // removing any symbols.
2074 if (sym_idx < num_syms)
2075 {
2076 num_syms = sym_idx;
2077 sym = symtab->Resize (num_syms);
2078 }
2079
2080 // Now synthesize indirect symbols
2081 if (m_dysymtab.nindirectsyms != 0)
2082 {
2083 DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
2084
2085 if (indirect_symbol_index_data.GetByteSize())
2086 {
2087 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
2088
2089 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
2090 {
2091 if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
2092 {
2093 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
2094 if (symbol_stub_byte_size == 0)
2095 continue;
2096
2097 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
2098
2099 if (num_symbol_stubs == 0)
2100 continue;
2101
2102 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
2103 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
2104 {
2105 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
2106 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
2107 uint32_t symbol_stub_offset = symbol_stub_index * 4;
2108 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
2109 {
2110 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
2111 if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
2112 continue;
2113
2114 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
2115 Symbol *stub_symbol = NULL;
2116 if (index_pos != end_index_pos)
2117 {
2118 // We have a remapping from the original nlist index to
2119 // a current symbol index, so just look this up by index
2120 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
2121 }
2122 else
2123 {
2124 // We need to lookup a symbol using the original nlist
2125 // symbol index since this index is coming from the
2126 // S_SYMBOL_STUBS
2127 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
2128 }
2129
2130 assert (stub_symbol);
2131 if (stub_symbol)
2132 {
2133 Address so_addr(symbol_stub_addr, section_list);
2134
2135 if (stub_symbol->GetType() == eSymbolTypeUndefined)
2136 {
2137 // Change the external symbol into a trampoline that makes sense
2138 // These symbols were N_UNDF N_EXT, and are useless to us, so we
2139 // can re-use them so we don't have to make up a synthetic symbol
2140 // for no good reason.
2141 stub_symbol->SetType (eSymbolTypeTrampoline);
2142 stub_symbol->SetExternal (false);
2143 stub_symbol->GetAddress() = so_addr;
2144 stub_symbol->SetByteSize (symbol_stub_byte_size);
2145 }
2146 else
2147 {
2148 // Make a synthetic symbol to describe the trampoline stub
2149 if (sym_idx >= num_syms)
2150 sym = symtab->Resize (++num_syms);
2151 sym[sym_idx].SetID (synthetic_sym_id++);
2152 sym[sym_idx].GetMangled() = stub_symbol->GetMangled();
2153 sym[sym_idx].SetType (eSymbolTypeTrampoline);
2154 sym[sym_idx].SetIsSynthetic (true);
2155 sym[sym_idx].GetAddress() = so_addr;
2156 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
2157 ++sym_idx;
2158 }
2159 }
2160 }
2161 }
2162 }
2163 }
2164 }
2165 }
2166 return symtab->GetNumSymbols();
Chris Lattner24943d22010-06-08 16:52:24 +00002167 }
2168 return 0;
2169}
2170
2171
2172void
2173ObjectFileMachO::Dump (Stream *s)
2174{
2175 lldb_private::Mutex::Locker locker(m_mutex);
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00002176 s->Printf("%p: ", this);
Chris Lattner24943d22010-06-08 16:52:24 +00002177 s->Indent();
Greg Clayton1674b122010-07-21 22:12:05 +00002178 if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped)
Chris Lattner24943d22010-06-08 16:52:24 +00002179 s->PutCString("ObjectFileMachO64");
2180 else
2181 s->PutCString("ObjectFileMachO32");
2182
Greg Claytoncf015052010-06-11 03:25:34 +00002183 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +00002184
Greg Clayton940b1032011-02-23 00:35:02 +00002185 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner24943d22010-06-08 16:52:24 +00002186
2187 if (m_sections_ap.get())
Greg Clayton58e844b2010-12-08 05:08:21 +00002188 m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00002189
2190 if (m_symtab_ap.get())
Greg Clayton8d3802d2010-10-08 04:20:14 +00002191 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
Chris Lattner24943d22010-06-08 16:52:24 +00002192}
2193
2194
2195bool
Greg Clayton0467c782011-02-04 18:53:10 +00002196ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner24943d22010-06-08 16:52:24 +00002197{
2198 lldb_private::Mutex::Locker locker(m_mutex);
2199 struct uuid_command load_cmd;
2200 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2201 uint32_t i;
2202 for (i=0; i<m_header.ncmds; ++i)
2203 {
2204 const uint32_t cmd_offset = offset;
2205 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2206 break;
2207
Greg Clayton1674b122010-07-21 22:12:05 +00002208 if (load_cmd.cmd == LoadCommandUUID)
Chris Lattner24943d22010-06-08 16:52:24 +00002209 {
2210 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
2211 if (uuid_bytes)
2212 {
2213 uuid->SetBytes (uuid_bytes);
2214 return true;
2215 }
2216 return false;
2217 }
2218 offset = cmd_offset + load_cmd.cmdsize;
2219 }
2220 return false;
2221}
2222
2223
2224uint32_t
2225ObjectFileMachO::GetDependentModules (FileSpecList& files)
2226{
2227 lldb_private::Mutex::Locker locker(m_mutex);
2228 struct load_command load_cmd;
2229 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2230 uint32_t count = 0;
Greg Clayton54b38412011-05-24 23:06:02 +00002231 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 +00002232 uint32_t i;
2233 for (i=0; i<m_header.ncmds; ++i)
2234 {
2235 const uint32_t cmd_offset = offset;
2236 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2237 break;
2238
2239 switch (load_cmd.cmd)
2240 {
Greg Clayton1674b122010-07-21 22:12:05 +00002241 case LoadCommandDylibLoad:
2242 case LoadCommandDylibLoadWeak:
2243 case LoadCommandDylibReexport:
2244 case LoadCommandDynamicLinkerLoad:
2245 case LoadCommandFixedVMShlibLoad:
Greg Clayton08a73202010-10-09 00:48:53 +00002246 case LoadCommandDylibLoadUpward:
Chris Lattner24943d22010-06-08 16:52:24 +00002247 {
2248 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2249 const char *path = m_data.PeekCStr(name_offset);
2250 // Skip any path that starts with '@' since these are usually:
2251 // @executable_path/.../file
2252 // @rpath/.../file
2253 if (path && path[0] != '@')
2254 {
Greg Clayton54b38412011-05-24 23:06:02 +00002255 FileSpec file_spec(path, resolve_path);
Chris Lattner24943d22010-06-08 16:52:24 +00002256 if (files.AppendIfUnique(file_spec))
2257 count++;
2258 }
2259 }
2260 break;
2261
2262 default:
2263 break;
2264 }
2265 offset = cmd_offset + load_cmd.cmdsize;
2266 }
2267 return count;
2268}
2269
Jim Ingham28775942011-03-07 23:44:08 +00002270lldb_private::Address
2271ObjectFileMachO::GetEntryPointAddress ()
2272{
2273 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
2274 // is initialized to an invalid address, so we can just return that.
2275 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
2276
2277 if (!IsExecutable() || m_entry_point_address.IsValid())
2278 return m_entry_point_address;
2279
2280 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
2281 // /usr/include/mach-o.h, but it is basically:
2282 //
2283 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
2284 // uint32_t count - this is the count of longs in the thread state data
2285 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
2286 // <repeat this trio>
2287 //
2288 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
2289 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
2290 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
2291 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
2292 //
2293 // For now we hard-code the offsets and flavors we need:
2294 //
2295 //
2296
2297 lldb_private::Mutex::Locker locker(m_mutex);
2298 struct load_command load_cmd;
2299 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2300 uint32_t i;
2301 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
2302 bool done = false;
2303
2304 for (i=0; i<m_header.ncmds; ++i)
2305 {
2306 const uint32_t cmd_offset = offset;
2307 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2308 break;
2309
2310 switch (load_cmd.cmd)
2311 {
2312 case LoadCommandUnixThread:
2313 case LoadCommandThread:
2314 {
2315 while (offset < cmd_offset + load_cmd.cmdsize)
2316 {
2317 uint32_t flavor = m_data.GetU32(&offset);
2318 uint32_t count = m_data.GetU32(&offset);
2319 if (count == 0)
2320 {
2321 // We've gotten off somehow, log and exit;
2322 return m_entry_point_address;
2323 }
2324
2325 switch (m_header.cputype)
2326 {
2327 case llvm::MachO::CPUTypeARM:
2328 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
2329 {
2330 offset += 60; // This is the offset of pc in the GPR thread state data structure.
2331 start_address = m_data.GetU32(&offset);
2332 done = true;
2333 }
2334 break;
2335 case llvm::MachO::CPUTypeI386:
2336 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
2337 {
2338 offset += 40; // This is the offset of eip in the GPR thread state data structure.
2339 start_address = m_data.GetU32(&offset);
2340 done = true;
2341 }
2342 break;
2343 case llvm::MachO::CPUTypeX86_64:
2344 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
2345 {
2346 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
2347 start_address = m_data.GetU64(&offset);
2348 done = true;
2349 }
2350 break;
2351 default:
2352 return m_entry_point_address;
2353 }
2354 // Haven't found the GPR flavor yet, skip over the data for this flavor:
2355 if (done)
2356 break;
2357 offset += count * 4;
2358 }
2359 }
2360 break;
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002361 case LoadCommandMain:
2362 {
2363 ConstString text_segment_name ("__TEXT");
2364 uint64_t entryoffset = m_data.GetU64(&offset);
2365 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2366 if (text_segment_sp)
2367 {
2368 done = true;
2369 start_address = text_segment_sp->GetFileAddress() + entryoffset;
2370 }
2371 }
Jim Ingham28775942011-03-07 23:44:08 +00002372
2373 default:
2374 break;
2375 }
2376 if (done)
2377 break;
2378
2379 // Go to the next load command:
2380 offset = cmd_offset + load_cmd.cmdsize;
2381 }
2382
2383 if (start_address != LLDB_INVALID_ADDRESS)
2384 {
2385 // We got the start address from the load commands, so now resolve that address in the sections
2386 // of this ObjectFile:
2387 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
2388 {
2389 m_entry_point_address.Clear();
2390 }
2391 }
2392 else
2393 {
2394 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
2395 // "start" symbol in the main executable.
2396
Greg Clayton3508c382012-02-24 01:59:29 +00002397 ModuleSP module_sp (GetModule());
Jim Ingham28775942011-03-07 23:44:08 +00002398
Greg Clayton3508c382012-02-24 01:59:29 +00002399 if (module_sp)
2400 {
2401 SymbolContextList contexts;
2402 SymbolContext context;
2403 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
2404 {
2405 if (contexts.GetContextAtIndex(0, context))
Greg Clayton0c31d3d2012-03-07 21:03:09 +00002406 m_entry_point_address = context.symbol->GetAddress();
Greg Clayton3508c382012-02-24 01:59:29 +00002407 }
2408 }
Jim Ingham28775942011-03-07 23:44:08 +00002409 }
2410
2411 return m_entry_point_address;
2412
2413}
2414
Greg Claytonb5a8f142012-02-05 02:38:54 +00002415lldb_private::Address
2416ObjectFileMachO::GetHeaderAddress ()
2417{
2418 lldb_private::Address header_addr;
2419 SectionList *section_list = GetSectionList();
2420 if (section_list)
2421 {
2422 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
2423 if (text_segment_sp)
2424 {
Greg Clayton3508c382012-02-24 01:59:29 +00002425 header_addr.SetSection (text_segment_sp);
Greg Claytonb5a8f142012-02-05 02:38:54 +00002426 header_addr.SetOffset (0);
2427 }
2428 }
2429 return header_addr;
2430}
2431
Greg Clayton46c9a352012-02-09 06:16:32 +00002432uint32_t
2433ObjectFileMachO::GetNumThreadContexts ()
2434{
2435 lldb_private::Mutex::Locker locker(m_mutex);
2436 if (!m_thread_context_offsets_valid)
2437 {
2438 m_thread_context_offsets_valid = true;
2439 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2440 FileRangeArray::Entry file_range;
2441 thread_command thread_cmd;
2442 for (uint32_t i=0; i<m_header.ncmds; ++i)
2443 {
2444 const uint32_t cmd_offset = offset;
2445 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
2446 break;
2447
2448 if (thread_cmd.cmd == LoadCommandThread)
2449 {
2450 file_range.SetRangeBase (offset);
2451 file_range.SetByteSize (thread_cmd.cmdsize - 8);
2452 m_thread_context_offsets.Append (file_range);
2453 }
2454 offset = cmd_offset + thread_cmd.cmdsize;
2455 }
2456 }
2457 return m_thread_context_offsets.GetSize();
2458}
2459
2460lldb::RegisterContextSP
2461ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
2462{
2463 lldb_private::Mutex::Locker locker(m_mutex);
2464 if (!m_thread_context_offsets_valid)
2465 GetNumThreadContexts ();
2466
2467 lldb::RegisterContextSP reg_ctx_sp;
2468 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
Greg Clayton9ce95382012-02-13 23:10:39 +00002469
2470 DataExtractor data (m_data,
2471 thread_context_file_range->GetRangeBase(),
2472 thread_context_file_range->GetByteSize());
2473
2474 switch (m_header.cputype)
Greg Clayton46c9a352012-02-09 06:16:32 +00002475 {
Greg Clayton9ce95382012-02-13 23:10:39 +00002476 case llvm::MachO::CPUTypeARM:
2477 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
2478 break;
2479
2480 case llvm::MachO::CPUTypeI386:
2481 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
2482 break;
2483
2484 case llvm::MachO::CPUTypeX86_64:
2485 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
2486 break;
Greg Clayton46c9a352012-02-09 06:16:32 +00002487 }
2488 return reg_ctx_sp;
2489}
2490
Greg Claytonb5a8f142012-02-05 02:38:54 +00002491
Greg Claytonca319972011-07-09 00:41:34 +00002492ObjectFile::Type
2493ObjectFileMachO::CalculateType()
2494{
2495 switch (m_header.filetype)
2496 {
2497 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2498 if (GetAddressByteSize () == 4)
2499 {
2500 // 32 bit kexts are just object files, but they do have a valid
2501 // UUID load command.
2502 UUID uuid;
2503 if (GetUUID(&uuid))
2504 {
2505 // this checking for the UUID load command is not enough
2506 // we could eventually look for the symbol named
2507 // "OSKextGetCurrentIdentifier" as this is required of kexts
2508 if (m_strata == eStrataInvalid)
2509 m_strata = eStrataKernel;
2510 return eTypeSharedLibrary;
2511 }
2512 }
2513 return eTypeObjectFile;
2514
2515 case HeaderFileTypeExecutable: return eTypeExecutable; // 0x2u MH_EXECUTE
2516 case HeaderFileTypeFixedVMShlib: return eTypeSharedLibrary; // 0x3u MH_FVMLIB
2517 case HeaderFileTypeCore: return eTypeCoreFile; // 0x4u MH_CORE
2518 case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary; // 0x5u MH_PRELOAD
2519 case HeaderFileTypeDynamicShlib: return eTypeSharedLibrary; // 0x6u MH_DYLIB
2520 case HeaderFileTypeDynamicLinkEditor: return eTypeDynamicLinker; // 0x7u MH_DYLINKER
2521 case HeaderFileTypeBundle: return eTypeSharedLibrary; // 0x8u MH_BUNDLE
2522 case HeaderFileTypeDynamicShlibStub: return eTypeStubLibrary; // 0x9u MH_DYLIB_STUB
2523 case HeaderFileTypeDSYM: return eTypeDebugInfo; // 0xAu MH_DSYM
2524 case HeaderFileTypeKextBundle: return eTypeSharedLibrary; // 0xBu MH_KEXT_BUNDLE
2525 default:
2526 break;
2527 }
2528 return eTypeUnknown;
2529}
2530
2531ObjectFile::Strata
2532ObjectFileMachO::CalculateStrata()
2533{
2534 switch (m_header.filetype)
2535 {
2536 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2537 {
2538 // 32 bit kexts are just object files, but they do have a valid
2539 // UUID load command.
2540 UUID uuid;
2541 if (GetUUID(&uuid))
2542 {
2543 // this checking for the UUID load command is not enough
2544 // we could eventually look for the symbol named
2545 // "OSKextGetCurrentIdentifier" as this is required of kexts
2546 if (m_type == eTypeInvalid)
2547 m_type = eTypeSharedLibrary;
2548
2549 return eStrataKernel;
2550 }
2551 }
2552 return eStrataUnknown;
2553
2554 case HeaderFileTypeExecutable: // 0x2u MH_EXECUTE
2555 // Check for the MH_DYLDLINK bit in the flags
2556 if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
Sean Callananac725af2012-02-10 20:22:35 +00002557 {
Greg Claytonca319972011-07-09 00:41:34 +00002558 return eStrataUser;
Sean Callananac725af2012-02-10 20:22:35 +00002559 }
2560 else
2561 {
2562 SectionList *section_list = GetSectionList();
2563 if (section_list)
2564 {
2565 static ConstString g_kld_section_name ("__KLD");
2566 if (section_list->FindSectionByName(g_kld_section_name))
2567 return eStrataKernel;
2568 }
2569 }
2570 return eStrataRawImage;
Greg Claytonca319972011-07-09 00:41:34 +00002571
2572 case HeaderFileTypeFixedVMShlib: return eStrataUser; // 0x3u MH_FVMLIB
2573 case HeaderFileTypeCore: return eStrataUnknown; // 0x4u MH_CORE
Sean Callananac725af2012-02-10 20:22:35 +00002574 case HeaderFileTypePreloadedExecutable: return eStrataRawImage; // 0x5u MH_PRELOAD
Greg Claytonca319972011-07-09 00:41:34 +00002575 case HeaderFileTypeDynamicShlib: return eStrataUser; // 0x6u MH_DYLIB
2576 case HeaderFileTypeDynamicLinkEditor: return eStrataUser; // 0x7u MH_DYLINKER
2577 case HeaderFileTypeBundle: return eStrataUser; // 0x8u MH_BUNDLE
2578 case HeaderFileTypeDynamicShlibStub: return eStrataUser; // 0x9u MH_DYLIB_STUB
2579 case HeaderFileTypeDSYM: return eStrataUnknown; // 0xAu MH_DSYM
2580 case HeaderFileTypeKextBundle: return eStrataKernel; // 0xBu MH_KEXT_BUNDLE
2581 default:
2582 break;
2583 }
2584 return eStrataUnknown;
2585}
2586
2587
Greg Clayton49f4bf22012-02-22 19:41:02 +00002588uint32_t
2589ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
2590{
2591 lldb_private::Mutex::Locker locker(m_mutex);
2592 struct dylib_command load_cmd;
2593 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2594 uint32_t version_cmd = 0;
2595 uint64_t version = 0;
2596 uint32_t i;
2597 for (i=0; i<m_header.ncmds; ++i)
2598 {
2599 const uint32_t cmd_offset = offset;
2600 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2601 break;
2602
2603 if (load_cmd.cmd == LoadCommandDylibIdent)
2604 {
2605 if (version_cmd == 0)
2606 {
2607 version_cmd = load_cmd.cmd;
2608 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
2609 break;
2610 version = load_cmd.dylib.current_version;
2611 }
2612 break; // Break for now unless there is another more complete version
2613 // number load command in the future.
2614 }
2615 offset = cmd_offset + load_cmd.cmdsize;
2616 }
2617
2618 if (version_cmd == LoadCommandDylibIdent)
2619 {
2620 if (versions != NULL && num_versions > 0)
2621 {
2622 if (num_versions > 0)
2623 versions[0] = (version & 0xFFFF0000ull) >> 16;
2624 if (num_versions > 1)
2625 versions[1] = (version & 0x0000FF00ull) >> 8;
2626 if (num_versions > 2)
2627 versions[2] = (version & 0x000000FFull);
2628 // Fill in an remaining version numbers with invalid values
2629 for (i=3; i<num_versions; ++i)
2630 versions[i] = UINT32_MAX;
2631 }
2632 // The LC_ID_DYLIB load command has a version with 3 version numbers
2633 // in it, so always return 3
2634 return 3;
2635 }
2636 return false;
2637}
2638
Chris Lattner24943d22010-06-08 16:52:24 +00002639bool
Greg Clayton395fc332011-02-15 21:59:32 +00002640ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +00002641{
2642 lldb_private::Mutex::Locker locker(m_mutex);
Greg Claytonb3448432011-03-24 21:19:54 +00002643 arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002644
2645 // Files with type MH_PRELOAD are currently used in cases where the image
2646 // debugs at the addresses in the file itself. Below we set the OS to
2647 // unknown to make sure we use the DynamicLoaderStatic()...
2648 if (m_header.filetype == HeaderFileTypePreloadedExecutable)
2649 {
2650 arch.GetTriple().setOS (llvm::Triple::UnknownOS);
2651 }
2652
Greg Clayton395fc332011-02-15 21:59:32 +00002653 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00002654}
2655
2656
2657//------------------------------------------------------------------
2658// PluginInterface protocol
2659//------------------------------------------------------------------
2660const char *
2661ObjectFileMachO::GetPluginName()
2662{
2663 return "ObjectFileMachO";
2664}
2665
2666const char *
2667ObjectFileMachO::GetShortPluginName()
2668{
2669 return GetPluginNameStatic();
2670}
2671
2672uint32_t
2673ObjectFileMachO::GetPluginVersion()
2674{
2675 return 1;
2676}
2677