blob: c845d098a5e782600792f3fd5fb58518e92918e7 [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"
Greg Clayton6f7f8da2012-04-24 03:06:13 +000020#include "lldb/Core/RangeMap.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Section.h"
22#include "lldb/Core/StreamFile.h"
23#include "lldb/Core/StreamString.h"
24#include "lldb/Core/Timer.h"
25#include "lldb/Core/UUID.h"
Greg Claytondf6dc882012-01-05 03:57:59 +000026#include "lldb/Host/Host.h"
27#include "lldb/Host/FileSpec.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000028#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000029#include "lldb/Symbol/ObjectFile.h"
Greg Clayton29021d32012-04-18 05:19:20 +000030#include "lldb/Target/Platform.h"
Greg Claytonb5a8f142012-02-05 02:38:54 +000031#include "lldb/Target/Process.h"
Greg Clayton29021d32012-04-18 05:19:20 +000032#include "lldb/Target/Target.h"
Greg Clayton9ce95382012-02-13 23:10:39 +000033#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
34#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
Greg Clayton46c9a352012-02-09 06:16:32 +000035#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
Chris Lattner24943d22010-06-08 16:52:24 +000037
38using namespace lldb;
39using namespace lldb_private;
Greg Clayton1674b122010-07-21 22:12:05 +000040using namespace llvm::MachO;
Chris Lattner24943d22010-06-08 16:52:24 +000041
Greg Clayton46c9a352012-02-09 06:16:32 +000042class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
43{
44public:
45 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
46 RegisterContextDarwin_x86_64 (thread, 0)
47 {
48 SetRegisterDataFrom_LC_THREAD (data);
49 }
50
51 virtual void
52 InvalidateAllRegisters ()
53 {
54 // Do nothing... registers are always valid...
55 }
56
57 void
58 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
59 {
Greg Clayton46c9a352012-02-09 06:16:32 +000060 uint32_t offset = 0;
61 SetError (GPRRegSet, Read, -1);
62 SetError (FPURegSet, Read, -1);
63 SetError (EXCRegSet, Read, -1);
Greg Clayton9ce95382012-02-13 23:10:39 +000064 bool done = false;
65
66 while (!done)
Greg Clayton46c9a352012-02-09 06:16:32 +000067 {
Greg Clayton9ce95382012-02-13 23:10:39 +000068 int flavor = data.GetU32 (&offset);
69 if (flavor == 0)
70 done = true;
71 else
Greg Clayton46c9a352012-02-09 06:16:32 +000072 {
Greg Clayton9ce95382012-02-13 23:10:39 +000073 uint32_t i;
74 uint32_t count = data.GetU32 (&offset);
75 switch (flavor)
76 {
77 case GPRRegSet:
78 for (i=0; i<count; ++i)
79 (&gpr.rax)[i] = data.GetU64(&offset);
80 SetError (GPRRegSet, Read, 0);
81 done = true;
82
83 break;
84 case FPURegSet:
85 // TODO: fill in FPU regs....
86 //SetError (FPURegSet, Read, -1);
87 done = true;
88
89 break;
90 case EXCRegSet:
91 exc.trapno = data.GetU32(&offset);
92 exc.err = data.GetU32(&offset);
93 exc.faultvaddr = data.GetU64(&offset);
94 SetError (EXCRegSet, Read, 0);
95 done = true;
96 break;
97 case 7:
98 case 8:
99 case 9:
100 // fancy flavors that encapsulate of the the above
101 // falvors...
102 break;
103
104 default:
105 done = true;
106 break;
107 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000108 }
Greg Clayton9ce95382012-02-13 23:10:39 +0000109 }
110 }
111protected:
112 virtual int
113 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
114 {
115 return 0;
116 }
117
118 virtual int
119 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
120 {
121 return 0;
122 }
123
124 virtual int
125 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
126 {
127 return 0;
128 }
129
130 virtual int
131 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
132 {
133 return 0;
134 }
135
136 virtual int
137 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
138 {
139 return 0;
140 }
141
142 virtual int
143 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
144 {
145 return 0;
146 }
147};
Greg Clayton46c9a352012-02-09 06:16:32 +0000148
Greg Clayton9ce95382012-02-13 23:10:39 +0000149
150class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
151{
152public:
153 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
154 RegisterContextDarwin_i386 (thread, 0)
155 {
156 SetRegisterDataFrom_LC_THREAD (data);
157 }
158
159 virtual void
160 InvalidateAllRegisters ()
161 {
162 // Do nothing... registers are always valid...
163 }
164
165 void
166 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
167 {
168 uint32_t offset = 0;
169 SetError (GPRRegSet, Read, -1);
170 SetError (FPURegSet, Read, -1);
171 SetError (EXCRegSet, Read, -1);
172 bool done = false;
173
174 while (!done)
175 {
176 int flavor = data.GetU32 (&offset);
177 if (flavor == 0)
178 done = true;
179 else
Greg Clayton46c9a352012-02-09 06:16:32 +0000180 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000181 uint32_t i;
182 uint32_t count = data.GetU32 (&offset);
183 switch (flavor)
184 {
185 case GPRRegSet:
186 for (i=0; i<count; ++i)
187 (&gpr.eax)[i] = data.GetU32(&offset);
188 SetError (GPRRegSet, Read, 0);
189 done = true;
190
191 break;
192 case FPURegSet:
193 // TODO: fill in FPU regs....
194 //SetError (FPURegSet, Read, -1);
195 done = true;
196
197 break;
198 case EXCRegSet:
199 exc.trapno = data.GetU32(&offset);
200 exc.err = data.GetU32(&offset);
201 exc.faultvaddr = data.GetU32(&offset);
202 SetError (EXCRegSet, Read, 0);
203 done = true;
204 break;
205 case 7:
206 case 8:
207 case 9:
208 // fancy flavors that encapsulate of the the above
209 // falvors...
210 break;
211
212 default:
213 done = true;
214 break;
215 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000216 }
217 }
218 }
219protected:
220 virtual int
221 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
222 {
223 return 0;
224 }
225
226 virtual int
227 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
228 {
229 return 0;
230 }
231
232 virtual int
233 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
234 {
235 return 0;
236 }
237
238 virtual int
239 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
240 {
241 return 0;
242 }
243
244 virtual int
245 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
246 {
247 return 0;
248 }
249
250 virtual int
251 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
252 {
253 return 0;
254 }
255};
256
Greg Clayton9ce95382012-02-13 23:10:39 +0000257class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
258{
259public:
260 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
261 RegisterContextDarwin_arm (thread, 0)
262 {
263 SetRegisterDataFrom_LC_THREAD (data);
264 }
265
266 virtual void
267 InvalidateAllRegisters ()
268 {
269 // Do nothing... registers are always valid...
270 }
271
272 void
273 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
274 {
275 uint32_t offset = 0;
276 SetError (GPRRegSet, Read, -1);
277 SetError (FPURegSet, Read, -1);
278 SetError (EXCRegSet, Read, -1);
279 int flavor = data.GetU32 (&offset);
280 uint32_t count = data.GetU32 (&offset);
281 switch (flavor)
282 {
283 case GPRRegSet:
284 for (uint32_t i=0; i<count; ++i)
285 gpr.r[i] = data.GetU32(&offset);
286 SetError (GPRRegSet, Read, 0);
287 break;
288 case FPURegSet:
289 // TODO: fill in FPU regs....
290 //SetError (FPURegSet, Read, -1);
291 break;
292 case EXCRegSet:
293 exc.exception = data.GetU32(&offset);
294 exc.fsr = data.GetU32(&offset);
295 exc.far = data.GetU32(&offset);
296 SetError (EXCRegSet, Read, 0);
297 break;
298 }
299 }
300protected:
301 virtual int
302 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
303 {
304 return 0;
305 }
306
307 virtual int
308 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
309 {
310 return 0;
311 }
312
313 virtual int
314 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
315 {
316 return 0;
317 }
318
319 virtual int
320 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
321 {
322 return 0;
323 }
324
325 virtual int
326 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
327 {
328 return 0;
329 }
330
331 virtual int
332 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
333 {
334 return 0;
335 }
336};
337
Greg Claytonb1888f22011-03-19 01:12:21 +0000338#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner24943d22010-06-08 16:52:24 +0000339
340void
341ObjectFileMachO::Initialize()
342{
343 PluginManager::RegisterPlugin (GetPluginNameStatic(),
344 GetPluginDescriptionStatic(),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000345 CreateInstance,
346 CreateMemoryInstance);
Chris Lattner24943d22010-06-08 16:52:24 +0000347}
348
349void
350ObjectFileMachO::Terminate()
351{
352 PluginManager::UnregisterPlugin (CreateInstance);
353}
354
355
356const char *
357ObjectFileMachO::GetPluginNameStatic()
358{
359 return "object-file.mach-o";
360}
361
362const char *
363ObjectFileMachO::GetPluginDescriptionStatic()
364{
365 return "Mach-o object file reader (32 and 64 bit)";
366}
367
368
369ObjectFile *
Greg Clayton3508c382012-02-24 01:59:29 +0000370ObjectFileMachO::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 +0000371{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000372 if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length))
Chris Lattner24943d22010-06-08 16:52:24 +0000373 {
Greg Clayton3508c382012-02-24 01:59:29 +0000374 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, file, offset, length));
Chris Lattner24943d22010-06-08 16:52:24 +0000375 if (objfile_ap.get() && objfile_ap->ParseHeader())
376 return objfile_ap.release();
377 }
378 return NULL;
379}
380
Greg Claytonb5a8f142012-02-05 02:38:54 +0000381ObjectFile *
Greg Clayton3508c382012-02-24 01:59:29 +0000382ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000383 DataBufferSP& data_sp,
384 const ProcessSP &process_sp,
385 lldb::addr_t header_addr)
386{
387 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
388 {
Greg Clayton3508c382012-02-24 01:59:29 +0000389 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonb5a8f142012-02-05 02:38:54 +0000390 if (objfile_ap.get() && objfile_ap->ParseHeader())
391 return objfile_ap.release();
392 }
393 return NULL;
394}
395
396
397const ConstString &
398ObjectFileMachO::GetSegmentNameTEXT()
399{
400 static ConstString g_segment_name_TEXT ("__TEXT");
401 return g_segment_name_TEXT;
402}
403
404const ConstString &
405ObjectFileMachO::GetSegmentNameDATA()
406{
407 static ConstString g_segment_name_DATA ("__DATA");
408 return g_segment_name_DATA;
409}
410
411const ConstString &
412ObjectFileMachO::GetSegmentNameOBJC()
413{
414 static ConstString g_segment_name_OBJC ("__OBJC");
415 return g_segment_name_OBJC;
416}
417
418const ConstString &
419ObjectFileMachO::GetSegmentNameLINKEDIT()
420{
421 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
422 return g_section_name_LINKEDIT;
423}
424
425const ConstString &
426ObjectFileMachO::GetSectionNameEHFrame()
427{
428 static ConstString g_section_name_eh_frame ("__eh_frame");
429 return g_section_name_eh_frame;
430}
431
432
Chris Lattner24943d22010-06-08 16:52:24 +0000433
434static uint32_t
435MachHeaderSizeFromMagic(uint32_t magic)
436{
437 switch (magic)
438 {
Greg Clayton1674b122010-07-21 22:12:05 +0000439 case HeaderMagic32:
440 case HeaderMagic32Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000441 return sizeof(struct mach_header);
442
Greg Clayton1674b122010-07-21 22:12:05 +0000443 case HeaderMagic64:
444 case HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000445 return sizeof(struct mach_header_64);
446 break;
447
448 default:
449 break;
450 }
451 return 0;
452}
453
454
455bool
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000456ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
457 lldb::addr_t data_offset,
458 lldb::addr_t data_length)
Chris Lattner24943d22010-06-08 16:52:24 +0000459{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000460 DataExtractor data;
461 data.SetData (data_sp, data_offset, data_length);
Chris Lattner24943d22010-06-08 16:52:24 +0000462 uint32_t offset = 0;
463 uint32_t magic = data.GetU32(&offset);
464 return MachHeaderSizeFromMagic(magic) != 0;
465}
466
467
Greg Clayton3508c382012-02-24 01:59:29 +0000468ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) :
469 ObjectFile(module_sp, file, offset, length, data_sp),
Chris Lattner24943d22010-06-08 16:52:24 +0000470 m_sections_ap(),
Jim Ingham28775942011-03-07 23:44:08 +0000471 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000472 m_mach_segments(),
473 m_mach_sections(),
474 m_entry_point_address(),
475 m_thread_context_offsets(),
476 m_thread_context_offsets_valid(false)
Chris Lattner24943d22010-06-08 16:52:24 +0000477{
Greg Claytonddff7cc2011-02-04 21:13:05 +0000478 ::memset (&m_header, 0, sizeof(m_header));
479 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner24943d22010-06-08 16:52:24 +0000480}
481
Greg Clayton3508c382012-02-24 01:59:29 +0000482ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000483 lldb::DataBufferSP& header_data_sp,
484 const lldb::ProcessSP &process_sp,
485 lldb::addr_t header_addr) :
Greg Clayton3508c382012-02-24 01:59:29 +0000486 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000487 m_sections_ap(),
488 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000489 m_mach_segments(),
490 m_mach_sections(),
491 m_entry_point_address(),
492 m_thread_context_offsets(),
493 m_thread_context_offsets_valid(false)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000494{
495 ::memset (&m_header, 0, sizeof(m_header));
496 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
497}
Chris Lattner24943d22010-06-08 16:52:24 +0000498
499ObjectFileMachO::~ObjectFileMachO()
500{
501}
502
503
504bool
505ObjectFileMachO::ParseHeader ()
506{
Greg Clayton9482f052012-03-13 23:14:29 +0000507 ModuleSP module_sp(GetModule());
508 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000509 {
Greg Clayton9482f052012-03-13 23:14:29 +0000510 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
511 bool can_parse = false;
512 uint32_t offset = 0;
Greg Claytoncd548032011-02-01 01:31:41 +0000513 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Greg Clayton9482f052012-03-13 23:14:29 +0000514 // Leave magic in the original byte order
515 m_header.magic = m_data.GetU32(&offset);
516 switch (m_header.magic)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000517 {
Greg Clayton9482f052012-03-13 23:14:29 +0000518 case HeaderMagic32:
519 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
520 m_data.SetAddressByteSize(4);
521 can_parse = true;
522 break;
523
524 case HeaderMagic64:
525 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
526 m_data.SetAddressByteSize(8);
527 can_parse = true;
528 break;
529
530 case HeaderMagic32Swapped:
531 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
532 m_data.SetAddressByteSize(4);
533 can_parse = true;
534 break;
535
536 case HeaderMagic64Swapped:
537 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
538 m_data.SetAddressByteSize(8);
539 can_parse = true;
540 break;
541
542 default:
543 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +0000544 }
Greg Clayton9482f052012-03-13 23:14:29 +0000545
546 if (can_parse)
547 {
548 m_data.GetU32(&offset, &m_header.cputype, 6);
549
550 ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
551
552 if (SetModulesArchitecture (mach_arch))
553 {
554 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
555 if (m_data.GetByteSize() < header_and_lc_size)
556 {
557 DataBufferSP data_sp;
558 ProcessSP process_sp (m_process_wp.lock());
559 if (process_sp)
560 {
561 data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
562 }
563 else
564 {
565 // Read in all only the load command data from the file on disk
566 data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
567 if (data_sp->GetByteSize() != header_and_lc_size)
568 return false;
569 }
570 if (data_sp)
571 m_data.SetData (data_sp);
572 }
573 }
574 return true;
575 }
576 else
577 {
578 memset(&m_header, 0, sizeof(struct mach_header));
579 }
Chris Lattner24943d22010-06-08 16:52:24 +0000580 }
581 return false;
582}
583
584
585ByteOrder
586ObjectFileMachO::GetByteOrder () const
587{
Chris Lattner24943d22010-06-08 16:52:24 +0000588 return m_data.GetByteOrder ();
589}
590
Jim Ingham7508e732010-08-09 23:31:02 +0000591bool
592ObjectFileMachO::IsExecutable() const
593{
594 return m_header.filetype == HeaderFileTypeExecutable;
595}
Chris Lattner24943d22010-06-08 16:52:24 +0000596
597size_t
598ObjectFileMachO::GetAddressByteSize () const
599{
Chris Lattner24943d22010-06-08 16:52:24 +0000600 return m_data.GetAddressByteSize ();
601}
602
Greg Claytonb3448432011-03-24 21:19:54 +0000603AddressClass
Greg Claytonb1888f22011-03-19 01:12:21 +0000604ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
605{
606 Symtab *symtab = GetSymtab();
607 if (symtab)
608 {
609 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
610 if (symbol)
611 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000612 if (symbol->ValueIsAddress())
Greg Claytonb1888f22011-03-19 01:12:21 +0000613 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000614 SectionSP section_sp (symbol->GetAddress().GetSection());
Greg Clayton3508c382012-02-24 01:59:29 +0000615 if (section_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000616 {
Greg Clayton3508c382012-02-24 01:59:29 +0000617 const SectionType section_type = section_sp->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000618 switch (section_type)
619 {
620 case eSectionTypeInvalid: return eAddressClassUnknown;
621 case eSectionTypeCode:
622 if (m_header.cputype == llvm::MachO::CPUTypeARM)
623 {
624 // For ARM we have a bit in the n_desc field of the symbol
625 // that tells us ARM/Thumb which is bit 0x0008.
626 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
627 return eAddressClassCodeAlternateISA;
628 }
629 return eAddressClassCode;
630
631 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000632 case eSectionTypeData:
633 case eSectionTypeDataCString:
634 case eSectionTypeDataCStringPointers:
635 case eSectionTypeDataSymbolAddress:
636 case eSectionTypeData4:
637 case eSectionTypeData8:
638 case eSectionTypeData16:
639 case eSectionTypeDataPointers:
640 case eSectionTypeZeroFill:
641 case eSectionTypeDataObjCMessageRefs:
642 case eSectionTypeDataObjCCFStrings:
643 return eAddressClassData;
644 case eSectionTypeDebug:
645 case eSectionTypeDWARFDebugAbbrev:
646 case eSectionTypeDWARFDebugAranges:
647 case eSectionTypeDWARFDebugFrame:
648 case eSectionTypeDWARFDebugInfo:
649 case eSectionTypeDWARFDebugLine:
650 case eSectionTypeDWARFDebugLoc:
651 case eSectionTypeDWARFDebugMacInfo:
652 case eSectionTypeDWARFDebugPubNames:
653 case eSectionTypeDWARFDebugPubTypes:
654 case eSectionTypeDWARFDebugRanges:
655 case eSectionTypeDWARFDebugStr:
656 case eSectionTypeDWARFAppleNames:
657 case eSectionTypeDWARFAppleTypes:
658 case eSectionTypeDWARFAppleNamespaces:
659 case eSectionTypeDWARFAppleObjC:
660 return eAddressClassDebug;
Greg Claytonb1888f22011-03-19 01:12:21 +0000661 case eSectionTypeEHFrame: return eAddressClassRuntime;
662 case eSectionTypeOther: return eAddressClassUnknown;
663 }
664 }
665 }
666
Greg Claytonb3448432011-03-24 21:19:54 +0000667 const SymbolType symbol_type = symbol->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000668 switch (symbol_type)
669 {
670 case eSymbolTypeAny: return eAddressClassUnknown;
671 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Greg Claytonb1888f22011-03-19 01:12:21 +0000672
673 case eSymbolTypeCode:
674 case eSymbolTypeTrampoline:
675 if (m_header.cputype == llvm::MachO::CPUTypeARM)
676 {
677 // For ARM we have a bit in the n_desc field of the symbol
678 // that tells us ARM/Thumb which is bit 0x0008.
679 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
680 return eAddressClassCodeAlternateISA;
681 }
682 return eAddressClassCode;
683
684 case eSymbolTypeData: return eAddressClassData;
685 case eSymbolTypeRuntime: return eAddressClassRuntime;
686 case eSymbolTypeException: return eAddressClassRuntime;
687 case eSymbolTypeSourceFile: return eAddressClassDebug;
688 case eSymbolTypeHeaderFile: return eAddressClassDebug;
689 case eSymbolTypeObjectFile: return eAddressClassDebug;
690 case eSymbolTypeCommonBlock: return eAddressClassDebug;
691 case eSymbolTypeBlock: return eAddressClassDebug;
692 case eSymbolTypeLocal: return eAddressClassData;
693 case eSymbolTypeParam: return eAddressClassData;
694 case eSymbolTypeVariable: return eAddressClassData;
695 case eSymbolTypeVariableType: return eAddressClassDebug;
696 case eSymbolTypeLineEntry: return eAddressClassDebug;
697 case eSymbolTypeLineHeader: return eAddressClassDebug;
698 case eSymbolTypeScopeBegin: return eAddressClassDebug;
699 case eSymbolTypeScopeEnd: return eAddressClassDebug;
700 case eSymbolTypeAdditional: return eAddressClassUnknown;
701 case eSymbolTypeCompiler: return eAddressClassDebug;
702 case eSymbolTypeInstrumentation:return eAddressClassDebug;
703 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton3f69eac2011-12-03 02:30:59 +0000704 case eSymbolTypeObjCClass: return eAddressClassRuntime;
705 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
706 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Claytonb1888f22011-03-19 01:12:21 +0000707 }
708 }
709 }
710 return eAddressClassUnknown;
711}
Chris Lattner24943d22010-06-08 16:52:24 +0000712
713Symtab *
714ObjectFileMachO::GetSymtab()
715{
Greg Clayton9482f052012-03-13 23:14:29 +0000716 ModuleSP module_sp(GetModule());
717 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000718 {
Greg Clayton9482f052012-03-13 23:14:29 +0000719 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
720 if (m_symtab_ap.get() == NULL)
721 {
722 m_symtab_ap.reset(new Symtab(this));
723 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
724 ParseSymtab (true);
725 m_symtab_ap->Finalize ();
726 }
Chris Lattner24943d22010-06-08 16:52:24 +0000727 }
728 return m_symtab_ap.get();
729}
730
731
732SectionList *
733ObjectFileMachO::GetSectionList()
734{
Greg Clayton9482f052012-03-13 23:14:29 +0000735 ModuleSP module_sp(GetModule());
736 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000737 {
Greg Clayton9482f052012-03-13 23:14:29 +0000738 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
739 if (m_sections_ap.get() == NULL)
740 {
741 m_sections_ap.reset(new SectionList());
742 ParseSections();
743 }
Chris Lattner24943d22010-06-08 16:52:24 +0000744 }
745 return m_sections_ap.get();
746}
747
748
749size_t
750ObjectFileMachO::ParseSections ()
751{
752 lldb::user_id_t segID = 0;
753 lldb::user_id_t sectID = 0;
754 struct segment_command_64 load_cmd;
755 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
756 uint32_t i;
Greg Clayton46c9a352012-02-09 06:16:32 +0000757 const bool is_core = GetType() == eTypeCoreFile;
Chris Lattner24943d22010-06-08 16:52:24 +0000758 //bool dump_sections = false;
Greg Clayton3508c382012-02-24 01:59:29 +0000759 ModuleSP module_sp (GetModule());
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000760 // First look up any LC_ENCRYPTION_INFO load commands
761 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
762 EncryptedFileRanges encrypted_file_ranges;
763 for (i=0; i<m_header.ncmds; ++i)
764 {
765 const uint32_t load_cmd_offset = offset;
766 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
767 break;
768
769 if (load_cmd.cmd == LoadCommandEncryptionInfo)
770 {
771 EncryptedFileRanges::Entry entry;
772 entry.SetRangeBase(m_data.GetU32(&offset));
773 entry.SetByteSize(m_data.GetU32(&offset));
774 encrypted_file_ranges.Append(entry);
775 }
776 offset = load_cmd_offset + load_cmd.cmdsize;
777 }
778
779 offset = MachHeaderSizeFromMagic(m_header.magic);
780
Chris Lattner24943d22010-06-08 16:52:24 +0000781 for (i=0; i<m_header.ncmds; ++i)
782 {
783 const uint32_t load_cmd_offset = offset;
784 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
785 break;
786
Greg Clayton1674b122010-07-21 22:12:05 +0000787 if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
Chris Lattner24943d22010-06-08 16:52:24 +0000788 {
789 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
790 {
791 load_cmd.vmaddr = m_data.GetAddress(&offset);
792 load_cmd.vmsize = m_data.GetAddress(&offset);
793 load_cmd.fileoff = m_data.GetAddress(&offset);
794 load_cmd.filesize = m_data.GetAddress(&offset);
795 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
796 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000797
798 const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
799
Chris Lattner24943d22010-06-08 16:52:24 +0000800 // Keep a list of mach segments around in case we need to
801 // get at data that isn't stored in the abstracted Sections.
802 m_mach_segments.push_back (load_cmd);
803
804 ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
805 // Use a segment ID of the segment index shifted left by 8 so they
806 // never conflict with any of the sections.
807 SectionSP segment_sp;
Greg Clayton46c9a352012-02-09 06:16:32 +0000808 if (segment_name || is_core)
Chris Lattner24943d22010-06-08 16:52:24 +0000809 {
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000810 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
Chris Lattner24943d22010-06-08 16:52:24 +0000811 ++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
812 segment_name, // Name of this section
813 eSectionTypeContainer, // This section is a container of other sections.
814 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
815 load_cmd.vmsize, // VM size in bytes of this section
816 load_cmd.fileoff, // Offset to the data for this section in the file
817 load_cmd.filesize, // Size in bytes of this section as found in the the file
818 load_cmd.flags)); // Flags for this section
819
Greg Clayton68ca8232011-01-25 02:58:48 +0000820 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000821 m_sections_ap->AddSection(segment_sp);
822 }
823
824 struct section_64 sect64;
Greg Claytonddff7cc2011-02-04 21:13:05 +0000825 ::memset (&sect64, 0, sizeof(sect64));
Chris Lattner24943d22010-06-08 16:52:24 +0000826 // Push a section into our mach sections for the section at
Greg Clayton6af4fad2010-10-06 01:26:32 +0000827 // index zero (NListSectionNoSection) if we don't have any
828 // mach sections yet...
829 if (m_mach_sections.empty())
830 m_mach_sections.push_back(sect64);
Chris Lattner24943d22010-06-08 16:52:24 +0000831 uint32_t segment_sect_idx;
832 const lldb::user_id_t first_segment_sectID = sectID + 1;
833
834
Greg Clayton1674b122010-07-21 22:12:05 +0000835 const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
Chris Lattner24943d22010-06-08 16:52:24 +0000836 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
837 {
838 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
839 break;
840 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
841 break;
842 sect64.addr = m_data.GetAddress(&offset);
843 sect64.size = m_data.GetAddress(&offset);
844
845 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
846 break;
847
848 // Keep a list of mach sections around in case we need to
849 // get at data that isn't stored in the abstracted Sections.
850 m_mach_sections.push_back (sect64);
851
852 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
853 if (!segment_name)
854 {
855 // We have a segment with no name so we need to conjure up
856 // segments that correspond to the section's segname if there
857 // isn't already such a section. If there is such a section,
858 // we resize the section so that it spans all sections.
859 // We also mark these sections as fake so address matches don't
860 // hit if they land in the gaps between the child sections.
861 segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
862 segment_sp = m_sections_ap->FindSectionByName (segment_name);
863 if (segment_sp.get())
864 {
865 Section *segment = segment_sp.get();
866 // Grow the section size as needed.
867 const lldb::addr_t sect64_min_addr = sect64.addr;
868 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
869 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
870 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
871 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
872 if (sect64_min_addr >= curr_seg_min_addr)
873 {
874 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
875 // Only grow the section size if needed
876 if (new_seg_byte_size > curr_seg_byte_size)
877 segment->SetByteSize (new_seg_byte_size);
878 }
879 else
880 {
881 // We need to change the base address of the segment and
882 // adjust the child section offsets for all existing children.
883 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
884 segment->Slide(slide_amount, false);
885 segment->GetChildren().Slide (-slide_amount, false);
886 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
887 }
Greg Clayton661825b2010-06-28 23:51:11 +0000888
889 // Grow the section size as needed.
890 if (sect64.offset)
891 {
892 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
893 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
894
895 const lldb::addr_t section_min_file_offset = sect64.offset;
896 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
897 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
898 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
899 segment->SetFileOffset (new_file_offset);
900 segment->SetFileSize (new_file_size);
901 }
Chris Lattner24943d22010-06-08 16:52:24 +0000902 }
903 else
904 {
905 // Create a fake section for the section's named segment
Greg Clayton3508c382012-02-24 01:59:29 +0000906 segment_sp.reset(new Section (segment_sp, // Parent section
907 module_sp, // Module to which this section belongs
908 ++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
909 segment_name, // Name of this section
910 eSectionTypeContainer, // This section is a container of other sections.
911 sect64.addr, // File VM address == addresses as they are found in the object file
912 sect64.size, // VM size in bytes of this section
913 sect64.offset, // Offset to the data for this section in the file
914 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
915 load_cmd.flags)); // Flags for this section
Chris Lattner24943d22010-06-08 16:52:24 +0000916 segment_sp->SetIsFake(true);
917 m_sections_ap->AddSection(segment_sp);
Greg Clayton68ca8232011-01-25 02:58:48 +0000918 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000919 }
920 }
921 assert (segment_sp.get());
922
Greg Clayton1674b122010-07-21 22:12:05 +0000923 uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
Chris Lattner24943d22010-06-08 16:52:24 +0000924 static ConstString g_sect_name_objc_data ("__objc_data");
925 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
926 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
927 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
928 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
929 static ConstString g_sect_name_objc_const ("__objc_const");
930 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
931 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000932
933 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
934 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
935 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
936 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
937 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
938 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
939 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
940 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
941 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
942 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
943 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
Greg Claytonf6e3de22011-09-28 17:06:40 +0000944 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
945 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
Greg Clayton00db2152011-10-04 22:41:51 +0000946 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
Greg Clayton24a6bd92011-10-27 17:55:14 +0000947 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000948 static ConstString g_sect_name_eh_frame ("__eh_frame");
Greg Clayton3fed8b92010-10-08 00:21:05 +0000949 static ConstString g_sect_name_DATA ("__DATA");
950 static ConstString g_sect_name_TEXT ("__TEXT");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000951
Chris Lattner24943d22010-06-08 16:52:24 +0000952 SectionType sect_type = eSectionTypeOther;
953
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000954 if (section_name == g_sect_name_dwarf_debug_abbrev)
955 sect_type = eSectionTypeDWARFDebugAbbrev;
956 else if (section_name == g_sect_name_dwarf_debug_aranges)
957 sect_type = eSectionTypeDWARFDebugAranges;
958 else if (section_name == g_sect_name_dwarf_debug_frame)
959 sect_type = eSectionTypeDWARFDebugFrame;
960 else if (section_name == g_sect_name_dwarf_debug_info)
961 sect_type = eSectionTypeDWARFDebugInfo;
962 else if (section_name == g_sect_name_dwarf_debug_line)
963 sect_type = eSectionTypeDWARFDebugLine;
964 else if (section_name == g_sect_name_dwarf_debug_loc)
965 sect_type = eSectionTypeDWARFDebugLoc;
966 else if (section_name == g_sect_name_dwarf_debug_macinfo)
967 sect_type = eSectionTypeDWARFDebugMacInfo;
968 else if (section_name == g_sect_name_dwarf_debug_pubnames)
969 sect_type = eSectionTypeDWARFDebugPubNames;
970 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
971 sect_type = eSectionTypeDWARFDebugPubTypes;
972 else if (section_name == g_sect_name_dwarf_debug_ranges)
973 sect_type = eSectionTypeDWARFDebugRanges;
974 else if (section_name == g_sect_name_dwarf_debug_str)
975 sect_type = eSectionTypeDWARFDebugStr;
Greg Claytonf6e3de22011-09-28 17:06:40 +0000976 else if (section_name == g_sect_name_dwarf_apple_names)
977 sect_type = eSectionTypeDWARFAppleNames;
978 else if (section_name == g_sect_name_dwarf_apple_types)
979 sect_type = eSectionTypeDWARFAppleTypes;
Greg Clayton00db2152011-10-04 22:41:51 +0000980 else if (section_name == g_sect_name_dwarf_apple_namespaces)
981 sect_type = eSectionTypeDWARFAppleNamespaces;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000982 else if (section_name == g_sect_name_dwarf_apple_objc)
983 sect_type = eSectionTypeDWARFAppleObjC;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000984 else if (section_name == g_sect_name_objc_selrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000985 sect_type = eSectionTypeDataCStringPointers;
Chris Lattner24943d22010-06-08 16:52:24 +0000986 else if (section_name == g_sect_name_objc_msgrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000987 sect_type = eSectionTypeDataObjCMessageRefs;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000988 else if (section_name == g_sect_name_eh_frame)
989 sect_type = eSectionTypeEHFrame;
990 else if (section_name == g_sect_name_cfstring)
991 sect_type = eSectionTypeDataObjCCFStrings;
Chris Lattner24943d22010-06-08 16:52:24 +0000992 else if (section_name == g_sect_name_objc_data ||
993 section_name == g_sect_name_objc_classrefs ||
994 section_name == g_sect_name_objc_superrefs ||
995 section_name == g_sect_name_objc_const ||
996 section_name == g_sect_name_objc_classlist)
997 {
998 sect_type = eSectionTypeDataPointers;
999 }
Chris Lattner24943d22010-06-08 16:52:24 +00001000
1001 if (sect_type == eSectionTypeOther)
1002 {
1003 switch (mach_sect_type)
1004 {
1005 // TODO: categorize sections by other flags for regular sections
Greg Clayton3fed8b92010-10-08 00:21:05 +00001006 case SectionTypeRegular:
1007 if (segment_sp->GetName() == g_sect_name_TEXT)
1008 sect_type = eSectionTypeCode;
1009 else if (segment_sp->GetName() == g_sect_name_DATA)
1010 sect_type = eSectionTypeData;
1011 else
1012 sect_type = eSectionTypeOther;
1013 break;
Greg Clayton1674b122010-07-21 22:12:05 +00001014 case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
1015 case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1016 case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1017 case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1018 case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1019 case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1020 case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1021 case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1022 case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1023 case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1024 case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
1025 case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
1026 case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1027 case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1028 case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
1029 case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
Chris Lattner24943d22010-06-08 16:52:24 +00001030 default: break;
1031 }
1032 }
1033
Greg Clayton3508c382012-02-24 01:59:29 +00001034 SectionSP section_sp(new Section (segment_sp,
1035 module_sp,
1036 ++sectID,
1037 section_name,
1038 sect_type,
1039 sect64.addr - segment_sp->GetFileAddress(),
1040 sect64.size,
1041 sect64.offset,
1042 sect64.offset == 0 ? 0 : sect64.size,
1043 sect64.flags));
Greg Clayton68ca8232011-01-25 02:58:48 +00001044 // Set the section to be encrypted to match the segment
Greg Clayton6f7f8da2012-04-24 03:06:13 +00001045
1046 bool section_is_encrypted = false;
1047 if (!segment_is_encrypted && load_cmd.filesize != 0)
1048 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
Greg Clayton68ca8232011-01-25 02:58:48 +00001049
Greg Clayton6f7f8da2012-04-24 03:06:13 +00001050 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +00001051 segment_sp->GetChildren().AddSection(section_sp);
1052
1053 if (segment_sp->IsFake())
1054 {
1055 segment_sp.reset();
1056 segment_name.Clear();
1057 }
1058 }
Greg Clayton0fa51242011-07-19 03:57:15 +00001059 if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
Chris Lattner24943d22010-06-08 16:52:24 +00001060 {
1061 if (first_segment_sectID <= sectID)
1062 {
1063 lldb::user_id_t sect_uid;
1064 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
1065 {
1066 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1067 SectionSP next_section_sp;
1068 if (sect_uid + 1 <= sectID)
1069 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1070
1071 if (curr_section_sp.get())
1072 {
1073 if (curr_section_sp->GetByteSize() == 0)
1074 {
1075 if (next_section_sp.get() != NULL)
1076 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1077 else
1078 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1079 }
1080 }
1081 }
1082 }
1083 }
1084 }
1085 }
1086 }
Greg Clayton1674b122010-07-21 22:12:05 +00001087 else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
Chris Lattner24943d22010-06-08 16:52:24 +00001088 {
1089 m_dysymtab.cmd = load_cmd.cmd;
1090 m_dysymtab.cmdsize = load_cmd.cmdsize;
1091 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1092 }
1093
1094 offset = load_cmd_offset + load_cmd.cmdsize;
1095 }
1096// if (dump_sections)
1097// {
1098// StreamFile s(stdout);
1099// m_sections_ap->Dump(&s, true);
1100// }
1101 return sectID; // Return the number of sections we registered with the module
1102}
1103
1104class MachSymtabSectionInfo
1105{
1106public:
1107
1108 MachSymtabSectionInfo (SectionList *section_list) :
1109 m_section_list (section_list),
1110 m_section_infos()
1111 {
1112 // Get the number of sections down to a depth of 1 to include
1113 // all segments and their sections, but no other sections that
1114 // may be added for debug map or
1115 m_section_infos.resize(section_list->GetNumSections(1));
1116 }
1117
1118
Greg Clayton3508c382012-02-24 01:59:29 +00001119 SectionSP
Chris Lattner24943d22010-06-08 16:52:24 +00001120 GetSection (uint8_t n_sect, addr_t file_addr)
1121 {
1122 if (n_sect == 0)
Greg Clayton3508c382012-02-24 01:59:29 +00001123 return SectionSP();
Chris Lattner24943d22010-06-08 16:52:24 +00001124 if (n_sect < m_section_infos.size())
1125 {
Greg Clayton3508c382012-02-24 01:59:29 +00001126 if (!m_section_infos[n_sect].section_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001127 {
Greg Clayton3508c382012-02-24 01:59:29 +00001128 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1129 m_section_infos[n_sect].section_sp = section_sp;
1130 if (section_sp != NULL)
Greg Clayton5638d2c2011-07-10 17:32:33 +00001131 {
Greg Clayton3508c382012-02-24 01:59:29 +00001132 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1133 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Clayton5638d2c2011-07-10 17:32:33 +00001134 }
1135 else
1136 {
Greg Claytondf6dc882012-01-05 03:57:59 +00001137 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Clayton5638d2c2011-07-10 17:32:33 +00001138 }
Chris Lattner24943d22010-06-08 16:52:24 +00001139 }
1140 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton811b9c52011-08-26 20:01:35 +00001141 {
1142 // Symbol is in section.
Greg Clayton3508c382012-02-24 01:59:29 +00001143 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001144 }
1145 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1146 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1147 {
1148 // Symbol is in section with zero size, but has the same start
1149 // address as the section. This can happen with linker symbols
1150 // (symbols that start with the letter 'l' or 'L'.
Greg Clayton3508c382012-02-24 01:59:29 +00001151 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001152 }
Chris Lattner24943d22010-06-08 16:52:24 +00001153 }
Greg Clayton3508c382012-02-24 01:59:29 +00001154 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner24943d22010-06-08 16:52:24 +00001155 }
1156
1157protected:
1158 struct SectionInfo
1159 {
1160 SectionInfo () :
1161 vm_range(),
Greg Clayton3508c382012-02-24 01:59:29 +00001162 section_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +00001163 {
1164 }
1165
1166 VMRange vm_range;
Greg Clayton3508c382012-02-24 01:59:29 +00001167 SectionSP section_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001168 };
1169 SectionList *m_section_list;
1170 std::vector<SectionInfo> m_section_infos;
1171};
1172
1173
1174
1175size_t
1176ObjectFileMachO::ParseSymtab (bool minimize)
1177{
1178 Timer scoped_timer(__PRETTY_FUNCTION__,
1179 "ObjectFileMachO::ParseSymtab () module = %s",
1180 m_file.GetFilename().AsCString(""));
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001181 ModuleSP module_sp (GetModule());
1182 if (!module_sp)
1183 return 0;
1184
1185 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
1186 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
1187 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
1188 FunctionStarts function_starts;
Chris Lattner24943d22010-06-08 16:52:24 +00001189 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1190 uint32_t i;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001191
Greg Clayton0fea0512011-12-30 00:32:24 +00001192 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
1193
Chris Lattner24943d22010-06-08 16:52:24 +00001194 for (i=0; i<m_header.ncmds; ++i)
1195 {
1196 const uint32_t cmd_offset = offset;
1197 // Read in the load command and load command size
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001198 struct load_command lc;
1199 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001200 break;
1201 // Watch for the symbol table load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001202 switch (lc.cmd)
Chris Lattner24943d22010-06-08 16:52:24 +00001203 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001204 case LoadCommandSymtab:
1205 symtab_load_command.cmd = lc.cmd;
1206 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00001207 // Read in the rest of the symtab load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001208 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
1209 return 0;
1210 if (symtab_load_command.symoff == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001211 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001212 if (log)
1213 module_sp->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
1214 return 0;
1215 }
1216
1217 if (symtab_load_command.stroff == 0)
1218 {
1219 if (log)
1220 module_sp->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
1221 return 0;
1222 }
1223
1224 if (symtab_load_command.nsyms == 0)
1225 {
1226 if (log)
1227 module_sp->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
1228 return 0;
1229 }
1230
1231 if (symtab_load_command.strsize == 0)
1232 {
1233 if (log)
1234 module_sp->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
1235 return 0;
1236 }
1237 break;
1238
1239 case LoadCommandFunctionStarts:
1240 function_starts_load_command.cmd = lc.cmd;
1241 function_starts_load_command.cmdsize = lc.cmdsize;
1242 if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
1243 bzero (&function_starts_load_command, sizeof(function_starts_load_command));
1244 break;
1245
1246 default:
1247 break;
1248 }
1249 offset = cmd_offset + lc.cmdsize;
1250 }
1251
1252 if (symtab_load_command.cmd)
1253 {
1254 Symtab *symtab = m_symtab_ap.get();
1255 SectionList *section_list = GetSectionList();
1256 if (section_list == NULL)
1257 return 0;
1258
1259 ProcessSP process_sp (m_process_wp.lock());
1260
1261 const size_t addr_byte_size = m_data.GetAddressByteSize();
1262 bool bit_width_32 = addr_byte_size == 4;
1263 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
1264
1265 DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1266 DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1267 DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1268
1269 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
1270 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
1271 if (process_sp)
1272 {
1273 Target &target = process_sp->GetTarget();
1274 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
1275 // Reading mach file from memory in a process or core file...
1276
1277 if (linkedit_section_sp)
1278 {
1279 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
1280 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
1281 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
1282 const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton29021d32012-04-18 05:19:20 +00001283
1284 bool data_was_read = false;
1285
1286#if defined (__APPLE__) && defined (__arm__)
1287 if (m_header.flags & 0x80000000u)
Greg Clayton0fea0512011-12-30 00:32:24 +00001288 {
Greg Clayton29021d32012-04-18 05:19:20 +00001289 // This mach-o memory file is in the dyld shared cache. If this
1290 // program is not remote and this is iOS, then this process will
1291 // share the same shared cache as the process we are debugging and
1292 // we can read the entire __LINKEDIT from the address space in this
1293 // process. This is a needed optimization that is used for local iOS
1294 // debugging only since all shared libraries in the shared cache do
1295 // not have corresponding files that exist in the file system of the
1296 // device. They have been combined into a single file. This means we
1297 // always have to load these files from memory. All of the symbol and
1298 // string tables from all of the __LINKEDIT sections from the shared
1299 // libraries in the shared cache have been merged into a single large
1300 // symbol and string table. Reading all of this symbol and string table
1301 // data across can slow down debug launch times, so we optimize this by
1302 // reading the memory for the __LINKEDIT section from this process.
1303 PlatformSP platform_sp (target.GetPlatform());
1304 if (platform_sp && platform_sp->IsHost())
1305 {
1306 data_was_read = true;
1307 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
1308 strtab_data.SetData((void *)stroff_addr, strtab_data_byte_size, eByteOrderLittle);
1309 if (function_starts_load_command.cmd)
1310 {
1311 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1312 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
1313 }
1314 }
1315 }
1316#endif
1317
1318 if (!data_was_read)
1319 {
1320 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
1321 if (nlist_data_sp)
1322 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
1323 DataBufferSP strtab_data_sp (ReadMemory (process_sp, stroff_addr, strtab_data_byte_size));
1324 if (strtab_data_sp)
1325 strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
1326 if (function_starts_load_command.cmd)
1327 {
1328 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1329 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
1330 if (func_start_data_sp)
1331 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
1332 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001333 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001334 }
1335 }
1336 else
1337 {
1338 nlist_data.SetData (m_data,
1339 symtab_load_command.symoff,
1340 nlist_data_byte_size);
1341 strtab_data.SetData (m_data,
1342 symtab_load_command.stroff,
1343 strtab_data_byte_size);
1344 if (function_starts_load_command.cmd)
1345 {
1346 function_starts_data.SetData (m_data,
1347 function_starts_load_command.dataoff,
1348 function_starts_load_command.datasize);
1349 }
1350 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001351
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001352 if (nlist_data.GetByteSize() == 0)
1353 {
1354 if (log)
1355 module_sp->LogMessage(log.get(), "failed to read nlist data");
1356 return 0;
1357 }
1358
1359
1360 if (strtab_data.GetByteSize() == 0)
1361 {
1362 if (log)
1363 module_sp->LogMessage(log.get(), "failed to read strtab data");
1364 return 0;
1365 }
1366
1367 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
1368 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
1369 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
1370 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
1371 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
1372 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
1373 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
1374 SectionSP eh_frame_section_sp;
1375 if (text_section_sp.get())
1376 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
1377 else
1378 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
1379
Greg Claytond2653c22012-03-14 01:53:24 +00001380 const bool is_arm = (m_header.cputype == llvm::MachO::CPUTypeARM);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001381 if (text_section_sp && function_starts_data.GetByteSize())
1382 {
1383 FunctionStarts::Entry function_start_entry;
1384 function_start_entry.data = false;
1385 uint32_t function_start_offset = 0;
1386 function_start_entry.addr = text_section_sp->GetFileAddress();
1387 uint64_t delta;
1388 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
1389 {
1390 // Now append the current entry
1391 function_start_entry.addr += delta;
1392 function_starts.Append(function_start_entry);
1393 }
1394 }
1395
1396 const uint32_t function_starts_count = function_starts.GetSize();
1397
1398 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
1399
1400 uint32_t nlist_data_offset = 0;
1401
1402 uint32_t N_SO_index = UINT32_MAX;
1403
1404 MachSymtabSectionInfo section_info (section_list);
1405 std::vector<uint32_t> N_FUN_indexes;
1406 std::vector<uint32_t> N_NSYM_indexes;
1407 std::vector<uint32_t> N_INCL_indexes;
1408 std::vector<uint32_t> N_BRAC_indexes;
1409 std::vector<uint32_t> N_COMM_indexes;
1410 typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
1411 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
1412 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
1413 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
1414 // Any symbols that get merged into another will get an entry
1415 // in this map so we know
1416 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
1417 uint32_t nlist_idx = 0;
1418 Symbol *symbol_ptr = NULL;
1419
1420 uint32_t sym_idx = 0;
1421 Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1422 uint32_t num_syms = symtab->GetNumSymbols();
1423
1424 //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1425 for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
1426 {
1427 struct nlist_64 nlist;
1428 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
1429 break;
1430
1431 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
1432 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
1433 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
1434 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
1435 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
1436
1437 SymbolType type = eSymbolTypeInvalid;
1438 const char *symbol_name = strtab_data.PeekCStr(nlist.n_strx);
1439 if (symbol_name == NULL)
1440 {
1441 // No symbol should be NULL, even the symbols with no
1442 // string values should have an offset zero which points
1443 // to an empty C-string
1444 Host::SystemLog (Host::eSystemLogError,
1445 "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
1446 nlist_idx,
1447 nlist.n_strx,
1448 module_sp->GetFileSpec().GetDirectory().GetCString(),
1449 module_sp->GetFileSpec().GetFilename().GetCString());
1450 continue;
1451 }
1452 const char *symbol_name_non_abi_mangled = NULL;
1453
1454 if (symbol_name[0] == '\0')
1455 symbol_name = NULL;
1456 SectionSP symbol_section;
1457 uint32_t symbol_byte_size = 0;
1458 bool add_nlist = true;
1459 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
1460
1461 assert (sym_idx < num_syms);
1462
1463 sym[sym_idx].SetDebug (is_debug);
1464
1465 if (is_debug)
1466 {
1467 switch (nlist.n_type)
Greg Clayton0fea0512011-12-30 00:32:24 +00001468 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001469 case StabGlobalSymbol:
1470 // N_GSYM -- global symbol: name,,NO_SECT,type,0
1471 // Sometimes the N_GSYM value contains the address.
1472
1473 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
1474 // have the same address, but we want to ensure that we always find only the real symbol,
1475 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
1476 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
1477 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
1478 // same address.
1479
1480 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
1481 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
1482 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
1483 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
1484 add_nlist = false;
1485 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00001486 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001487 sym[sym_idx].SetExternal(true);
1488 if (nlist.n_value != 0)
1489 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1490 type = eSymbolTypeData;
Greg Claytonb5a8f142012-02-05 02:38:54 +00001491 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001492 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +00001493
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001494 case StabFunctionName:
1495 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
1496 type = eSymbolTypeCompiler;
1497 break;
Greg Clayton0fea0512011-12-30 00:32:24 +00001498
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001499 case StabFunction:
1500 // N_FUN -- procedure: name,,n_sect,linenumber,address
1501 if (symbol_name)
Greg Claytona9c4f312011-10-31 20:50:40 +00001502 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001503 type = eSymbolTypeCode;
1504 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1505
1506 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
1507 // We use the current number of symbols in the symbol table in lieu of
1508 // using nlist_idx in case we ever start trimming entries out
1509 N_FUN_indexes.push_back(sym_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001510 }
1511 else
1512 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001513 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00001514
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001515 if ( !N_FUN_indexes.empty() )
Chris Lattner24943d22010-06-08 16:52:24 +00001516 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001517 // Copy the size of the function into the original STAB entry so we don't have
1518 // to hunt for it later
1519 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
1520 N_FUN_indexes.pop_back();
1521 // We don't really need the end function STAB as it contains the size which
1522 // we already placed with the original symbol, so don't add it if we want a
1523 // minimal symbol table
1524 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001525 add_nlist = false;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001526 }
Greg Clayton3f69eac2011-12-03 02:30:59 +00001527 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001528 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001529
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001530 case StabStaticSymbol:
1531 // N_STSYM -- static symbol: name,,n_sect,type,address
1532 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
1533 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1534 type = eSymbolTypeData;
1535 break;
1536
1537 case StabLocalCommon:
1538 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
1539 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1540 type = eSymbolTypeCommonBlock;
1541 break;
1542
1543 case StabBeginSymbol:
1544 // N_BNSYM
1545 // We use the current number of symbols in the symbol table in lieu of
1546 // using nlist_idx in case we ever start trimming entries out
1547 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001548 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001549 // Skip these if we want minimal symbol tables
1550 add_nlist = false;
1551 }
1552 else
1553 {
1554 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1555 N_NSYM_indexes.push_back(sym_idx);
1556 type = eSymbolTypeScopeBegin;
1557 }
1558 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001559
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001560 case StabEndSymbol:
1561 // N_ENSYM
1562 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
1563 // so that we can always skip the entire symbol if we need to navigate
1564 // more quickly at the source level when parsing STABS
1565 if (minimize)
1566 {
1567 // Skip these if we want minimal symbol tables
1568 add_nlist = false;
1569 }
1570 else
1571 {
1572 if ( !N_NSYM_indexes.empty() )
Greg Clayton3f69eac2011-12-03 02:30:59 +00001573 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001574 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
1575 symbol_ptr->SetByteSize(sym_idx + 1);
1576 symbol_ptr->SetSizeIsSibling(true);
1577 N_NSYM_indexes.pop_back();
1578 }
1579 type = eSymbolTypeScopeEnd;
1580 }
1581 break;
1582
1583
1584 case StabSourceFileOptions:
1585 // N_OPT - emitted with gcc2_compiled and in gcc source
1586 type = eSymbolTypeCompiler;
1587 break;
1588
1589 case StabRegisterSymbol:
1590 // N_RSYM - register sym: name,,NO_SECT,type,register
1591 type = eSymbolTypeVariable;
1592 break;
1593
1594 case StabSourceLine:
1595 // N_SLINE - src line: 0,,n_sect,linenumber,address
1596 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1597 type = eSymbolTypeLineEntry;
1598 break;
1599
1600 case StabStructureType:
1601 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
1602 type = eSymbolTypeVariableType;
1603 break;
1604
1605 case StabSourceFileName:
1606 // N_SO - source file name
1607 type = eSymbolTypeSourceFile;
1608 if (symbol_name == NULL)
1609 {
1610 if (minimize)
1611 add_nlist = false;
1612 if (N_SO_index != UINT32_MAX)
1613 {
1614 // Set the size of the N_SO to the terminating index of this N_SO
1615 // so that we can always skip the entire N_SO if we need to navigate
1616 // more quickly at the source level when parsing STABS
1617 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
1618 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
1619 symbol_ptr->SetSizeIsSibling(true);
1620 }
1621 N_NSYM_indexes.clear();
1622 N_INCL_indexes.clear();
1623 N_BRAC_indexes.clear();
1624 N_COMM_indexes.clear();
1625 N_FUN_indexes.clear();
1626 N_SO_index = UINT32_MAX;
1627 }
1628 else
1629 {
1630 // We use the current number of symbols in the symbol table in lieu of
1631 // using nlist_idx in case we ever start trimming entries out
1632 if (symbol_name[0] == '/')
1633 N_SO_index = sym_idx;
1634 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1635 {
1636 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
1637 if (so_path && so_path[0])
1638 {
1639 std::string full_so_path (so_path);
1640 if (*full_so_path.rbegin() != '/')
1641 full_so_path += '/';
1642 full_so_path += symbol_name;
1643 sym[sym_idx - 1].GetMangled().SetValue(full_so_path.c_str(), false);
1644 add_nlist = false;
1645 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1646 }
1647 }
1648 }
1649
1650 break;
1651
1652 case StabObjectFileName:
1653 // N_OSO - object file name: name,,0,0,st_mtime
1654 type = eSymbolTypeObjectFile;
1655 break;
1656
1657 case StabLocalSymbol:
1658 // N_LSYM - local sym: name,,NO_SECT,type,offset
1659 type = eSymbolTypeLocal;
1660 break;
1661
1662 //----------------------------------------------------------------------
1663 // INCL scopes
1664 //----------------------------------------------------------------------
1665 case StabBeginIncludeFileName:
1666 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
1667 // We use the current number of symbols in the symbol table in lieu of
1668 // using nlist_idx in case we ever start trimming entries out
1669 N_INCL_indexes.push_back(sym_idx);
1670 type = eSymbolTypeScopeBegin;
1671 break;
1672
1673 case StabEndIncludeFile:
1674 // N_EINCL - include file end: name,,NO_SECT,0,0
1675 // Set the size of the N_BINCL to the terminating index of this N_EINCL
1676 // so that we can always skip the entire symbol if we need to navigate
1677 // more quickly at the source level when parsing STABS
1678 if ( !N_INCL_indexes.empty() )
1679 {
1680 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
1681 symbol_ptr->SetByteSize(sym_idx + 1);
1682 symbol_ptr->SetSizeIsSibling(true);
1683 N_INCL_indexes.pop_back();
1684 }
1685 type = eSymbolTypeScopeEnd;
1686 break;
1687
1688 case StabIncludeFileName:
1689 // N_SOL - #included file name: name,,n_sect,0,address
1690 type = eSymbolTypeHeaderFile;
1691
1692 // We currently don't use the header files on darwin
1693 if (minimize)
1694 add_nlist = false;
1695 break;
1696
1697 case StabCompilerParameters:
1698 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
1699 type = eSymbolTypeCompiler;
1700 break;
1701
1702 case StabCompilerVersion:
1703 // N_VERSION - compiler version: name,,NO_SECT,0,0
1704 type = eSymbolTypeCompiler;
1705 break;
1706
1707 case StabCompilerOptLevel:
1708 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
1709 type = eSymbolTypeCompiler;
1710 break;
1711
1712 case StabParameter:
1713 // N_PSYM - parameter: name,,NO_SECT,type,offset
1714 type = eSymbolTypeVariable;
1715 break;
1716
1717 case StabAlternateEntry:
1718 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
1719 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1720 type = eSymbolTypeLineEntry;
1721 break;
1722
1723 //----------------------------------------------------------------------
1724 // Left and Right Braces
1725 //----------------------------------------------------------------------
1726 case StabLeftBracket:
1727 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
1728 // We use the current number of symbols in the symbol table in lieu of
1729 // using nlist_idx in case we ever start trimming entries out
1730 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1731 N_BRAC_indexes.push_back(sym_idx);
1732 type = eSymbolTypeScopeBegin;
1733 break;
1734
1735 case StabRightBracket:
1736 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
1737 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
1738 // so that we can always skip the entire symbol if we need to navigate
1739 // more quickly at the source level when parsing STABS
1740 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1741 if ( !N_BRAC_indexes.empty() )
1742 {
1743 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
1744 symbol_ptr->SetByteSize(sym_idx + 1);
1745 symbol_ptr->SetSizeIsSibling(true);
1746 N_BRAC_indexes.pop_back();
1747 }
1748 type = eSymbolTypeScopeEnd;
1749 break;
1750
1751 case StabDeletedIncludeFile:
1752 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
1753 type = eSymbolTypeHeaderFile;
1754 break;
1755
1756 //----------------------------------------------------------------------
1757 // COMM scopes
1758 //----------------------------------------------------------------------
1759 case StabBeginCommon:
1760 // N_BCOMM - begin common: name,,NO_SECT,0,0
1761 // We use the current number of symbols in the symbol table in lieu of
1762 // using nlist_idx in case we ever start trimming entries out
1763 type = eSymbolTypeScopeBegin;
1764 N_COMM_indexes.push_back(sym_idx);
1765 break;
1766
1767 case StabEndCommonLocal:
1768 // N_ECOML - end common (local name): 0,,n_sect,0,address
1769 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1770 // Fall through
1771
1772 case StabEndCommon:
1773 // N_ECOMM - end common: name,,n_sect,0,0
1774 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
1775 // so that we can always skip the entire symbol if we need to navigate
1776 // more quickly at the source level when parsing STABS
1777 if ( !N_COMM_indexes.empty() )
1778 {
1779 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
1780 symbol_ptr->SetByteSize(sym_idx + 1);
1781 symbol_ptr->SetSizeIsSibling(true);
1782 N_COMM_indexes.pop_back();
1783 }
1784 type = eSymbolTypeScopeEnd;
1785 break;
1786
1787 case StabLength:
1788 // N_LENG - second stab entry with length information
1789 type = eSymbolTypeAdditional;
1790 break;
1791
1792 default: break;
1793 }
1794 }
1795 else
1796 {
1797 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
1798 uint8_t n_type = NlistMaskType & nlist.n_type;
1799 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
1800
1801 switch (n_type)
1802 {
1803 case NListTypeIndirect: // N_INDR - Fall through
1804 case NListTypePreboundUndefined:// N_PBUD - Fall through
1805 case NListTypeUndefined: // N_UNDF
1806 type = eSymbolTypeUndefined;
1807 break;
1808
1809 case NListTypeAbsolute: // N_ABS
1810 type = eSymbolTypeAbsolute;
1811 break;
1812
1813 case NListTypeSection: // N_SECT
1814 {
1815 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1816
1817 if (symbol_section == NULL)
1818 {
1819 // TODO: warn about this?
1820 add_nlist = false;
1821 break;
1822 }
1823
1824 if (TEXT_eh_frame_sectID == nlist.n_sect)
1825 {
1826 type = eSymbolTypeException;
Chris Lattner24943d22010-06-08 16:52:24 +00001827 }
1828 else
1829 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001830 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
1831
1832 switch (section_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001833 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001834 case SectionTypeRegular: break; // regular section
1835 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
1836 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
1837 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
1838 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
1839 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
1840 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
1841 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
1842 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1843 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
1844 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
1845 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
1846 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
1847 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
1848 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
1849 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
1850 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
1851 default: break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001852 }
Chris Lattner24943d22010-06-08 16:52:24 +00001853
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001854 if (type == eSymbolTypeInvalid)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001855 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001856 const char *symbol_sect_name = symbol_section->GetName().AsCString();
1857 if (symbol_section->IsDescendant (text_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00001858 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001859 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
1860 SectionAttrUserSelfModifyingCode |
1861 SectionAttrSytemSomeInstructions))
1862 type = eSymbolTypeData;
1863 else
1864 type = eSymbolTypeCode;
Greg Clayton576a68b2010-09-08 16:38:06 +00001865 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001866 else
1867 if (symbol_section->IsDescendant(data_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00001868 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001869 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
Greg Clayton7c36fa02010-09-11 03:13:28 +00001870 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001871 type = eSymbolTypeRuntime;
Chris Lattner24943d22010-06-08 16:52:24 +00001872
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001873 if (symbol_name &&
1874 symbol_name[0] == '_' &&
1875 symbol_name[1] == 'O' &&
1876 symbol_name[2] == 'B')
Greg Clayton637029b2010-09-12 05:25:16 +00001877 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001878 llvm::StringRef symbol_name_ref(symbol_name);
1879 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
1880 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
1881 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
1882 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
Chris Lattner24943d22010-06-08 16:52:24 +00001883 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001884 symbol_name_non_abi_mangled = symbol_name + 1;
1885 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
1886 type = eSymbolTypeObjCClass;
Chris Lattner24943d22010-06-08 16:52:24 +00001887 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001888 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
Chris Lattner24943d22010-06-08 16:52:24 +00001889 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001890 symbol_name_non_abi_mangled = symbol_name + 1;
1891 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
1892 type = eSymbolTypeObjCMetaClass;
1893 }
1894 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
1895 {
1896 symbol_name_non_abi_mangled = symbol_name + 1;
1897 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
1898 type = eSymbolTypeObjCIVar;
Chris Lattner24943d22010-06-08 16:52:24 +00001899 }
1900 }
1901 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001902 else
1903 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
1904 {
1905 type = eSymbolTypeException;
1906 }
1907 else
1908 {
1909 type = eSymbolTypeData;
1910 }
1911 }
1912 else
1913 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
1914 {
1915 type = eSymbolTypeTrampoline;
1916 }
1917 else
1918 if (symbol_section->IsDescendant(objc_section_sp.get()))
1919 {
1920 type = eSymbolTypeRuntime;
1921 if (symbol_name && symbol_name[0] == '.')
1922 {
1923 llvm::StringRef symbol_name_ref(symbol_name);
1924 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
1925 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
1926 {
1927 symbol_name_non_abi_mangled = symbol_name;
1928 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
1929 type = eSymbolTypeObjCClass;
1930 }
1931 }
Chris Lattner24943d22010-06-08 16:52:24 +00001932 }
1933 }
1934 }
1935 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001936 break;
1937 }
1938 }
1939
1940 if (add_nlist)
1941 {
1942 uint64_t symbol_value = nlist.n_value;
1943 bool symbol_name_is_mangled = false;
1944
1945 if (symbol_name_non_abi_mangled)
1946 {
1947 sym[sym_idx].GetMangled().SetMangledName (symbol_name_non_abi_mangled);
1948 sym[sym_idx].GetMangled().SetDemangledName (symbol_name);
Chris Lattner24943d22010-06-08 16:52:24 +00001949 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001950 else
1951 {
1952 if (symbol_name && symbol_name[0] == '_')
1953 {
1954 symbol_name_is_mangled = symbol_name[1] == '_';
1955 symbol_name++; // Skip the leading underscore
1956 }
1957
1958 if (symbol_name)
1959 {
1960 sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
1961 }
1962 }
1963
1964 if (is_debug == false)
1965 {
1966 if (type == eSymbolTypeCode)
1967 {
1968 // See if we can find a N_FUN entry for any code symbols.
1969 // If we do find a match, and the name matches, then we
1970 // can merge the two into just the function symbol to avoid
1971 // duplicate entries in the symbol table
1972 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
1973 if (pos != N_FUN_addr_to_sym_idx.end())
1974 {
1975 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1976 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1977 {
1978 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
1979 // We just need the flags from the linker symbol, so put these flags
1980 // into the N_FUN flags to avoid duplicate symbols in the symbol table
1981 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1982 sym[sym_idx].Clear();
1983 continue;
1984 }
1985 }
1986 }
1987 else if (type == eSymbolTypeData)
1988 {
1989 // See if we can find a N_STSYM entry for any data symbols.
1990 // If we do find a match, and the name matches, then we
1991 // can merge the two into just the Static symbol to avoid
1992 // duplicate entries in the symbol table
1993 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
1994 if (pos != N_STSYM_addr_to_sym_idx.end())
1995 {
1996 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1997 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1998 {
1999 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2000 // We just need the flags from the linker symbol, so put these flags
2001 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
2002 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2003 sym[sym_idx].Clear();
2004 continue;
2005 }
2006 }
2007 }
2008 }
2009 if (symbol_section)
2010 {
2011 const addr_t section_file_addr = symbol_section->GetFileAddress();
2012 if (symbol_byte_size == 0 && function_starts_count > 0)
2013 {
Greg Claytond2653c22012-03-14 01:53:24 +00002014 addr_t symbol_lookup_file_addr = nlist.n_value;
2015 // Do an exact address match for non-ARM addresses, else get the closest since
2016 // the symbol might be a thumb symbol which has an address with bit zero set
2017 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
2018 if (is_arm && func_start_entry)
2019 {
2020 // Verify that the function start address is the symbol address (ARM)
2021 // or the symbol address + 1 (thumb)
2022 if (func_start_entry->addr != symbol_lookup_file_addr &&
2023 func_start_entry->addr != (symbol_lookup_file_addr + 1))
2024 {
2025 // Not the right entry, NULL it out...
2026 func_start_entry = NULL;
2027 }
2028 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002029 if (func_start_entry)
2030 {
2031 func_start_entry->data = true;
Greg Claytond2653c22012-03-14 01:53:24 +00002032
2033 addr_t symbol_file_addr = func_start_entry->addr;
2034 uint32_t symbol_flags = 0;
2035 if (is_arm)
2036 {
2037 if (symbol_file_addr & 1)
2038 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
2039 symbol_file_addr &= 0xfffffffffffffffeull;
2040 }
2041
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002042 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2043 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2044 if (next_func_start_entry)
2045 {
Greg Claytond2653c22012-03-14 01:53:24 +00002046 addr_t next_symbol_file_addr = next_func_start_entry->addr;
2047 // Be sure the clear the Thumb address bit when we calculate the size
2048 // from the current and next address
2049 if (is_arm)
2050 next_symbol_file_addr &= 0xfffffffffffffffeull;
2051 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002052 }
2053 else
2054 {
Greg Claytond2653c22012-03-14 01:53:24 +00002055 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002056 }
2057 }
2058 }
2059 symbol_value -= section_file_addr;
2060 }
2061
2062 sym[sym_idx].SetID (nlist_idx);
2063 sym[sym_idx].SetType (type);
2064 sym[sym_idx].GetAddress().SetSection (symbol_section);
2065 sym[sym_idx].GetAddress().SetOffset (symbol_value);
2066 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2067
2068 if (symbol_byte_size > 0)
2069 sym[sym_idx].SetByteSize(symbol_byte_size);
2070
2071 ++sym_idx;
2072 }
2073 else
2074 {
2075 sym[sym_idx].Clear();
2076 }
2077
2078 }
2079
2080 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
2081 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
2082 // such entries by figuring out what the address for the global is by looking up this non-STAB
2083 // entry and copying the value into the debug symbol's value to save us the hassle in the
2084 // debug symbol parser.
2085
2086 Symbol *global_symbol = NULL;
2087 for (nlist_idx = 0;
2088 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
2089 nlist_idx++)
2090 {
2091 if (global_symbol->GetAddress().GetFileAddress() == 0)
2092 {
2093 std::vector<uint32_t> indexes;
2094 if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
2095 {
2096 std::vector<uint32_t>::const_iterator pos;
2097 std::vector<uint32_t>::const_iterator end = indexes.end();
2098 for (pos = indexes.begin(); pos != end; ++pos)
2099 {
2100 symbol_ptr = symtab->SymbolAtIndex(*pos);
2101 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
2102 {
2103 global_symbol->GetAddress() = symbol_ptr->GetAddress();
2104 break;
2105 }
2106 }
2107 }
Chris Lattner24943d22010-06-08 16:52:24 +00002108 }
2109 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002110
2111 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
2112
2113
2114 if (function_starts_count > 0)
2115 {
2116 char synthetic_function_symbol[PATH_MAX];
2117 uint32_t num_synthetic_function_symbols = 0;
2118 for (i=0; i<function_starts_count; ++i)
2119 {
2120 if (function_starts.GetEntryRef (i).data == false)
2121 ++num_synthetic_function_symbols;
2122 }
2123
2124 if (num_synthetic_function_symbols > 0)
2125 {
2126 if (num_syms < sym_idx + num_synthetic_function_symbols)
2127 {
2128 num_syms = sym_idx + num_synthetic_function_symbols;
2129 sym = symtab->Resize (num_syms);
2130 }
2131 uint32_t synthetic_function_symbol_idx = 0;
2132 for (i=0; i<function_starts_count; ++i)
2133 {
2134 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
2135 if (func_start_entry->data == false)
2136 {
Greg Claytond2653c22012-03-14 01:53:24 +00002137 addr_t symbol_file_addr = func_start_entry->addr;
2138 uint32_t symbol_flags = 0;
2139 if (is_arm)
2140 {
2141 if (symbol_file_addr & 1)
2142 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
2143 symbol_file_addr &= 0xfffffffffffffffeull;
2144 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002145 Address symbol_addr;
Greg Claytond2653c22012-03-14 01:53:24 +00002146 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002147 {
2148 SectionSP symbol_section (symbol_addr.GetSection());
2149 uint32_t symbol_byte_size = 0;
2150 if (symbol_section)
2151 {
2152 const addr_t section_file_addr = symbol_section->GetFileAddress();
2153 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2154 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2155 if (next_func_start_entry)
2156 {
Greg Claytond2653c22012-03-14 01:53:24 +00002157 addr_t next_symbol_file_addr = next_func_start_entry->addr;
2158 if (is_arm)
2159 next_symbol_file_addr &= 0xfffffffffffffffeull;
2160 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002161 }
2162 else
2163 {
Greg Claytond2653c22012-03-14 01:53:24 +00002164 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002165 }
2166 snprintf (synthetic_function_symbol,
2167 sizeof(synthetic_function_symbol),
2168 "___lldb_unnamed_function%u$$%s",
2169 ++synthetic_function_symbol_idx,
2170 module_sp->GetFileSpec().GetFilename().GetCString());
2171 sym[sym_idx].SetID (synthetic_sym_id++);
2172 sym[sym_idx].GetMangled().SetDemangledName(synthetic_function_symbol);
2173 sym[sym_idx].SetType (eSymbolTypeCode);
2174 sym[sym_idx].SetIsSynthetic (true);
2175 sym[sym_idx].GetAddress() = symbol_addr;
Greg Claytond2653c22012-03-14 01:53:24 +00002176 if (symbol_flags)
2177 sym[sym_idx].SetFlags (symbol_flags);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002178 if (symbol_byte_size)
2179 sym[sym_idx].SetByteSize (symbol_byte_size);
2180 ++sym_idx;
2181 }
2182 }
2183 }
2184 }
2185 }
2186 }
2187
2188 // Trim our symbols down to just what we ended up with after
2189 // removing any symbols.
2190 if (sym_idx < num_syms)
2191 {
2192 num_syms = sym_idx;
2193 sym = symtab->Resize (num_syms);
2194 }
2195
2196 // Now synthesize indirect symbols
2197 if (m_dysymtab.nindirectsyms != 0)
2198 {
2199 DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
2200
2201 if (indirect_symbol_index_data.GetByteSize())
2202 {
2203 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
2204
2205 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
2206 {
2207 if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
2208 {
2209 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
2210 if (symbol_stub_byte_size == 0)
2211 continue;
2212
2213 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
2214
2215 if (num_symbol_stubs == 0)
2216 continue;
2217
2218 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
2219 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
2220 {
2221 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
2222 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
2223 uint32_t symbol_stub_offset = symbol_stub_index * 4;
2224 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
2225 {
2226 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
2227 if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
2228 continue;
2229
2230 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
2231 Symbol *stub_symbol = NULL;
2232 if (index_pos != end_index_pos)
2233 {
2234 // We have a remapping from the original nlist index to
2235 // a current symbol index, so just look this up by index
2236 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
2237 }
2238 else
2239 {
2240 // We need to lookup a symbol using the original nlist
2241 // symbol index since this index is coming from the
2242 // S_SYMBOL_STUBS
2243 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
2244 }
2245
2246 assert (stub_symbol);
2247 if (stub_symbol)
2248 {
2249 Address so_addr(symbol_stub_addr, section_list);
2250
2251 if (stub_symbol->GetType() == eSymbolTypeUndefined)
2252 {
2253 // Change the external symbol into a trampoline that makes sense
2254 // These symbols were N_UNDF N_EXT, and are useless to us, so we
2255 // can re-use them so we don't have to make up a synthetic symbol
2256 // for no good reason.
2257 stub_symbol->SetType (eSymbolTypeTrampoline);
2258 stub_symbol->SetExternal (false);
2259 stub_symbol->GetAddress() = so_addr;
2260 stub_symbol->SetByteSize (symbol_stub_byte_size);
2261 }
2262 else
2263 {
2264 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda2a76fbf2012-04-24 02:09:58 +00002265 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002266 if (sym_idx >= num_syms)
Jason Molenda2a76fbf2012-04-24 02:09:58 +00002267 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002268 sym = symtab->Resize (++num_syms);
Jason Molenda2a76fbf2012-04-24 02:09:58 +00002269 stub_symbol = NULL; // this pointer no longer valid
2270 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002271 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda2a76fbf2012-04-24 02:09:58 +00002272 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002273 sym[sym_idx].SetType (eSymbolTypeTrampoline);
2274 sym[sym_idx].SetIsSynthetic (true);
2275 sym[sym_idx].GetAddress() = so_addr;
2276 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
2277 ++sym_idx;
2278 }
2279 }
2280 }
2281 }
2282 }
2283 }
2284 }
2285 }
2286 return symtab->GetNumSymbols();
Chris Lattner24943d22010-06-08 16:52:24 +00002287 }
2288 return 0;
2289}
2290
2291
2292void
2293ObjectFileMachO::Dump (Stream *s)
2294{
Greg Clayton9482f052012-03-13 23:14:29 +00002295 ModuleSP module_sp(GetModule());
2296 if (module_sp)
2297 {
2298 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2299 s->Printf("%p: ", this);
2300 s->Indent();
2301 if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped)
2302 s->PutCString("ObjectFileMachO64");
2303 else
2304 s->PutCString("ObjectFileMachO32");
Chris Lattner24943d22010-06-08 16:52:24 +00002305
Greg Clayton9482f052012-03-13 23:14:29 +00002306 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +00002307
Greg Clayton9482f052012-03-13 23:14:29 +00002308 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner24943d22010-06-08 16:52:24 +00002309
Greg Clayton9482f052012-03-13 23:14:29 +00002310 if (m_sections_ap.get())
2311 m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00002312
Greg Clayton9482f052012-03-13 23:14:29 +00002313 if (m_symtab_ap.get())
2314 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
2315 }
Chris Lattner24943d22010-06-08 16:52:24 +00002316}
2317
2318
2319bool
Greg Clayton0467c782011-02-04 18:53:10 +00002320ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner24943d22010-06-08 16:52:24 +00002321{
Greg Clayton9482f052012-03-13 23:14:29 +00002322 ModuleSP module_sp(GetModule());
2323 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00002324 {
Greg Clayton9482f052012-03-13 23:14:29 +00002325 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2326 struct uuid_command load_cmd;
2327 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2328 uint32_t i;
2329 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00002330 {
Greg Clayton9482f052012-03-13 23:14:29 +00002331 const uint32_t cmd_offset = offset;
2332 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2333 break;
2334
2335 if (load_cmd.cmd == LoadCommandUUID)
Chris Lattner24943d22010-06-08 16:52:24 +00002336 {
Greg Clayton9482f052012-03-13 23:14:29 +00002337 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
2338 if (uuid_bytes)
2339 {
2340 uuid->SetBytes (uuid_bytes);
2341 return true;
2342 }
2343 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00002344 }
Greg Clayton9482f052012-03-13 23:14:29 +00002345 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00002346 }
Chris Lattner24943d22010-06-08 16:52:24 +00002347 }
2348 return false;
2349}
2350
2351
2352uint32_t
2353ObjectFileMachO::GetDependentModules (FileSpecList& files)
2354{
Chris Lattner24943d22010-06-08 16:52:24 +00002355 uint32_t count = 0;
Greg Clayton9482f052012-03-13 23:14:29 +00002356 ModuleSP module_sp(GetModule());
2357 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00002358 {
Greg Clayton9482f052012-03-13 23:14:29 +00002359 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2360 struct load_command load_cmd;
2361 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2362 const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
2363 uint32_t i;
2364 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00002365 {
Greg Clayton9482f052012-03-13 23:14:29 +00002366 const uint32_t cmd_offset = offset;
2367 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2368 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002369
Greg Clayton9482f052012-03-13 23:14:29 +00002370 switch (load_cmd.cmd)
2371 {
2372 case LoadCommandDylibLoad:
2373 case LoadCommandDylibLoadWeak:
2374 case LoadCommandDylibReexport:
2375 case LoadCommandDynamicLinkerLoad:
2376 case LoadCommandFixedVMShlibLoad:
2377 case LoadCommandDylibLoadUpward:
2378 {
2379 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2380 const char *path = m_data.PeekCStr(name_offset);
2381 // Skip any path that starts with '@' since these are usually:
2382 // @executable_path/.../file
2383 // @rpath/.../file
2384 if (path && path[0] != '@')
2385 {
2386 FileSpec file_spec(path, resolve_path);
2387 if (files.AppendIfUnique(file_spec))
2388 count++;
2389 }
2390 }
2391 break;
2392
2393 default:
2394 break;
2395 }
2396 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00002397 }
Chris Lattner24943d22010-06-08 16:52:24 +00002398 }
2399 return count;
2400}
2401
Jim Ingham28775942011-03-07 23:44:08 +00002402lldb_private::Address
2403ObjectFileMachO::GetEntryPointAddress ()
2404{
2405 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
2406 // is initialized to an invalid address, so we can just return that.
2407 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
2408
2409 if (!IsExecutable() || m_entry_point_address.IsValid())
2410 return m_entry_point_address;
2411
2412 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
2413 // /usr/include/mach-o.h, but it is basically:
2414 //
2415 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
2416 // uint32_t count - this is the count of longs in the thread state data
2417 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
2418 // <repeat this trio>
2419 //
2420 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
2421 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
2422 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
2423 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
2424 //
2425 // For now we hard-code the offsets and flavors we need:
2426 //
2427 //
2428
Greg Clayton9482f052012-03-13 23:14:29 +00002429 ModuleSP module_sp(GetModule());
2430 if (module_sp)
Jim Ingham28775942011-03-07 23:44:08 +00002431 {
Greg Clayton9482f052012-03-13 23:14:29 +00002432 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2433 struct load_command load_cmd;
2434 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2435 uint32_t i;
2436 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
2437 bool done = false;
2438
2439 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham28775942011-03-07 23:44:08 +00002440 {
Greg Clayton9482f052012-03-13 23:14:29 +00002441 const uint32_t cmd_offset = offset;
2442 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2443 break;
2444
2445 switch (load_cmd.cmd)
Jim Ingham28775942011-03-07 23:44:08 +00002446 {
Greg Clayton9482f052012-03-13 23:14:29 +00002447 case LoadCommandUnixThread:
2448 case LoadCommandThread:
Jim Ingham28775942011-03-07 23:44:08 +00002449 {
Greg Clayton9482f052012-03-13 23:14:29 +00002450 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham28775942011-03-07 23:44:08 +00002451 {
Greg Clayton9482f052012-03-13 23:14:29 +00002452 uint32_t flavor = m_data.GetU32(&offset);
2453 uint32_t count = m_data.GetU32(&offset);
2454 if (count == 0)
2455 {
2456 // We've gotten off somehow, log and exit;
2457 return m_entry_point_address;
Jim Ingham28775942011-03-07 23:44:08 +00002458 }
Greg Clayton9482f052012-03-13 23:14:29 +00002459
2460 switch (m_header.cputype)
2461 {
2462 case llvm::MachO::CPUTypeARM:
2463 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
2464 {
2465 offset += 60; // This is the offset of pc in the GPR thread state data structure.
2466 start_address = m_data.GetU32(&offset);
2467 done = true;
2468 }
Jim Ingham28775942011-03-07 23:44:08 +00002469 break;
Greg Clayton9482f052012-03-13 23:14:29 +00002470 case llvm::MachO::CPUTypeI386:
2471 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
2472 {
2473 offset += 40; // This is the offset of eip in the GPR thread state data structure.
2474 start_address = m_data.GetU32(&offset);
2475 done = true;
2476 }
2477 break;
2478 case llvm::MachO::CPUTypeX86_64:
2479 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
2480 {
2481 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
2482 start_address = m_data.GetU64(&offset);
2483 done = true;
2484 }
2485 break;
2486 default:
2487 return m_entry_point_address;
2488 }
2489 // Haven't found the GPR flavor yet, skip over the data for this flavor:
2490 if (done)
2491 break;
2492 offset += count * 4;
2493 }
Jim Ingham28775942011-03-07 23:44:08 +00002494 }
Greg Clayton9482f052012-03-13 23:14:29 +00002495 break;
2496 case LoadCommandMain:
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002497 {
Greg Clayton9482f052012-03-13 23:14:29 +00002498 ConstString text_segment_name ("__TEXT");
2499 uint64_t entryoffset = m_data.GetU64(&offset);
2500 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2501 if (text_segment_sp)
2502 {
2503 done = true;
2504 start_address = text_segment_sp->GetFileAddress() + entryoffset;
2505 }
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002506 }
Greg Clayton9482f052012-03-13 23:14:29 +00002507
2508 default:
2509 break;
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002510 }
Greg Clayton9482f052012-03-13 23:14:29 +00002511 if (done)
2512 break;
Jim Ingham28775942011-03-07 23:44:08 +00002513
Greg Clayton9482f052012-03-13 23:14:29 +00002514 // Go to the next load command:
2515 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham28775942011-03-07 23:44:08 +00002516 }
Jim Ingham28775942011-03-07 23:44:08 +00002517
Greg Clayton9482f052012-03-13 23:14:29 +00002518 if (start_address != LLDB_INVALID_ADDRESS)
Greg Clayton3508c382012-02-24 01:59:29 +00002519 {
Greg Clayton9482f052012-03-13 23:14:29 +00002520 // We got the start address from the load commands, so now resolve that address in the sections
2521 // of this ObjectFile:
2522 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Clayton3508c382012-02-24 01:59:29 +00002523 {
Greg Clayton9482f052012-03-13 23:14:29 +00002524 m_entry_point_address.Clear();
2525 }
2526 }
2527 else
2528 {
2529 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
2530 // "start" symbol in the main executable.
2531
2532 ModuleSP module_sp (GetModule());
2533
2534 if (module_sp)
2535 {
2536 SymbolContextList contexts;
2537 SymbolContext context;
2538 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
2539 {
2540 if (contexts.GetContextAtIndex(0, context))
2541 m_entry_point_address = context.symbol->GetAddress();
2542 }
Greg Clayton3508c382012-02-24 01:59:29 +00002543 }
2544 }
Jim Ingham28775942011-03-07 23:44:08 +00002545 }
2546
2547 return m_entry_point_address;
2548
2549}
2550
Greg Claytonb5a8f142012-02-05 02:38:54 +00002551lldb_private::Address
2552ObjectFileMachO::GetHeaderAddress ()
2553{
2554 lldb_private::Address header_addr;
2555 SectionList *section_list = GetSectionList();
2556 if (section_list)
2557 {
2558 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
2559 if (text_segment_sp)
2560 {
Greg Clayton3508c382012-02-24 01:59:29 +00002561 header_addr.SetSection (text_segment_sp);
Greg Claytonb5a8f142012-02-05 02:38:54 +00002562 header_addr.SetOffset (0);
2563 }
2564 }
2565 return header_addr;
2566}
2567
Greg Clayton46c9a352012-02-09 06:16:32 +00002568uint32_t
2569ObjectFileMachO::GetNumThreadContexts ()
2570{
Greg Clayton9482f052012-03-13 23:14:29 +00002571 ModuleSP module_sp(GetModule());
2572 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00002573 {
Greg Clayton9482f052012-03-13 23:14:29 +00002574 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2575 if (!m_thread_context_offsets_valid)
Greg Clayton46c9a352012-02-09 06:16:32 +00002576 {
Greg Clayton9482f052012-03-13 23:14:29 +00002577 m_thread_context_offsets_valid = true;
2578 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2579 FileRangeArray::Entry file_range;
2580 thread_command thread_cmd;
2581 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton46c9a352012-02-09 06:16:32 +00002582 {
Greg Clayton9482f052012-03-13 23:14:29 +00002583 const uint32_t cmd_offset = offset;
2584 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
2585 break;
2586
2587 if (thread_cmd.cmd == LoadCommandThread)
2588 {
2589 file_range.SetRangeBase (offset);
2590 file_range.SetByteSize (thread_cmd.cmdsize - 8);
2591 m_thread_context_offsets.Append (file_range);
2592 }
2593 offset = cmd_offset + thread_cmd.cmdsize;
Greg Clayton46c9a352012-02-09 06:16:32 +00002594 }
Greg Clayton46c9a352012-02-09 06:16:32 +00002595 }
2596 }
2597 return m_thread_context_offsets.GetSize();
2598}
2599
2600lldb::RegisterContextSP
2601ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
2602{
Greg Clayton46c9a352012-02-09 06:16:32 +00002603 lldb::RegisterContextSP reg_ctx_sp;
Greg Clayton9ce95382012-02-13 23:10:39 +00002604
Greg Clayton9482f052012-03-13 23:14:29 +00002605 ModuleSP module_sp(GetModule());
2606 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00002607 {
Greg Clayton9482f052012-03-13 23:14:29 +00002608 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2609 if (!m_thread_context_offsets_valid)
2610 GetNumThreadContexts ();
2611
2612 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
2613
2614 DataExtractor data (m_data,
2615 thread_context_file_range->GetRangeBase(),
2616 thread_context_file_range->GetByteSize());
2617
2618 switch (m_header.cputype)
2619 {
2620 case llvm::MachO::CPUTypeARM:
2621 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
2622 break;
2623
2624 case llvm::MachO::CPUTypeI386:
2625 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
2626 break;
2627
2628 case llvm::MachO::CPUTypeX86_64:
2629 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
2630 break;
2631 }
Greg Clayton46c9a352012-02-09 06:16:32 +00002632 }
2633 return reg_ctx_sp;
2634}
2635
Greg Claytonb5a8f142012-02-05 02:38:54 +00002636
Greg Claytonca319972011-07-09 00:41:34 +00002637ObjectFile::Type
2638ObjectFileMachO::CalculateType()
2639{
2640 switch (m_header.filetype)
2641 {
2642 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2643 if (GetAddressByteSize () == 4)
2644 {
2645 // 32 bit kexts are just object files, but they do have a valid
2646 // UUID load command.
2647 UUID uuid;
2648 if (GetUUID(&uuid))
2649 {
2650 // this checking for the UUID load command is not enough
2651 // we could eventually look for the symbol named
2652 // "OSKextGetCurrentIdentifier" as this is required of kexts
2653 if (m_strata == eStrataInvalid)
2654 m_strata = eStrataKernel;
2655 return eTypeSharedLibrary;
2656 }
2657 }
2658 return eTypeObjectFile;
2659
2660 case HeaderFileTypeExecutable: return eTypeExecutable; // 0x2u MH_EXECUTE
2661 case HeaderFileTypeFixedVMShlib: return eTypeSharedLibrary; // 0x3u MH_FVMLIB
2662 case HeaderFileTypeCore: return eTypeCoreFile; // 0x4u MH_CORE
2663 case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary; // 0x5u MH_PRELOAD
2664 case HeaderFileTypeDynamicShlib: return eTypeSharedLibrary; // 0x6u MH_DYLIB
2665 case HeaderFileTypeDynamicLinkEditor: return eTypeDynamicLinker; // 0x7u MH_DYLINKER
2666 case HeaderFileTypeBundle: return eTypeSharedLibrary; // 0x8u MH_BUNDLE
2667 case HeaderFileTypeDynamicShlibStub: return eTypeStubLibrary; // 0x9u MH_DYLIB_STUB
2668 case HeaderFileTypeDSYM: return eTypeDebugInfo; // 0xAu MH_DSYM
2669 case HeaderFileTypeKextBundle: return eTypeSharedLibrary; // 0xBu MH_KEXT_BUNDLE
2670 default:
2671 break;
2672 }
2673 return eTypeUnknown;
2674}
2675
2676ObjectFile::Strata
2677ObjectFileMachO::CalculateStrata()
2678{
2679 switch (m_header.filetype)
2680 {
2681 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2682 {
2683 // 32 bit kexts are just object files, but they do have a valid
2684 // UUID load command.
2685 UUID uuid;
2686 if (GetUUID(&uuid))
2687 {
2688 // this checking for the UUID load command is not enough
2689 // we could eventually look for the symbol named
2690 // "OSKextGetCurrentIdentifier" as this is required of kexts
2691 if (m_type == eTypeInvalid)
2692 m_type = eTypeSharedLibrary;
2693
2694 return eStrataKernel;
2695 }
2696 }
2697 return eStrataUnknown;
2698
2699 case HeaderFileTypeExecutable: // 0x2u MH_EXECUTE
2700 // Check for the MH_DYLDLINK bit in the flags
2701 if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
Sean Callananac725af2012-02-10 20:22:35 +00002702 {
Greg Claytonca319972011-07-09 00:41:34 +00002703 return eStrataUser;
Sean Callananac725af2012-02-10 20:22:35 +00002704 }
2705 else
2706 {
2707 SectionList *section_list = GetSectionList();
2708 if (section_list)
2709 {
2710 static ConstString g_kld_section_name ("__KLD");
2711 if (section_list->FindSectionByName(g_kld_section_name))
2712 return eStrataKernel;
2713 }
2714 }
2715 return eStrataRawImage;
Greg Claytonca319972011-07-09 00:41:34 +00002716
2717 case HeaderFileTypeFixedVMShlib: return eStrataUser; // 0x3u MH_FVMLIB
2718 case HeaderFileTypeCore: return eStrataUnknown; // 0x4u MH_CORE
Sean Callananac725af2012-02-10 20:22:35 +00002719 case HeaderFileTypePreloadedExecutable: return eStrataRawImage; // 0x5u MH_PRELOAD
Greg Claytonca319972011-07-09 00:41:34 +00002720 case HeaderFileTypeDynamicShlib: return eStrataUser; // 0x6u MH_DYLIB
2721 case HeaderFileTypeDynamicLinkEditor: return eStrataUser; // 0x7u MH_DYLINKER
2722 case HeaderFileTypeBundle: return eStrataUser; // 0x8u MH_BUNDLE
2723 case HeaderFileTypeDynamicShlibStub: return eStrataUser; // 0x9u MH_DYLIB_STUB
2724 case HeaderFileTypeDSYM: return eStrataUnknown; // 0xAu MH_DSYM
2725 case HeaderFileTypeKextBundle: return eStrataKernel; // 0xBu MH_KEXT_BUNDLE
2726 default:
2727 break;
2728 }
2729 return eStrataUnknown;
2730}
2731
2732
Greg Clayton49f4bf22012-02-22 19:41:02 +00002733uint32_t
2734ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
2735{
Greg Clayton9482f052012-03-13 23:14:29 +00002736 ModuleSP module_sp(GetModule());
2737 if (module_sp)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002738 {
Greg Clayton9482f052012-03-13 23:14:29 +00002739 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2740 struct dylib_command load_cmd;
2741 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2742 uint32_t version_cmd = 0;
2743 uint64_t version = 0;
2744 uint32_t i;
2745 for (i=0; i<m_header.ncmds; ++i)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002746 {
Greg Clayton9482f052012-03-13 23:14:29 +00002747 const uint32_t cmd_offset = offset;
2748 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2749 break;
2750
2751 if (load_cmd.cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002752 {
Greg Clayton9482f052012-03-13 23:14:29 +00002753 if (version_cmd == 0)
2754 {
2755 version_cmd = load_cmd.cmd;
2756 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
2757 break;
2758 version = load_cmd.dylib.current_version;
2759 }
2760 break; // Break for now unless there is another more complete version
2761 // number load command in the future.
Greg Clayton49f4bf22012-02-22 19:41:02 +00002762 }
Greg Clayton9482f052012-03-13 23:14:29 +00002763 offset = cmd_offset + load_cmd.cmdsize;
Greg Clayton49f4bf22012-02-22 19:41:02 +00002764 }
Greg Clayton9482f052012-03-13 23:14:29 +00002765
2766 if (version_cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002767 {
Greg Clayton9482f052012-03-13 23:14:29 +00002768 if (versions != NULL && num_versions > 0)
2769 {
2770 if (num_versions > 0)
2771 versions[0] = (version & 0xFFFF0000ull) >> 16;
2772 if (num_versions > 1)
2773 versions[1] = (version & 0x0000FF00ull) >> 8;
2774 if (num_versions > 2)
2775 versions[2] = (version & 0x000000FFull);
2776 // Fill in an remaining version numbers with invalid values
2777 for (i=3; i<num_versions; ++i)
2778 versions[i] = UINT32_MAX;
2779 }
2780 // The LC_ID_DYLIB load command has a version with 3 version numbers
2781 // in it, so always return 3
2782 return 3;
Greg Clayton49f4bf22012-02-22 19:41:02 +00002783 }
Greg Clayton49f4bf22012-02-22 19:41:02 +00002784 }
2785 return false;
2786}
2787
Chris Lattner24943d22010-06-08 16:52:24 +00002788bool
Greg Clayton395fc332011-02-15 21:59:32 +00002789ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +00002790{
Greg Clayton9482f052012-03-13 23:14:29 +00002791 ModuleSP module_sp(GetModule());
2792 if (module_sp)
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002793 {
Greg Clayton9482f052012-03-13 23:14:29 +00002794 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2795 arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
2796
2797 // Files with type MH_PRELOAD are currently used in cases where the image
2798 // debugs at the addresses in the file itself. Below we set the OS to
2799 // unknown to make sure we use the DynamicLoaderStatic()...
2800 if (m_header.filetype == HeaderFileTypePreloadedExecutable)
2801 {
2802 arch.GetTriple().setOS (llvm::Triple::UnknownOS);
2803 }
2804 return true;
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002805 }
Greg Clayton9482f052012-03-13 23:14:29 +00002806 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00002807}
2808
2809
2810//------------------------------------------------------------------
2811// PluginInterface protocol
2812//------------------------------------------------------------------
2813const char *
2814ObjectFileMachO::GetPluginName()
2815{
2816 return "ObjectFileMachO";
2817}
2818
2819const char *
2820ObjectFileMachO::GetShortPluginName()
2821{
2822 return GetPluginNameStatic();
2823}
2824
2825uint32_t
2826ObjectFileMachO::GetPluginVersion()
2827{
2828 return 1;
2829}
2830