blob: ae08a632024ff8ffea48d21580c083018eb3e48c [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_sections_ap(),
Jim Ingham28775942011-03-07 23:44:08 +0000468 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000469 m_mach_segments(),
470 m_mach_sections(),
471 m_entry_point_address(),
472 m_thread_context_offsets(),
473 m_thread_context_offsets_valid(false)
Chris Lattner24943d22010-06-08 16:52:24 +0000474{
Greg Claytonddff7cc2011-02-04 21:13:05 +0000475 ::memset (&m_header, 0, sizeof(m_header));
476 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner24943d22010-06-08 16:52:24 +0000477}
478
Greg Clayton3508c382012-02-24 01:59:29 +0000479ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000480 lldb::DataBufferSP& header_data_sp,
481 const lldb::ProcessSP &process_sp,
482 lldb::addr_t header_addr) :
Greg Clayton3508c382012-02-24 01:59:29 +0000483 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000484 m_sections_ap(),
485 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000486 m_mach_segments(),
487 m_mach_sections(),
488 m_entry_point_address(),
489 m_thread_context_offsets(),
490 m_thread_context_offsets_valid(false)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000491{
492 ::memset (&m_header, 0, sizeof(m_header));
493 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
494}
Chris Lattner24943d22010-06-08 16:52:24 +0000495
496ObjectFileMachO::~ObjectFileMachO()
497{
498}
499
500
501bool
502ObjectFileMachO::ParseHeader ()
503{
Greg Clayton9482f052012-03-13 23:14:29 +0000504 ModuleSP module_sp(GetModule());
505 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000506 {
Greg Clayton9482f052012-03-13 23:14:29 +0000507 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
508 bool can_parse = false;
509 uint32_t offset = 0;
Greg Claytoncd548032011-02-01 01:31:41 +0000510 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Greg Clayton9482f052012-03-13 23:14:29 +0000511 // Leave magic in the original byte order
512 m_header.magic = m_data.GetU32(&offset);
513 switch (m_header.magic)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000514 {
Greg Clayton9482f052012-03-13 23:14:29 +0000515 case HeaderMagic32:
516 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
517 m_data.SetAddressByteSize(4);
518 can_parse = true;
519 break;
520
521 case HeaderMagic64:
522 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
523 m_data.SetAddressByteSize(8);
524 can_parse = true;
525 break;
526
527 case HeaderMagic32Swapped:
528 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
529 m_data.SetAddressByteSize(4);
530 can_parse = true;
531 break;
532
533 case HeaderMagic64Swapped:
534 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
535 m_data.SetAddressByteSize(8);
536 can_parse = true;
537 break;
538
539 default:
540 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +0000541 }
Greg Clayton9482f052012-03-13 23:14:29 +0000542
543 if (can_parse)
544 {
545 m_data.GetU32(&offset, &m_header.cputype, 6);
546
547 ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
548
549 if (SetModulesArchitecture (mach_arch))
550 {
551 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
552 if (m_data.GetByteSize() < header_and_lc_size)
553 {
554 DataBufferSP data_sp;
555 ProcessSP process_sp (m_process_wp.lock());
556 if (process_sp)
557 {
558 data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
559 }
560 else
561 {
562 // Read in all only the load command data from the file on disk
563 data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
564 if (data_sp->GetByteSize() != header_and_lc_size)
565 return false;
566 }
567 if (data_sp)
568 m_data.SetData (data_sp);
569 }
570 }
571 return true;
572 }
573 else
574 {
575 memset(&m_header, 0, sizeof(struct mach_header));
576 }
Chris Lattner24943d22010-06-08 16:52:24 +0000577 }
578 return false;
579}
580
581
582ByteOrder
583ObjectFileMachO::GetByteOrder () const
584{
Chris Lattner24943d22010-06-08 16:52:24 +0000585 return m_data.GetByteOrder ();
586}
587
Jim Ingham7508e732010-08-09 23:31:02 +0000588bool
589ObjectFileMachO::IsExecutable() const
590{
591 return m_header.filetype == HeaderFileTypeExecutable;
592}
Chris Lattner24943d22010-06-08 16:52:24 +0000593
594size_t
595ObjectFileMachO::GetAddressByteSize () const
596{
Chris Lattner24943d22010-06-08 16:52:24 +0000597 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 Clayton9482f052012-03-13 23:14:29 +0000713 ModuleSP module_sp(GetModule());
714 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000715 {
Greg Clayton9482f052012-03-13 23:14:29 +0000716 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
717 if (m_symtab_ap.get() == NULL)
718 {
719 m_symtab_ap.reset(new Symtab(this));
720 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
721 ParseSymtab (true);
722 m_symtab_ap->Finalize ();
723 }
Chris Lattner24943d22010-06-08 16:52:24 +0000724 }
725 return m_symtab_ap.get();
726}
727
728
729SectionList *
730ObjectFileMachO::GetSectionList()
731{
Greg Clayton9482f052012-03-13 23:14:29 +0000732 ModuleSP module_sp(GetModule());
733 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000734 {
Greg Clayton9482f052012-03-13 23:14:29 +0000735 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
736 if (m_sections_ap.get() == NULL)
737 {
738 m_sections_ap.reset(new SectionList());
739 ParseSections();
740 }
Chris Lattner24943d22010-06-08 16:52:24 +0000741 }
742 return m_sections_ap.get();
743}
744
745
746size_t
747ObjectFileMachO::ParseSections ()
748{
749 lldb::user_id_t segID = 0;
750 lldb::user_id_t sectID = 0;
751 struct segment_command_64 load_cmd;
752 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
753 uint32_t i;
Greg Clayton46c9a352012-02-09 06:16:32 +0000754 const bool is_core = GetType() == eTypeCoreFile;
Chris Lattner24943d22010-06-08 16:52:24 +0000755 //bool dump_sections = false;
Greg Clayton3508c382012-02-24 01:59:29 +0000756 ModuleSP module_sp (GetModule());
Chris Lattner24943d22010-06-08 16:52:24 +0000757 for (i=0; i<m_header.ncmds; ++i)
758 {
759 const uint32_t load_cmd_offset = offset;
760 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
761 break;
762
Greg Clayton1674b122010-07-21 22:12:05 +0000763 if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
Chris Lattner24943d22010-06-08 16:52:24 +0000764 {
765 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
766 {
767 load_cmd.vmaddr = m_data.GetAddress(&offset);
768 load_cmd.vmsize = m_data.GetAddress(&offset);
769 load_cmd.fileoff = m_data.GetAddress(&offset);
770 load_cmd.filesize = m_data.GetAddress(&offset);
771 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
772 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000773
774 const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
775
Chris Lattner24943d22010-06-08 16:52:24 +0000776 // Keep a list of mach segments around in case we need to
777 // get at data that isn't stored in the abstracted Sections.
778 m_mach_segments.push_back (load_cmd);
779
780 ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
781 // Use a segment ID of the segment index shifted left by 8 so they
782 // never conflict with any of the sections.
783 SectionSP segment_sp;
Greg Clayton46c9a352012-02-09 06:16:32 +0000784 if (segment_name || is_core)
Chris Lattner24943d22010-06-08 16:52:24 +0000785 {
Greg Clayton3508c382012-02-24 01:59:29 +0000786 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
Chris Lattner24943d22010-06-08 16:52:24 +0000787 ++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
788 segment_name, // Name of this section
789 eSectionTypeContainer, // This section is a container of other sections.
790 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
791 load_cmd.vmsize, // VM size in bytes of this section
792 load_cmd.fileoff, // Offset to the data for this section in the file
793 load_cmd.filesize, // Size in bytes of this section as found in the the file
794 load_cmd.flags)); // Flags for this section
795
Greg Clayton68ca8232011-01-25 02:58:48 +0000796 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000797 m_sections_ap->AddSection(segment_sp);
798 }
799
800 struct section_64 sect64;
Greg Claytonddff7cc2011-02-04 21:13:05 +0000801 ::memset (&sect64, 0, sizeof(sect64));
Chris Lattner24943d22010-06-08 16:52:24 +0000802 // Push a section into our mach sections for the section at
Greg Clayton6af4fad2010-10-06 01:26:32 +0000803 // index zero (NListSectionNoSection) if we don't have any
804 // mach sections yet...
805 if (m_mach_sections.empty())
806 m_mach_sections.push_back(sect64);
Chris Lattner24943d22010-06-08 16:52:24 +0000807 uint32_t segment_sect_idx;
808 const lldb::user_id_t first_segment_sectID = sectID + 1;
809
810
Greg Clayton1674b122010-07-21 22:12:05 +0000811 const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
Chris Lattner24943d22010-06-08 16:52:24 +0000812 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
813 {
814 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
815 break;
816 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
817 break;
818 sect64.addr = m_data.GetAddress(&offset);
819 sect64.size = m_data.GetAddress(&offset);
820
821 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
822 break;
823
824 // Keep a list of mach sections around in case we need to
825 // get at data that isn't stored in the abstracted Sections.
826 m_mach_sections.push_back (sect64);
827
828 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
829 if (!segment_name)
830 {
831 // We have a segment with no name so we need to conjure up
832 // segments that correspond to the section's segname if there
833 // isn't already such a section. If there is such a section,
834 // we resize the section so that it spans all sections.
835 // We also mark these sections as fake so address matches don't
836 // hit if they land in the gaps between the child sections.
837 segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
838 segment_sp = m_sections_ap->FindSectionByName (segment_name);
839 if (segment_sp.get())
840 {
841 Section *segment = segment_sp.get();
842 // Grow the section size as needed.
843 const lldb::addr_t sect64_min_addr = sect64.addr;
844 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
845 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
846 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
847 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
848 if (sect64_min_addr >= curr_seg_min_addr)
849 {
850 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
851 // Only grow the section size if needed
852 if (new_seg_byte_size > curr_seg_byte_size)
853 segment->SetByteSize (new_seg_byte_size);
854 }
855 else
856 {
857 // We need to change the base address of the segment and
858 // adjust the child section offsets for all existing children.
859 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
860 segment->Slide(slide_amount, false);
861 segment->GetChildren().Slide (-slide_amount, false);
862 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
863 }
Greg Clayton661825b2010-06-28 23:51:11 +0000864
865 // Grow the section size as needed.
866 if (sect64.offset)
867 {
868 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
869 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
870
871 const lldb::addr_t section_min_file_offset = sect64.offset;
872 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
873 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
874 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
875 segment->SetFileOffset (new_file_offset);
876 segment->SetFileSize (new_file_size);
877 }
Chris Lattner24943d22010-06-08 16:52:24 +0000878 }
879 else
880 {
881 // Create a fake section for the section's named segment
Greg Clayton3508c382012-02-24 01:59:29 +0000882 segment_sp.reset(new Section (segment_sp, // Parent section
883 module_sp, // Module to which this section belongs
884 ++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
885 segment_name, // Name of this section
886 eSectionTypeContainer, // This section is a container of other sections.
887 sect64.addr, // File VM address == addresses as they are found in the object file
888 sect64.size, // VM size in bytes of this section
889 sect64.offset, // Offset to the data for this section in the file
890 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
891 load_cmd.flags)); // Flags for this section
Chris Lattner24943d22010-06-08 16:52:24 +0000892 segment_sp->SetIsFake(true);
893 m_sections_ap->AddSection(segment_sp);
Greg Clayton68ca8232011-01-25 02:58:48 +0000894 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000895 }
896 }
897 assert (segment_sp.get());
898
Greg Clayton1674b122010-07-21 22:12:05 +0000899 uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
Chris Lattner24943d22010-06-08 16:52:24 +0000900 static ConstString g_sect_name_objc_data ("__objc_data");
901 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
902 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
903 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
904 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
905 static ConstString g_sect_name_objc_const ("__objc_const");
906 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
907 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000908
909 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
910 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
911 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
912 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
913 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
914 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
915 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
916 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
917 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
918 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
919 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
Greg Claytonf6e3de22011-09-28 17:06:40 +0000920 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
921 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
Greg Clayton00db2152011-10-04 22:41:51 +0000922 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
Greg Clayton24a6bd92011-10-27 17:55:14 +0000923 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000924 static ConstString g_sect_name_eh_frame ("__eh_frame");
Greg Clayton3fed8b92010-10-08 00:21:05 +0000925 static ConstString g_sect_name_DATA ("__DATA");
926 static ConstString g_sect_name_TEXT ("__TEXT");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000927
Chris Lattner24943d22010-06-08 16:52:24 +0000928 SectionType sect_type = eSectionTypeOther;
929
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000930 if (section_name == g_sect_name_dwarf_debug_abbrev)
931 sect_type = eSectionTypeDWARFDebugAbbrev;
932 else if (section_name == g_sect_name_dwarf_debug_aranges)
933 sect_type = eSectionTypeDWARFDebugAranges;
934 else if (section_name == g_sect_name_dwarf_debug_frame)
935 sect_type = eSectionTypeDWARFDebugFrame;
936 else if (section_name == g_sect_name_dwarf_debug_info)
937 sect_type = eSectionTypeDWARFDebugInfo;
938 else if (section_name == g_sect_name_dwarf_debug_line)
939 sect_type = eSectionTypeDWARFDebugLine;
940 else if (section_name == g_sect_name_dwarf_debug_loc)
941 sect_type = eSectionTypeDWARFDebugLoc;
942 else if (section_name == g_sect_name_dwarf_debug_macinfo)
943 sect_type = eSectionTypeDWARFDebugMacInfo;
944 else if (section_name == g_sect_name_dwarf_debug_pubnames)
945 sect_type = eSectionTypeDWARFDebugPubNames;
946 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
947 sect_type = eSectionTypeDWARFDebugPubTypes;
948 else if (section_name == g_sect_name_dwarf_debug_ranges)
949 sect_type = eSectionTypeDWARFDebugRanges;
950 else if (section_name == g_sect_name_dwarf_debug_str)
951 sect_type = eSectionTypeDWARFDebugStr;
Greg Claytonf6e3de22011-09-28 17:06:40 +0000952 else if (section_name == g_sect_name_dwarf_apple_names)
953 sect_type = eSectionTypeDWARFAppleNames;
954 else if (section_name == g_sect_name_dwarf_apple_types)
955 sect_type = eSectionTypeDWARFAppleTypes;
Greg Clayton00db2152011-10-04 22:41:51 +0000956 else if (section_name == g_sect_name_dwarf_apple_namespaces)
957 sect_type = eSectionTypeDWARFAppleNamespaces;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000958 else if (section_name == g_sect_name_dwarf_apple_objc)
959 sect_type = eSectionTypeDWARFAppleObjC;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000960 else if (section_name == g_sect_name_objc_selrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000961 sect_type = eSectionTypeDataCStringPointers;
Chris Lattner24943d22010-06-08 16:52:24 +0000962 else if (section_name == g_sect_name_objc_msgrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000963 sect_type = eSectionTypeDataObjCMessageRefs;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000964 else if (section_name == g_sect_name_eh_frame)
965 sect_type = eSectionTypeEHFrame;
966 else if (section_name == g_sect_name_cfstring)
967 sect_type = eSectionTypeDataObjCCFStrings;
Chris Lattner24943d22010-06-08 16:52:24 +0000968 else if (section_name == g_sect_name_objc_data ||
969 section_name == g_sect_name_objc_classrefs ||
970 section_name == g_sect_name_objc_superrefs ||
971 section_name == g_sect_name_objc_const ||
972 section_name == g_sect_name_objc_classlist)
973 {
974 sect_type = eSectionTypeDataPointers;
975 }
Chris Lattner24943d22010-06-08 16:52:24 +0000976
977 if (sect_type == eSectionTypeOther)
978 {
979 switch (mach_sect_type)
980 {
981 // TODO: categorize sections by other flags for regular sections
Greg Clayton3fed8b92010-10-08 00:21:05 +0000982 case SectionTypeRegular:
983 if (segment_sp->GetName() == g_sect_name_TEXT)
984 sect_type = eSectionTypeCode;
985 else if (segment_sp->GetName() == g_sect_name_DATA)
986 sect_type = eSectionTypeData;
987 else
988 sect_type = eSectionTypeOther;
989 break;
Greg Clayton1674b122010-07-21 22:12:05 +0000990 case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
991 case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
992 case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
993 case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
994 case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
995 case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
996 case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
997 case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
998 case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
999 case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1000 case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
1001 case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
1002 case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1003 case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1004 case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
1005 case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
Chris Lattner24943d22010-06-08 16:52:24 +00001006 default: break;
1007 }
1008 }
1009
Greg Clayton3508c382012-02-24 01:59:29 +00001010 SectionSP section_sp(new Section (segment_sp,
1011 module_sp,
1012 ++sectID,
1013 section_name,
1014 sect_type,
1015 sect64.addr - segment_sp->GetFileAddress(),
1016 sect64.size,
1017 sect64.offset,
1018 sect64.offset == 0 ? 0 : sect64.size,
1019 sect64.flags));
Greg Clayton68ca8232011-01-25 02:58:48 +00001020 // Set the section to be encrypted to match the segment
1021 section_sp->SetIsEncrypted (segment_is_encrypted);
1022
Chris Lattner24943d22010-06-08 16:52:24 +00001023 segment_sp->GetChildren().AddSection(section_sp);
1024
1025 if (segment_sp->IsFake())
1026 {
1027 segment_sp.reset();
1028 segment_name.Clear();
1029 }
1030 }
Greg Clayton0fa51242011-07-19 03:57:15 +00001031 if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
Chris Lattner24943d22010-06-08 16:52:24 +00001032 {
1033 if (first_segment_sectID <= sectID)
1034 {
1035 lldb::user_id_t sect_uid;
1036 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
1037 {
1038 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1039 SectionSP next_section_sp;
1040 if (sect_uid + 1 <= sectID)
1041 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1042
1043 if (curr_section_sp.get())
1044 {
1045 if (curr_section_sp->GetByteSize() == 0)
1046 {
1047 if (next_section_sp.get() != NULL)
1048 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1049 else
1050 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1051 }
1052 }
1053 }
1054 }
1055 }
1056 }
1057 }
1058 }
Greg Clayton1674b122010-07-21 22:12:05 +00001059 else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
Chris Lattner24943d22010-06-08 16:52:24 +00001060 {
1061 m_dysymtab.cmd = load_cmd.cmd;
1062 m_dysymtab.cmdsize = load_cmd.cmdsize;
1063 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1064 }
1065
1066 offset = load_cmd_offset + load_cmd.cmdsize;
1067 }
1068// if (dump_sections)
1069// {
1070// StreamFile s(stdout);
1071// m_sections_ap->Dump(&s, true);
1072// }
1073 return sectID; // Return the number of sections we registered with the module
1074}
1075
1076class MachSymtabSectionInfo
1077{
1078public:
1079
1080 MachSymtabSectionInfo (SectionList *section_list) :
1081 m_section_list (section_list),
1082 m_section_infos()
1083 {
1084 // Get the number of sections down to a depth of 1 to include
1085 // all segments and their sections, but no other sections that
1086 // may be added for debug map or
1087 m_section_infos.resize(section_list->GetNumSections(1));
1088 }
1089
1090
Greg Clayton3508c382012-02-24 01:59:29 +00001091 SectionSP
Chris Lattner24943d22010-06-08 16:52:24 +00001092 GetSection (uint8_t n_sect, addr_t file_addr)
1093 {
1094 if (n_sect == 0)
Greg Clayton3508c382012-02-24 01:59:29 +00001095 return SectionSP();
Chris Lattner24943d22010-06-08 16:52:24 +00001096 if (n_sect < m_section_infos.size())
1097 {
Greg Clayton3508c382012-02-24 01:59:29 +00001098 if (!m_section_infos[n_sect].section_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001099 {
Greg Clayton3508c382012-02-24 01:59:29 +00001100 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1101 m_section_infos[n_sect].section_sp = section_sp;
1102 if (section_sp != NULL)
Greg Clayton5638d2c2011-07-10 17:32:33 +00001103 {
Greg Clayton3508c382012-02-24 01:59:29 +00001104 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1105 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Clayton5638d2c2011-07-10 17:32:33 +00001106 }
1107 else
1108 {
Greg Claytondf6dc882012-01-05 03:57:59 +00001109 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Clayton5638d2c2011-07-10 17:32:33 +00001110 }
Chris Lattner24943d22010-06-08 16:52:24 +00001111 }
1112 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton811b9c52011-08-26 20:01:35 +00001113 {
1114 // Symbol is in section.
Greg Clayton3508c382012-02-24 01:59:29 +00001115 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001116 }
1117 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1118 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1119 {
1120 // Symbol is in section with zero size, but has the same start
1121 // address as the section. This can happen with linker symbols
1122 // (symbols that start with the letter 'l' or 'L'.
Greg Clayton3508c382012-02-24 01:59:29 +00001123 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001124 }
Chris Lattner24943d22010-06-08 16:52:24 +00001125 }
Greg Clayton3508c382012-02-24 01:59:29 +00001126 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner24943d22010-06-08 16:52:24 +00001127 }
1128
1129protected:
1130 struct SectionInfo
1131 {
1132 SectionInfo () :
1133 vm_range(),
Greg Clayton3508c382012-02-24 01:59:29 +00001134 section_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +00001135 {
1136 }
1137
1138 VMRange vm_range;
Greg Clayton3508c382012-02-24 01:59:29 +00001139 SectionSP section_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001140 };
1141 SectionList *m_section_list;
1142 std::vector<SectionInfo> m_section_infos;
1143};
1144
1145
1146
1147size_t
1148ObjectFileMachO::ParseSymtab (bool minimize)
1149{
1150 Timer scoped_timer(__PRETTY_FUNCTION__,
1151 "ObjectFileMachO::ParseSymtab () module = %s",
1152 m_file.GetFilename().AsCString(""));
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001153 ModuleSP module_sp (GetModule());
1154 if (!module_sp)
1155 return 0;
1156
1157 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
1158 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
1159 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
1160 FunctionStarts function_starts;
Chris Lattner24943d22010-06-08 16:52:24 +00001161 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1162 uint32_t i;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001163
Greg Clayton0fea0512011-12-30 00:32:24 +00001164 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
1165
Chris Lattner24943d22010-06-08 16:52:24 +00001166 for (i=0; i<m_header.ncmds; ++i)
1167 {
1168 const uint32_t cmd_offset = offset;
1169 // Read in the load command and load command size
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001170 struct load_command lc;
1171 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001172 break;
1173 // Watch for the symbol table load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001174 switch (lc.cmd)
Chris Lattner24943d22010-06-08 16:52:24 +00001175 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001176 case LoadCommandSymtab:
1177 symtab_load_command.cmd = lc.cmd;
1178 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00001179 // Read in the rest of the symtab load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001180 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
1181 return 0;
1182 if (symtab_load_command.symoff == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001183 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001184 if (log)
1185 module_sp->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
1186 return 0;
1187 }
1188
1189 if (symtab_load_command.stroff == 0)
1190 {
1191 if (log)
1192 module_sp->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
1193 return 0;
1194 }
1195
1196 if (symtab_load_command.nsyms == 0)
1197 {
1198 if (log)
1199 module_sp->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
1200 return 0;
1201 }
1202
1203 if (symtab_load_command.strsize == 0)
1204 {
1205 if (log)
1206 module_sp->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
1207 return 0;
1208 }
1209 break;
1210
1211 case LoadCommandFunctionStarts:
1212 function_starts_load_command.cmd = lc.cmd;
1213 function_starts_load_command.cmdsize = lc.cmdsize;
1214 if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
1215 bzero (&function_starts_load_command, sizeof(function_starts_load_command));
1216 break;
1217
1218 default:
1219 break;
1220 }
1221 offset = cmd_offset + lc.cmdsize;
1222 }
1223
1224 if (symtab_load_command.cmd)
1225 {
1226 Symtab *symtab = m_symtab_ap.get();
1227 SectionList *section_list = GetSectionList();
1228 if (section_list == NULL)
1229 return 0;
1230
1231 ProcessSP process_sp (m_process_wp.lock());
1232
1233 const size_t addr_byte_size = m_data.GetAddressByteSize();
1234 bool bit_width_32 = addr_byte_size == 4;
1235 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
1236
1237 DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1238 DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1239 DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1240
1241 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
1242 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
1243 if (process_sp)
1244 {
1245 Target &target = process_sp->GetTarget();
1246 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
1247 // Reading mach file from memory in a process or core file...
1248
1249 if (linkedit_section_sp)
1250 {
1251 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
1252 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
1253 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
1254 const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
1255 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
1256 if (nlist_data_sp)
1257 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
1258 DataBufferSP strtab_data_sp (ReadMemory (process_sp, stroff_addr, strtab_data_byte_size));
1259 if (strtab_data_sp)
1260 strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
1261 if (function_starts_load_command.cmd)
Greg Clayton0fea0512011-12-30 00:32:24 +00001262 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001263 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1264 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
1265 if (func_start_data_sp)
1266 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
Greg Clayton0fea0512011-12-30 00:32:24 +00001267 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001268 }
1269 }
1270 else
1271 {
1272 nlist_data.SetData (m_data,
1273 symtab_load_command.symoff,
1274 nlist_data_byte_size);
1275 strtab_data.SetData (m_data,
1276 symtab_load_command.stroff,
1277 strtab_data_byte_size);
1278 if (function_starts_load_command.cmd)
1279 {
1280 function_starts_data.SetData (m_data,
1281 function_starts_load_command.dataoff,
1282 function_starts_load_command.datasize);
1283 }
1284 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001285
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001286 if (nlist_data.GetByteSize() == 0)
1287 {
1288 if (log)
1289 module_sp->LogMessage(log.get(), "failed to read nlist data");
1290 return 0;
1291 }
1292
1293
1294 if (strtab_data.GetByteSize() == 0)
1295 {
1296 if (log)
1297 module_sp->LogMessage(log.get(), "failed to read strtab data");
1298 return 0;
1299 }
1300
1301 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
1302 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
1303 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
1304 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
1305 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
1306 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
1307 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
1308 SectionSP eh_frame_section_sp;
1309 if (text_section_sp.get())
1310 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
1311 else
1312 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
1313
1314
1315 if (text_section_sp && function_starts_data.GetByteSize())
1316 {
1317 FunctionStarts::Entry function_start_entry;
1318 function_start_entry.data = false;
1319 uint32_t function_start_offset = 0;
1320 function_start_entry.addr = text_section_sp->GetFileAddress();
1321 uint64_t delta;
1322 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
1323 {
1324 // Now append the current entry
1325 function_start_entry.addr += delta;
1326 function_starts.Append(function_start_entry);
1327 }
1328 }
1329
1330 const uint32_t function_starts_count = function_starts.GetSize();
1331
1332 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
1333
1334 uint32_t nlist_data_offset = 0;
1335
1336 uint32_t N_SO_index = UINT32_MAX;
1337
1338 MachSymtabSectionInfo section_info (section_list);
1339 std::vector<uint32_t> N_FUN_indexes;
1340 std::vector<uint32_t> N_NSYM_indexes;
1341 std::vector<uint32_t> N_INCL_indexes;
1342 std::vector<uint32_t> N_BRAC_indexes;
1343 std::vector<uint32_t> N_COMM_indexes;
1344 typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
1345 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
1346 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
1347 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
1348 // Any symbols that get merged into another will get an entry
1349 // in this map so we know
1350 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
1351 uint32_t nlist_idx = 0;
1352 Symbol *symbol_ptr = NULL;
1353
1354 uint32_t sym_idx = 0;
1355 Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1356 uint32_t num_syms = symtab->GetNumSymbols();
1357
1358 //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1359 for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
1360 {
1361 struct nlist_64 nlist;
1362 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
1363 break;
1364
1365 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
1366 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
1367 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
1368 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
1369 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
1370
1371 SymbolType type = eSymbolTypeInvalid;
1372 const char *symbol_name = strtab_data.PeekCStr(nlist.n_strx);
1373 if (symbol_name == NULL)
1374 {
1375 // No symbol should be NULL, even the symbols with no
1376 // string values should have an offset zero which points
1377 // to an empty C-string
1378 Host::SystemLog (Host::eSystemLogError,
1379 "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
1380 nlist_idx,
1381 nlist.n_strx,
1382 module_sp->GetFileSpec().GetDirectory().GetCString(),
1383 module_sp->GetFileSpec().GetFilename().GetCString());
1384 continue;
1385 }
1386 const char *symbol_name_non_abi_mangled = NULL;
1387
1388 if (symbol_name[0] == '\0')
1389 symbol_name = NULL;
1390 SectionSP symbol_section;
1391 uint32_t symbol_byte_size = 0;
1392 bool add_nlist = true;
1393 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
1394
1395 assert (sym_idx < num_syms);
1396
1397 sym[sym_idx].SetDebug (is_debug);
1398
1399 if (is_debug)
1400 {
1401 switch (nlist.n_type)
Greg Clayton0fea0512011-12-30 00:32:24 +00001402 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001403 case StabGlobalSymbol:
1404 // N_GSYM -- global symbol: name,,NO_SECT,type,0
1405 // Sometimes the N_GSYM value contains the address.
1406
1407 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
1408 // have the same address, but we want to ensure that we always find only the real symbol,
1409 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
1410 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
1411 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
1412 // same address.
1413
1414 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
1415 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
1416 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
1417 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
1418 add_nlist = false;
1419 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00001420 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001421 sym[sym_idx].SetExternal(true);
1422 if (nlist.n_value != 0)
1423 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1424 type = eSymbolTypeData;
Greg Claytonb5a8f142012-02-05 02:38:54 +00001425 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001426 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +00001427
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001428 case StabFunctionName:
1429 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
1430 type = eSymbolTypeCompiler;
1431 break;
Greg Clayton0fea0512011-12-30 00:32:24 +00001432
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001433 case StabFunction:
1434 // N_FUN -- procedure: name,,n_sect,linenumber,address
1435 if (symbol_name)
Greg Claytona9c4f312011-10-31 20:50:40 +00001436 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001437 type = eSymbolTypeCode;
1438 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1439
1440 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
1441 // We use the current number of symbols in the symbol table in lieu of
1442 // using nlist_idx in case we ever start trimming entries out
1443 N_FUN_indexes.push_back(sym_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001444 }
1445 else
1446 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001447 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00001448
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001449 if ( !N_FUN_indexes.empty() )
Chris Lattner24943d22010-06-08 16:52:24 +00001450 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001451 // Copy the size of the function into the original STAB entry so we don't have
1452 // to hunt for it later
1453 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
1454 N_FUN_indexes.pop_back();
1455 // We don't really need the end function STAB as it contains the size which
1456 // we already placed with the original symbol, so don't add it if we want a
1457 // minimal symbol table
1458 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001459 add_nlist = false;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001460 }
Greg Clayton3f69eac2011-12-03 02:30:59 +00001461 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001462 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001463
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001464 case StabStaticSymbol:
1465 // N_STSYM -- static symbol: name,,n_sect,type,address
1466 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
1467 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1468 type = eSymbolTypeData;
1469 break;
1470
1471 case StabLocalCommon:
1472 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
1473 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1474 type = eSymbolTypeCommonBlock;
1475 break;
1476
1477 case StabBeginSymbol:
1478 // N_BNSYM
1479 // We use the current number of symbols in the symbol table in lieu of
1480 // using nlist_idx in case we ever start trimming entries out
1481 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001482 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001483 // Skip these if we want minimal symbol tables
1484 add_nlist = false;
1485 }
1486 else
1487 {
1488 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1489 N_NSYM_indexes.push_back(sym_idx);
1490 type = eSymbolTypeScopeBegin;
1491 }
1492 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001493
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001494 case StabEndSymbol:
1495 // N_ENSYM
1496 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
1497 // so that we can always skip the entire symbol if we need to navigate
1498 // more quickly at the source level when parsing STABS
1499 if (minimize)
1500 {
1501 // Skip these if we want minimal symbol tables
1502 add_nlist = false;
1503 }
1504 else
1505 {
1506 if ( !N_NSYM_indexes.empty() )
Greg Clayton3f69eac2011-12-03 02:30:59 +00001507 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001508 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
1509 symbol_ptr->SetByteSize(sym_idx + 1);
1510 symbol_ptr->SetSizeIsSibling(true);
1511 N_NSYM_indexes.pop_back();
1512 }
1513 type = eSymbolTypeScopeEnd;
1514 }
1515 break;
1516
1517
1518 case StabSourceFileOptions:
1519 // N_OPT - emitted with gcc2_compiled and in gcc source
1520 type = eSymbolTypeCompiler;
1521 break;
1522
1523 case StabRegisterSymbol:
1524 // N_RSYM - register sym: name,,NO_SECT,type,register
1525 type = eSymbolTypeVariable;
1526 break;
1527
1528 case StabSourceLine:
1529 // N_SLINE - src line: 0,,n_sect,linenumber,address
1530 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1531 type = eSymbolTypeLineEntry;
1532 break;
1533
1534 case StabStructureType:
1535 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
1536 type = eSymbolTypeVariableType;
1537 break;
1538
1539 case StabSourceFileName:
1540 // N_SO - source file name
1541 type = eSymbolTypeSourceFile;
1542 if (symbol_name == NULL)
1543 {
1544 if (minimize)
1545 add_nlist = false;
1546 if (N_SO_index != UINT32_MAX)
1547 {
1548 // Set the size of the N_SO to the terminating index of this N_SO
1549 // so that we can always skip the entire N_SO if we need to navigate
1550 // more quickly at the source level when parsing STABS
1551 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
1552 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
1553 symbol_ptr->SetSizeIsSibling(true);
1554 }
1555 N_NSYM_indexes.clear();
1556 N_INCL_indexes.clear();
1557 N_BRAC_indexes.clear();
1558 N_COMM_indexes.clear();
1559 N_FUN_indexes.clear();
1560 N_SO_index = UINT32_MAX;
1561 }
1562 else
1563 {
1564 // We use the current number of symbols in the symbol table in lieu of
1565 // using nlist_idx in case we ever start trimming entries out
1566 if (symbol_name[0] == '/')
1567 N_SO_index = sym_idx;
1568 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1569 {
1570 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
1571 if (so_path && so_path[0])
1572 {
1573 std::string full_so_path (so_path);
1574 if (*full_so_path.rbegin() != '/')
1575 full_so_path += '/';
1576 full_so_path += symbol_name;
1577 sym[sym_idx - 1].GetMangled().SetValue(full_so_path.c_str(), false);
1578 add_nlist = false;
1579 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1580 }
1581 }
1582 }
1583
1584 break;
1585
1586 case StabObjectFileName:
1587 // N_OSO - object file name: name,,0,0,st_mtime
1588 type = eSymbolTypeObjectFile;
1589 break;
1590
1591 case StabLocalSymbol:
1592 // N_LSYM - local sym: name,,NO_SECT,type,offset
1593 type = eSymbolTypeLocal;
1594 break;
1595
1596 //----------------------------------------------------------------------
1597 // INCL scopes
1598 //----------------------------------------------------------------------
1599 case StabBeginIncludeFileName:
1600 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
1601 // We use the current number of symbols in the symbol table in lieu of
1602 // using nlist_idx in case we ever start trimming entries out
1603 N_INCL_indexes.push_back(sym_idx);
1604 type = eSymbolTypeScopeBegin;
1605 break;
1606
1607 case StabEndIncludeFile:
1608 // N_EINCL - include file end: name,,NO_SECT,0,0
1609 // Set the size of the N_BINCL to the terminating index of this N_EINCL
1610 // so that we can always skip the entire symbol if we need to navigate
1611 // more quickly at the source level when parsing STABS
1612 if ( !N_INCL_indexes.empty() )
1613 {
1614 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
1615 symbol_ptr->SetByteSize(sym_idx + 1);
1616 symbol_ptr->SetSizeIsSibling(true);
1617 N_INCL_indexes.pop_back();
1618 }
1619 type = eSymbolTypeScopeEnd;
1620 break;
1621
1622 case StabIncludeFileName:
1623 // N_SOL - #included file name: name,,n_sect,0,address
1624 type = eSymbolTypeHeaderFile;
1625
1626 // We currently don't use the header files on darwin
1627 if (minimize)
1628 add_nlist = false;
1629 break;
1630
1631 case StabCompilerParameters:
1632 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
1633 type = eSymbolTypeCompiler;
1634 break;
1635
1636 case StabCompilerVersion:
1637 // N_VERSION - compiler version: name,,NO_SECT,0,0
1638 type = eSymbolTypeCompiler;
1639 break;
1640
1641 case StabCompilerOptLevel:
1642 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
1643 type = eSymbolTypeCompiler;
1644 break;
1645
1646 case StabParameter:
1647 // N_PSYM - parameter: name,,NO_SECT,type,offset
1648 type = eSymbolTypeVariable;
1649 break;
1650
1651 case StabAlternateEntry:
1652 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
1653 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1654 type = eSymbolTypeLineEntry;
1655 break;
1656
1657 //----------------------------------------------------------------------
1658 // Left and Right Braces
1659 //----------------------------------------------------------------------
1660 case StabLeftBracket:
1661 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
1662 // We use the current number of symbols in the symbol table in lieu of
1663 // using nlist_idx in case we ever start trimming entries out
1664 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1665 N_BRAC_indexes.push_back(sym_idx);
1666 type = eSymbolTypeScopeBegin;
1667 break;
1668
1669 case StabRightBracket:
1670 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
1671 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
1672 // so that we can always skip the entire symbol if we need to navigate
1673 // more quickly at the source level when parsing STABS
1674 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1675 if ( !N_BRAC_indexes.empty() )
1676 {
1677 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
1678 symbol_ptr->SetByteSize(sym_idx + 1);
1679 symbol_ptr->SetSizeIsSibling(true);
1680 N_BRAC_indexes.pop_back();
1681 }
1682 type = eSymbolTypeScopeEnd;
1683 break;
1684
1685 case StabDeletedIncludeFile:
1686 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
1687 type = eSymbolTypeHeaderFile;
1688 break;
1689
1690 //----------------------------------------------------------------------
1691 // COMM scopes
1692 //----------------------------------------------------------------------
1693 case StabBeginCommon:
1694 // N_BCOMM - begin common: name,,NO_SECT,0,0
1695 // We use the current number of symbols in the symbol table in lieu of
1696 // using nlist_idx in case we ever start trimming entries out
1697 type = eSymbolTypeScopeBegin;
1698 N_COMM_indexes.push_back(sym_idx);
1699 break;
1700
1701 case StabEndCommonLocal:
1702 // N_ECOML - end common (local name): 0,,n_sect,0,address
1703 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1704 // Fall through
1705
1706 case StabEndCommon:
1707 // N_ECOMM - end common: name,,n_sect,0,0
1708 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
1709 // so that we can always skip the entire symbol if we need to navigate
1710 // more quickly at the source level when parsing STABS
1711 if ( !N_COMM_indexes.empty() )
1712 {
1713 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
1714 symbol_ptr->SetByteSize(sym_idx + 1);
1715 symbol_ptr->SetSizeIsSibling(true);
1716 N_COMM_indexes.pop_back();
1717 }
1718 type = eSymbolTypeScopeEnd;
1719 break;
1720
1721 case StabLength:
1722 // N_LENG - second stab entry with length information
1723 type = eSymbolTypeAdditional;
1724 break;
1725
1726 default: break;
1727 }
1728 }
1729 else
1730 {
1731 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
1732 uint8_t n_type = NlistMaskType & nlist.n_type;
1733 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
1734
1735 switch (n_type)
1736 {
1737 case NListTypeIndirect: // N_INDR - Fall through
1738 case NListTypePreboundUndefined:// N_PBUD - Fall through
1739 case NListTypeUndefined: // N_UNDF
1740 type = eSymbolTypeUndefined;
1741 break;
1742
1743 case NListTypeAbsolute: // N_ABS
1744 type = eSymbolTypeAbsolute;
1745 break;
1746
1747 case NListTypeSection: // N_SECT
1748 {
1749 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1750
1751 if (symbol_section == NULL)
1752 {
1753 // TODO: warn about this?
1754 add_nlist = false;
1755 break;
1756 }
1757
1758 if (TEXT_eh_frame_sectID == nlist.n_sect)
1759 {
1760 type = eSymbolTypeException;
Chris Lattner24943d22010-06-08 16:52:24 +00001761 }
1762 else
1763 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001764 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
1765
1766 switch (section_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001767 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001768 case SectionTypeRegular: break; // regular section
1769 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
1770 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
1771 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
1772 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
1773 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
1774 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
1775 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
1776 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1777 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
1778 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
1779 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
1780 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
1781 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
1782 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
1783 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
1784 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
1785 default: break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001786 }
Chris Lattner24943d22010-06-08 16:52:24 +00001787
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001788 if (type == eSymbolTypeInvalid)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001789 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001790 const char *symbol_sect_name = symbol_section->GetName().AsCString();
1791 if (symbol_section->IsDescendant (text_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00001792 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001793 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
1794 SectionAttrUserSelfModifyingCode |
1795 SectionAttrSytemSomeInstructions))
1796 type = eSymbolTypeData;
1797 else
1798 type = eSymbolTypeCode;
Greg Clayton576a68b2010-09-08 16:38:06 +00001799 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001800 else
1801 if (symbol_section->IsDescendant(data_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00001802 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001803 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
Greg Clayton7c36fa02010-09-11 03:13:28 +00001804 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001805 type = eSymbolTypeRuntime;
Chris Lattner24943d22010-06-08 16:52:24 +00001806
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001807 if (symbol_name &&
1808 symbol_name[0] == '_' &&
1809 symbol_name[1] == 'O' &&
1810 symbol_name[2] == 'B')
Greg Clayton637029b2010-09-12 05:25:16 +00001811 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001812 llvm::StringRef symbol_name_ref(symbol_name);
1813 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
1814 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
1815 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
1816 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
Chris Lattner24943d22010-06-08 16:52:24 +00001817 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001818 symbol_name_non_abi_mangled = symbol_name + 1;
1819 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
1820 type = eSymbolTypeObjCClass;
Chris Lattner24943d22010-06-08 16:52:24 +00001821 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001822 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
Chris Lattner24943d22010-06-08 16:52:24 +00001823 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001824 symbol_name_non_abi_mangled = symbol_name + 1;
1825 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
1826 type = eSymbolTypeObjCMetaClass;
1827 }
1828 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
1829 {
1830 symbol_name_non_abi_mangled = symbol_name + 1;
1831 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
1832 type = eSymbolTypeObjCIVar;
Chris Lattner24943d22010-06-08 16:52:24 +00001833 }
1834 }
1835 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001836 else
1837 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
1838 {
1839 type = eSymbolTypeException;
1840 }
1841 else
1842 {
1843 type = eSymbolTypeData;
1844 }
1845 }
1846 else
1847 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
1848 {
1849 type = eSymbolTypeTrampoline;
1850 }
1851 else
1852 if (symbol_section->IsDescendant(objc_section_sp.get()))
1853 {
1854 type = eSymbolTypeRuntime;
1855 if (symbol_name && symbol_name[0] == '.')
1856 {
1857 llvm::StringRef symbol_name_ref(symbol_name);
1858 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
1859 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
1860 {
1861 symbol_name_non_abi_mangled = symbol_name;
1862 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
1863 type = eSymbolTypeObjCClass;
1864 }
1865 }
Chris Lattner24943d22010-06-08 16:52:24 +00001866 }
1867 }
1868 }
1869 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001870 break;
1871 }
1872 }
1873
1874 if (add_nlist)
1875 {
1876 uint64_t symbol_value = nlist.n_value;
1877 bool symbol_name_is_mangled = false;
1878
1879 if (symbol_name_non_abi_mangled)
1880 {
1881 sym[sym_idx].GetMangled().SetMangledName (symbol_name_non_abi_mangled);
1882 sym[sym_idx].GetMangled().SetDemangledName (symbol_name);
Chris Lattner24943d22010-06-08 16:52:24 +00001883 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001884 else
1885 {
1886 if (symbol_name && symbol_name[0] == '_')
1887 {
1888 symbol_name_is_mangled = symbol_name[1] == '_';
1889 symbol_name++; // Skip the leading underscore
1890 }
1891
1892 if (symbol_name)
1893 {
1894 sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
1895 }
1896 }
1897
1898 if (is_debug == false)
1899 {
1900 if (type == eSymbolTypeCode)
1901 {
1902 // See if we can find a N_FUN entry for any code symbols.
1903 // If we do find a match, and the name matches, then we
1904 // can merge the two into just the function symbol to avoid
1905 // duplicate entries in the symbol table
1906 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
1907 if (pos != N_FUN_addr_to_sym_idx.end())
1908 {
1909 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1910 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1911 {
1912 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
1913 // We just need the flags from the linker symbol, so put these flags
1914 // into the N_FUN flags to avoid duplicate symbols in the symbol table
1915 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1916 sym[sym_idx].Clear();
1917 continue;
1918 }
1919 }
1920 }
1921 else if (type == eSymbolTypeData)
1922 {
1923 // See if we can find a N_STSYM entry for any data symbols.
1924 // If we do find a match, and the name matches, then we
1925 // can merge the two into just the Static symbol to avoid
1926 // duplicate entries in the symbol table
1927 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
1928 if (pos != N_STSYM_addr_to_sym_idx.end())
1929 {
1930 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1931 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1932 {
1933 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
1934 // We just need the flags from the linker symbol, so put these flags
1935 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
1936 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1937 sym[sym_idx].Clear();
1938 continue;
1939 }
1940 }
1941 }
1942 }
1943 if (symbol_section)
1944 {
1945 const addr_t section_file_addr = symbol_section->GetFileAddress();
1946 if (symbol_byte_size == 0 && function_starts_count > 0)
1947 {
1948 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry(nlist.n_value, true);
1949 if (func_start_entry)
1950 {
1951 func_start_entry->data = true;
1952 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
1953 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
1954 if (next_func_start_entry)
1955 {
1956 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);
1957 }
1958 else
1959 {
1960 symbol_byte_size = section_end_file_addr - func_start_entry->addr;
1961 }
1962 }
1963 }
1964 symbol_value -= section_file_addr;
1965 }
1966
1967 sym[sym_idx].SetID (nlist_idx);
1968 sym[sym_idx].SetType (type);
1969 sym[sym_idx].GetAddress().SetSection (symbol_section);
1970 sym[sym_idx].GetAddress().SetOffset (symbol_value);
1971 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1972
1973 if (symbol_byte_size > 0)
1974 sym[sym_idx].SetByteSize(symbol_byte_size);
1975
1976 ++sym_idx;
1977 }
1978 else
1979 {
1980 sym[sym_idx].Clear();
1981 }
1982
1983 }
1984
1985 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
1986 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
1987 // such entries by figuring out what the address for the global is by looking up this non-STAB
1988 // entry and copying the value into the debug symbol's value to save us the hassle in the
1989 // debug symbol parser.
1990
1991 Symbol *global_symbol = NULL;
1992 for (nlist_idx = 0;
1993 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
1994 nlist_idx++)
1995 {
1996 if (global_symbol->GetAddress().GetFileAddress() == 0)
1997 {
1998 std::vector<uint32_t> indexes;
1999 if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
2000 {
2001 std::vector<uint32_t>::const_iterator pos;
2002 std::vector<uint32_t>::const_iterator end = indexes.end();
2003 for (pos = indexes.begin(); pos != end; ++pos)
2004 {
2005 symbol_ptr = symtab->SymbolAtIndex(*pos);
2006 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
2007 {
2008 global_symbol->GetAddress() = symbol_ptr->GetAddress();
2009 break;
2010 }
2011 }
2012 }
Chris Lattner24943d22010-06-08 16:52:24 +00002013 }
2014 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002015
2016 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
2017
2018
2019 if (function_starts_count > 0)
2020 {
2021 char synthetic_function_symbol[PATH_MAX];
2022 uint32_t num_synthetic_function_symbols = 0;
2023 for (i=0; i<function_starts_count; ++i)
2024 {
2025 if (function_starts.GetEntryRef (i).data == false)
2026 ++num_synthetic_function_symbols;
2027 }
2028
2029 if (num_synthetic_function_symbols > 0)
2030 {
2031 if (num_syms < sym_idx + num_synthetic_function_symbols)
2032 {
2033 num_syms = sym_idx + num_synthetic_function_symbols;
2034 sym = symtab->Resize (num_syms);
2035 }
2036 uint32_t synthetic_function_symbol_idx = 0;
2037 for (i=0; i<function_starts_count; ++i)
2038 {
2039 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
2040 if (func_start_entry->data == false)
2041 {
2042 Address symbol_addr;
2043 if (module_sp->ResolveFileAddress (func_start_entry->addr, symbol_addr))
2044 {
2045 SectionSP symbol_section (symbol_addr.GetSection());
2046 uint32_t symbol_byte_size = 0;
2047 if (symbol_section)
2048 {
2049 const addr_t section_file_addr = symbol_section->GetFileAddress();
2050 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2051 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2052 if (next_func_start_entry)
2053 {
2054 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);
2055 }
2056 else
2057 {
2058 symbol_byte_size = section_end_file_addr - func_start_entry->addr;
2059 }
2060 snprintf (synthetic_function_symbol,
2061 sizeof(synthetic_function_symbol),
2062 "___lldb_unnamed_function%u$$%s",
2063 ++synthetic_function_symbol_idx,
2064 module_sp->GetFileSpec().GetFilename().GetCString());
2065 sym[sym_idx].SetID (synthetic_sym_id++);
2066 sym[sym_idx].GetMangled().SetDemangledName(synthetic_function_symbol);
2067 sym[sym_idx].SetType (eSymbolTypeCode);
2068 sym[sym_idx].SetIsSynthetic (true);
2069 sym[sym_idx].GetAddress() = symbol_addr;
2070 if (symbol_byte_size)
2071 sym[sym_idx].SetByteSize (symbol_byte_size);
2072 ++sym_idx;
2073 }
2074 }
2075 }
2076 }
2077 }
2078 }
2079
2080 // Trim our symbols down to just what we ended up with after
2081 // removing any symbols.
2082 if (sym_idx < num_syms)
2083 {
2084 num_syms = sym_idx;
2085 sym = symtab->Resize (num_syms);
2086 }
2087
2088 // Now synthesize indirect symbols
2089 if (m_dysymtab.nindirectsyms != 0)
2090 {
2091 DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
2092
2093 if (indirect_symbol_index_data.GetByteSize())
2094 {
2095 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
2096
2097 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
2098 {
2099 if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
2100 {
2101 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
2102 if (symbol_stub_byte_size == 0)
2103 continue;
2104
2105 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
2106
2107 if (num_symbol_stubs == 0)
2108 continue;
2109
2110 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
2111 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
2112 {
2113 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
2114 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
2115 uint32_t symbol_stub_offset = symbol_stub_index * 4;
2116 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
2117 {
2118 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
2119 if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
2120 continue;
2121
2122 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
2123 Symbol *stub_symbol = NULL;
2124 if (index_pos != end_index_pos)
2125 {
2126 // We have a remapping from the original nlist index to
2127 // a current symbol index, so just look this up by index
2128 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
2129 }
2130 else
2131 {
2132 // We need to lookup a symbol using the original nlist
2133 // symbol index since this index is coming from the
2134 // S_SYMBOL_STUBS
2135 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
2136 }
2137
2138 assert (stub_symbol);
2139 if (stub_symbol)
2140 {
2141 Address so_addr(symbol_stub_addr, section_list);
2142
2143 if (stub_symbol->GetType() == eSymbolTypeUndefined)
2144 {
2145 // Change the external symbol into a trampoline that makes sense
2146 // These symbols were N_UNDF N_EXT, and are useless to us, so we
2147 // can re-use them so we don't have to make up a synthetic symbol
2148 // for no good reason.
2149 stub_symbol->SetType (eSymbolTypeTrampoline);
2150 stub_symbol->SetExternal (false);
2151 stub_symbol->GetAddress() = so_addr;
2152 stub_symbol->SetByteSize (symbol_stub_byte_size);
2153 }
2154 else
2155 {
2156 // Make a synthetic symbol to describe the trampoline stub
2157 if (sym_idx >= num_syms)
2158 sym = symtab->Resize (++num_syms);
2159 sym[sym_idx].SetID (synthetic_sym_id++);
2160 sym[sym_idx].GetMangled() = stub_symbol->GetMangled();
2161 sym[sym_idx].SetType (eSymbolTypeTrampoline);
2162 sym[sym_idx].SetIsSynthetic (true);
2163 sym[sym_idx].GetAddress() = so_addr;
2164 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
2165 ++sym_idx;
2166 }
2167 }
2168 }
2169 }
2170 }
2171 }
2172 }
2173 }
2174 return symtab->GetNumSymbols();
Chris Lattner24943d22010-06-08 16:52:24 +00002175 }
2176 return 0;
2177}
2178
2179
2180void
2181ObjectFileMachO::Dump (Stream *s)
2182{
Greg Clayton9482f052012-03-13 23:14:29 +00002183 ModuleSP module_sp(GetModule());
2184 if (module_sp)
2185 {
2186 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2187 s->Printf("%p: ", this);
2188 s->Indent();
2189 if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped)
2190 s->PutCString("ObjectFileMachO64");
2191 else
2192 s->PutCString("ObjectFileMachO32");
Chris Lattner24943d22010-06-08 16:52:24 +00002193
Greg Clayton9482f052012-03-13 23:14:29 +00002194 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +00002195
Greg Clayton9482f052012-03-13 23:14:29 +00002196 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner24943d22010-06-08 16:52:24 +00002197
Greg Clayton9482f052012-03-13 23:14:29 +00002198 if (m_sections_ap.get())
2199 m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00002200
Greg Clayton9482f052012-03-13 23:14:29 +00002201 if (m_symtab_ap.get())
2202 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
2203 }
Chris Lattner24943d22010-06-08 16:52:24 +00002204}
2205
2206
2207bool
Greg Clayton0467c782011-02-04 18:53:10 +00002208ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner24943d22010-06-08 16:52:24 +00002209{
Greg Clayton9482f052012-03-13 23:14:29 +00002210 ModuleSP module_sp(GetModule());
2211 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00002212 {
Greg Clayton9482f052012-03-13 23:14:29 +00002213 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2214 struct uuid_command load_cmd;
2215 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2216 uint32_t i;
2217 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00002218 {
Greg Clayton9482f052012-03-13 23:14:29 +00002219 const uint32_t cmd_offset = offset;
2220 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2221 break;
2222
2223 if (load_cmd.cmd == LoadCommandUUID)
Chris Lattner24943d22010-06-08 16:52:24 +00002224 {
Greg Clayton9482f052012-03-13 23:14:29 +00002225 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
2226 if (uuid_bytes)
2227 {
2228 uuid->SetBytes (uuid_bytes);
2229 return true;
2230 }
2231 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00002232 }
Greg Clayton9482f052012-03-13 23:14:29 +00002233 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00002234 }
Chris Lattner24943d22010-06-08 16:52:24 +00002235 }
2236 return false;
2237}
2238
2239
2240uint32_t
2241ObjectFileMachO::GetDependentModules (FileSpecList& files)
2242{
Chris Lattner24943d22010-06-08 16:52:24 +00002243 uint32_t count = 0;
Greg Clayton9482f052012-03-13 23:14:29 +00002244 ModuleSP module_sp(GetModule());
2245 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00002246 {
Greg Clayton9482f052012-03-13 23:14:29 +00002247 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2248 struct load_command load_cmd;
2249 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2250 const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
2251 uint32_t i;
2252 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00002253 {
Greg Clayton9482f052012-03-13 23:14:29 +00002254 const uint32_t cmd_offset = offset;
2255 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2256 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002257
Greg Clayton9482f052012-03-13 23:14:29 +00002258 switch (load_cmd.cmd)
2259 {
2260 case LoadCommandDylibLoad:
2261 case LoadCommandDylibLoadWeak:
2262 case LoadCommandDylibReexport:
2263 case LoadCommandDynamicLinkerLoad:
2264 case LoadCommandFixedVMShlibLoad:
2265 case LoadCommandDylibLoadUpward:
2266 {
2267 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2268 const char *path = m_data.PeekCStr(name_offset);
2269 // Skip any path that starts with '@' since these are usually:
2270 // @executable_path/.../file
2271 // @rpath/.../file
2272 if (path && path[0] != '@')
2273 {
2274 FileSpec file_spec(path, resolve_path);
2275 if (files.AppendIfUnique(file_spec))
2276 count++;
2277 }
2278 }
2279 break;
2280
2281 default:
2282 break;
2283 }
2284 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00002285 }
Chris Lattner24943d22010-06-08 16:52:24 +00002286 }
2287 return count;
2288}
2289
Jim Ingham28775942011-03-07 23:44:08 +00002290lldb_private::Address
2291ObjectFileMachO::GetEntryPointAddress ()
2292{
2293 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
2294 // is initialized to an invalid address, so we can just return that.
2295 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
2296
2297 if (!IsExecutable() || m_entry_point_address.IsValid())
2298 return m_entry_point_address;
2299
2300 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
2301 // /usr/include/mach-o.h, but it is basically:
2302 //
2303 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
2304 // uint32_t count - this is the count of longs in the thread state data
2305 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
2306 // <repeat this trio>
2307 //
2308 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
2309 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
2310 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
2311 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
2312 //
2313 // For now we hard-code the offsets and flavors we need:
2314 //
2315 //
2316
Greg Clayton9482f052012-03-13 23:14:29 +00002317 ModuleSP module_sp(GetModule());
2318 if (module_sp)
Jim Ingham28775942011-03-07 23:44:08 +00002319 {
Greg Clayton9482f052012-03-13 23:14:29 +00002320 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2321 struct load_command load_cmd;
2322 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2323 uint32_t i;
2324 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
2325 bool done = false;
2326
2327 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham28775942011-03-07 23:44:08 +00002328 {
Greg Clayton9482f052012-03-13 23:14:29 +00002329 const uint32_t cmd_offset = offset;
2330 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2331 break;
2332
2333 switch (load_cmd.cmd)
Jim Ingham28775942011-03-07 23:44:08 +00002334 {
Greg Clayton9482f052012-03-13 23:14:29 +00002335 case LoadCommandUnixThread:
2336 case LoadCommandThread:
Jim Ingham28775942011-03-07 23:44:08 +00002337 {
Greg Clayton9482f052012-03-13 23:14:29 +00002338 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham28775942011-03-07 23:44:08 +00002339 {
Greg Clayton9482f052012-03-13 23:14:29 +00002340 uint32_t flavor = m_data.GetU32(&offset);
2341 uint32_t count = m_data.GetU32(&offset);
2342 if (count == 0)
2343 {
2344 // We've gotten off somehow, log and exit;
2345 return m_entry_point_address;
Jim Ingham28775942011-03-07 23:44:08 +00002346 }
Greg Clayton9482f052012-03-13 23:14:29 +00002347
2348 switch (m_header.cputype)
2349 {
2350 case llvm::MachO::CPUTypeARM:
2351 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
2352 {
2353 offset += 60; // This is the offset of pc in the GPR thread state data structure.
2354 start_address = m_data.GetU32(&offset);
2355 done = true;
2356 }
Jim Ingham28775942011-03-07 23:44:08 +00002357 break;
Greg Clayton9482f052012-03-13 23:14:29 +00002358 case llvm::MachO::CPUTypeI386:
2359 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
2360 {
2361 offset += 40; // This is the offset of eip in the GPR thread state data structure.
2362 start_address = m_data.GetU32(&offset);
2363 done = true;
2364 }
2365 break;
2366 case llvm::MachO::CPUTypeX86_64:
2367 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
2368 {
2369 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
2370 start_address = m_data.GetU64(&offset);
2371 done = true;
2372 }
2373 break;
2374 default:
2375 return m_entry_point_address;
2376 }
2377 // Haven't found the GPR flavor yet, skip over the data for this flavor:
2378 if (done)
2379 break;
2380 offset += count * 4;
2381 }
Jim Ingham28775942011-03-07 23:44:08 +00002382 }
Greg Clayton9482f052012-03-13 23:14:29 +00002383 break;
2384 case LoadCommandMain:
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002385 {
Greg Clayton9482f052012-03-13 23:14:29 +00002386 ConstString text_segment_name ("__TEXT");
2387 uint64_t entryoffset = m_data.GetU64(&offset);
2388 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2389 if (text_segment_sp)
2390 {
2391 done = true;
2392 start_address = text_segment_sp->GetFileAddress() + entryoffset;
2393 }
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002394 }
Greg Clayton9482f052012-03-13 23:14:29 +00002395
2396 default:
2397 break;
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002398 }
Greg Clayton9482f052012-03-13 23:14:29 +00002399 if (done)
2400 break;
Jim Ingham28775942011-03-07 23:44:08 +00002401
Greg Clayton9482f052012-03-13 23:14:29 +00002402 // Go to the next load command:
2403 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham28775942011-03-07 23:44:08 +00002404 }
Jim Ingham28775942011-03-07 23:44:08 +00002405
Greg Clayton9482f052012-03-13 23:14:29 +00002406 if (start_address != LLDB_INVALID_ADDRESS)
Greg Clayton3508c382012-02-24 01:59:29 +00002407 {
Greg Clayton9482f052012-03-13 23:14:29 +00002408 // We got the start address from the load commands, so now resolve that address in the sections
2409 // of this ObjectFile:
2410 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Clayton3508c382012-02-24 01:59:29 +00002411 {
Greg Clayton9482f052012-03-13 23:14:29 +00002412 m_entry_point_address.Clear();
2413 }
2414 }
2415 else
2416 {
2417 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
2418 // "start" symbol in the main executable.
2419
2420 ModuleSP module_sp (GetModule());
2421
2422 if (module_sp)
2423 {
2424 SymbolContextList contexts;
2425 SymbolContext context;
2426 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
2427 {
2428 if (contexts.GetContextAtIndex(0, context))
2429 m_entry_point_address = context.symbol->GetAddress();
2430 }
Greg Clayton3508c382012-02-24 01:59:29 +00002431 }
2432 }
Jim Ingham28775942011-03-07 23:44:08 +00002433 }
2434
2435 return m_entry_point_address;
2436
2437}
2438
Greg Claytonb5a8f142012-02-05 02:38:54 +00002439lldb_private::Address
2440ObjectFileMachO::GetHeaderAddress ()
2441{
2442 lldb_private::Address header_addr;
2443 SectionList *section_list = GetSectionList();
2444 if (section_list)
2445 {
2446 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
2447 if (text_segment_sp)
2448 {
Greg Clayton3508c382012-02-24 01:59:29 +00002449 header_addr.SetSection (text_segment_sp);
Greg Claytonb5a8f142012-02-05 02:38:54 +00002450 header_addr.SetOffset (0);
2451 }
2452 }
2453 return header_addr;
2454}
2455
Greg Clayton46c9a352012-02-09 06:16:32 +00002456uint32_t
2457ObjectFileMachO::GetNumThreadContexts ()
2458{
Greg Clayton9482f052012-03-13 23:14:29 +00002459 ModuleSP module_sp(GetModule());
2460 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00002461 {
Greg Clayton9482f052012-03-13 23:14:29 +00002462 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2463 if (!m_thread_context_offsets_valid)
Greg Clayton46c9a352012-02-09 06:16:32 +00002464 {
Greg Clayton9482f052012-03-13 23:14:29 +00002465 m_thread_context_offsets_valid = true;
2466 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2467 FileRangeArray::Entry file_range;
2468 thread_command thread_cmd;
2469 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton46c9a352012-02-09 06:16:32 +00002470 {
Greg Clayton9482f052012-03-13 23:14:29 +00002471 const uint32_t cmd_offset = offset;
2472 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
2473 break;
2474
2475 if (thread_cmd.cmd == LoadCommandThread)
2476 {
2477 file_range.SetRangeBase (offset);
2478 file_range.SetByteSize (thread_cmd.cmdsize - 8);
2479 m_thread_context_offsets.Append (file_range);
2480 }
2481 offset = cmd_offset + thread_cmd.cmdsize;
Greg Clayton46c9a352012-02-09 06:16:32 +00002482 }
Greg Clayton46c9a352012-02-09 06:16:32 +00002483 }
2484 }
2485 return m_thread_context_offsets.GetSize();
2486}
2487
2488lldb::RegisterContextSP
2489ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
2490{
Greg Clayton46c9a352012-02-09 06:16:32 +00002491 lldb::RegisterContextSP reg_ctx_sp;
Greg Clayton9ce95382012-02-13 23:10:39 +00002492
Greg Clayton9482f052012-03-13 23:14:29 +00002493 ModuleSP module_sp(GetModule());
2494 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00002495 {
Greg Clayton9482f052012-03-13 23:14:29 +00002496 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2497 if (!m_thread_context_offsets_valid)
2498 GetNumThreadContexts ();
2499
2500 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
2501
2502 DataExtractor data (m_data,
2503 thread_context_file_range->GetRangeBase(),
2504 thread_context_file_range->GetByteSize());
2505
2506 switch (m_header.cputype)
2507 {
2508 case llvm::MachO::CPUTypeARM:
2509 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
2510 break;
2511
2512 case llvm::MachO::CPUTypeI386:
2513 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
2514 break;
2515
2516 case llvm::MachO::CPUTypeX86_64:
2517 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
2518 break;
2519 }
Greg Clayton46c9a352012-02-09 06:16:32 +00002520 }
2521 return reg_ctx_sp;
2522}
2523
Greg Claytonb5a8f142012-02-05 02:38:54 +00002524
Greg Claytonca319972011-07-09 00:41:34 +00002525ObjectFile::Type
2526ObjectFileMachO::CalculateType()
2527{
2528 switch (m_header.filetype)
2529 {
2530 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2531 if (GetAddressByteSize () == 4)
2532 {
2533 // 32 bit kexts are just object files, but they do have a valid
2534 // UUID load command.
2535 UUID uuid;
2536 if (GetUUID(&uuid))
2537 {
2538 // this checking for the UUID load command is not enough
2539 // we could eventually look for the symbol named
2540 // "OSKextGetCurrentIdentifier" as this is required of kexts
2541 if (m_strata == eStrataInvalid)
2542 m_strata = eStrataKernel;
2543 return eTypeSharedLibrary;
2544 }
2545 }
2546 return eTypeObjectFile;
2547
2548 case HeaderFileTypeExecutable: return eTypeExecutable; // 0x2u MH_EXECUTE
2549 case HeaderFileTypeFixedVMShlib: return eTypeSharedLibrary; // 0x3u MH_FVMLIB
2550 case HeaderFileTypeCore: return eTypeCoreFile; // 0x4u MH_CORE
2551 case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary; // 0x5u MH_PRELOAD
2552 case HeaderFileTypeDynamicShlib: return eTypeSharedLibrary; // 0x6u MH_DYLIB
2553 case HeaderFileTypeDynamicLinkEditor: return eTypeDynamicLinker; // 0x7u MH_DYLINKER
2554 case HeaderFileTypeBundle: return eTypeSharedLibrary; // 0x8u MH_BUNDLE
2555 case HeaderFileTypeDynamicShlibStub: return eTypeStubLibrary; // 0x9u MH_DYLIB_STUB
2556 case HeaderFileTypeDSYM: return eTypeDebugInfo; // 0xAu MH_DSYM
2557 case HeaderFileTypeKextBundle: return eTypeSharedLibrary; // 0xBu MH_KEXT_BUNDLE
2558 default:
2559 break;
2560 }
2561 return eTypeUnknown;
2562}
2563
2564ObjectFile::Strata
2565ObjectFileMachO::CalculateStrata()
2566{
2567 switch (m_header.filetype)
2568 {
2569 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2570 {
2571 // 32 bit kexts are just object files, but they do have a valid
2572 // UUID load command.
2573 UUID uuid;
2574 if (GetUUID(&uuid))
2575 {
2576 // this checking for the UUID load command is not enough
2577 // we could eventually look for the symbol named
2578 // "OSKextGetCurrentIdentifier" as this is required of kexts
2579 if (m_type == eTypeInvalid)
2580 m_type = eTypeSharedLibrary;
2581
2582 return eStrataKernel;
2583 }
2584 }
2585 return eStrataUnknown;
2586
2587 case HeaderFileTypeExecutable: // 0x2u MH_EXECUTE
2588 // Check for the MH_DYLDLINK bit in the flags
2589 if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
Sean Callananac725af2012-02-10 20:22:35 +00002590 {
Greg Claytonca319972011-07-09 00:41:34 +00002591 return eStrataUser;
Sean Callananac725af2012-02-10 20:22:35 +00002592 }
2593 else
2594 {
2595 SectionList *section_list = GetSectionList();
2596 if (section_list)
2597 {
2598 static ConstString g_kld_section_name ("__KLD");
2599 if (section_list->FindSectionByName(g_kld_section_name))
2600 return eStrataKernel;
2601 }
2602 }
2603 return eStrataRawImage;
Greg Claytonca319972011-07-09 00:41:34 +00002604
2605 case HeaderFileTypeFixedVMShlib: return eStrataUser; // 0x3u MH_FVMLIB
2606 case HeaderFileTypeCore: return eStrataUnknown; // 0x4u MH_CORE
Sean Callananac725af2012-02-10 20:22:35 +00002607 case HeaderFileTypePreloadedExecutable: return eStrataRawImage; // 0x5u MH_PRELOAD
Greg Claytonca319972011-07-09 00:41:34 +00002608 case HeaderFileTypeDynamicShlib: return eStrataUser; // 0x6u MH_DYLIB
2609 case HeaderFileTypeDynamicLinkEditor: return eStrataUser; // 0x7u MH_DYLINKER
2610 case HeaderFileTypeBundle: return eStrataUser; // 0x8u MH_BUNDLE
2611 case HeaderFileTypeDynamicShlibStub: return eStrataUser; // 0x9u MH_DYLIB_STUB
2612 case HeaderFileTypeDSYM: return eStrataUnknown; // 0xAu MH_DSYM
2613 case HeaderFileTypeKextBundle: return eStrataKernel; // 0xBu MH_KEXT_BUNDLE
2614 default:
2615 break;
2616 }
2617 return eStrataUnknown;
2618}
2619
2620
Greg Clayton49f4bf22012-02-22 19:41:02 +00002621uint32_t
2622ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
2623{
Greg Clayton9482f052012-03-13 23:14:29 +00002624 ModuleSP module_sp(GetModule());
2625 if (module_sp)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002626 {
Greg Clayton9482f052012-03-13 23:14:29 +00002627 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2628 struct dylib_command load_cmd;
2629 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2630 uint32_t version_cmd = 0;
2631 uint64_t version = 0;
2632 uint32_t i;
2633 for (i=0; i<m_header.ncmds; ++i)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002634 {
Greg Clayton9482f052012-03-13 23:14:29 +00002635 const uint32_t cmd_offset = offset;
2636 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2637 break;
2638
2639 if (load_cmd.cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002640 {
Greg Clayton9482f052012-03-13 23:14:29 +00002641 if (version_cmd == 0)
2642 {
2643 version_cmd = load_cmd.cmd;
2644 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
2645 break;
2646 version = load_cmd.dylib.current_version;
2647 }
2648 break; // Break for now unless there is another more complete version
2649 // number load command in the future.
Greg Clayton49f4bf22012-02-22 19:41:02 +00002650 }
Greg Clayton9482f052012-03-13 23:14:29 +00002651 offset = cmd_offset + load_cmd.cmdsize;
Greg Clayton49f4bf22012-02-22 19:41:02 +00002652 }
Greg Clayton9482f052012-03-13 23:14:29 +00002653
2654 if (version_cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002655 {
Greg Clayton9482f052012-03-13 23:14:29 +00002656 if (versions != NULL && num_versions > 0)
2657 {
2658 if (num_versions > 0)
2659 versions[0] = (version & 0xFFFF0000ull) >> 16;
2660 if (num_versions > 1)
2661 versions[1] = (version & 0x0000FF00ull) >> 8;
2662 if (num_versions > 2)
2663 versions[2] = (version & 0x000000FFull);
2664 // Fill in an remaining version numbers with invalid values
2665 for (i=3; i<num_versions; ++i)
2666 versions[i] = UINT32_MAX;
2667 }
2668 // The LC_ID_DYLIB load command has a version with 3 version numbers
2669 // in it, so always return 3
2670 return 3;
Greg Clayton49f4bf22012-02-22 19:41:02 +00002671 }
Greg Clayton49f4bf22012-02-22 19:41:02 +00002672 }
2673 return false;
2674}
2675
Chris Lattner24943d22010-06-08 16:52:24 +00002676bool
Greg Clayton395fc332011-02-15 21:59:32 +00002677ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +00002678{
Greg Clayton9482f052012-03-13 23:14:29 +00002679 ModuleSP module_sp(GetModule());
2680 if (module_sp)
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002681 {
Greg Clayton9482f052012-03-13 23:14:29 +00002682 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2683 arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
2684
2685 // Files with type MH_PRELOAD are currently used in cases where the image
2686 // debugs at the addresses in the file itself. Below we set the OS to
2687 // unknown to make sure we use the DynamicLoaderStatic()...
2688 if (m_header.filetype == HeaderFileTypePreloadedExecutable)
2689 {
2690 arch.GetTriple().setOS (llvm::Triple::UnknownOS);
2691 }
2692 return true;
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002693 }
Greg Clayton9482f052012-03-13 23:14:29 +00002694 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00002695}
2696
2697
2698//------------------------------------------------------------------
2699// PluginInterface protocol
2700//------------------------------------------------------------------
2701const char *
2702ObjectFileMachO::GetPluginName()
2703{
2704 return "ObjectFileMachO";
2705}
2706
2707const char *
2708ObjectFileMachO::GetShortPluginName()
2709{
2710 return GetPluginNameStatic();
2711}
2712
2713uint32_t
2714ObjectFileMachO::GetPluginVersion()
2715{
2716 return 1;
2717}
2718