blob: 514c3966ee32fc930a54943350ec8829f8fd12de [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;
Chris Lattner24943d22010-06-08 16:52:24 +0000754 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
755 uint32_t i;
Greg Clayton46c9a352012-02-09 06:16:32 +0000756 const bool is_core = GetType() == eTypeCoreFile;
Chris Lattner24943d22010-06-08 16:52:24 +0000757 //bool dump_sections = false;
Greg Clayton3508c382012-02-24 01:59:29 +0000758 ModuleSP module_sp (GetModule());
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000759 // First look up any LC_ENCRYPTION_INFO load commands
760 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
761 EncryptedFileRanges encrypted_file_ranges;
Greg Clayton54e33712012-05-25 18:09:55 +0000762 encryption_info_command encryption_cmd;
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000763 for (i=0; i<m_header.ncmds; ++i)
764 {
765 const uint32_t load_cmd_offset = offset;
Greg Clayton54e33712012-05-25 18:09:55 +0000766 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000767 break;
768
Greg Clayton54e33712012-05-25 18:09:55 +0000769 if (encryption_cmd.cmd == LoadCommandEncryptionInfo)
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000770 {
Greg Clayton54e33712012-05-25 18:09:55 +0000771 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
772 {
773 if (encryption_cmd.cryptid != 0)
774 {
775 EncryptedFileRanges::Entry entry;
776 entry.SetRangeBase(encryption_cmd.cryptoff);
777 entry.SetByteSize(encryption_cmd.cryptsize);
778 encrypted_file_ranges.Append(entry);
779 }
780 }
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000781 }
Greg Clayton54e33712012-05-25 18:09:55 +0000782 offset = load_cmd_offset + encryption_cmd.cmdsize;
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000783 }
784
785 offset = MachHeaderSizeFromMagic(m_header.magic);
786
Greg Clayton54e33712012-05-25 18:09:55 +0000787 struct segment_command_64 load_cmd;
Chris Lattner24943d22010-06-08 16:52:24 +0000788 for (i=0; i<m_header.ncmds; ++i)
789 {
790 const uint32_t load_cmd_offset = offset;
791 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
792 break;
793
Greg Clayton1674b122010-07-21 22:12:05 +0000794 if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
Chris Lattner24943d22010-06-08 16:52:24 +0000795 {
796 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
797 {
798 load_cmd.vmaddr = m_data.GetAddress(&offset);
799 load_cmd.vmsize = m_data.GetAddress(&offset);
800 load_cmd.fileoff = m_data.GetAddress(&offset);
801 load_cmd.filesize = m_data.GetAddress(&offset);
802 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
803 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000804
805 const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
806
Chris Lattner24943d22010-06-08 16:52:24 +0000807 // Keep a list of mach segments around in case we need to
808 // get at data that isn't stored in the abstracted Sections.
809 m_mach_segments.push_back (load_cmd);
810
811 ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
812 // Use a segment ID of the segment index shifted left by 8 so they
813 // never conflict with any of the sections.
814 SectionSP segment_sp;
Greg Clayton46c9a352012-02-09 06:16:32 +0000815 if (segment_name || is_core)
Chris Lattner24943d22010-06-08 16:52:24 +0000816 {
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000817 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
Chris Lattner24943d22010-06-08 16:52:24 +0000818 ++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
819 segment_name, // Name of this section
820 eSectionTypeContainer, // This section is a container of other sections.
821 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
822 load_cmd.vmsize, // VM size in bytes of this section
823 load_cmd.fileoff, // Offset to the data for this section in the file
824 load_cmd.filesize, // Size in bytes of this section as found in the the file
825 load_cmd.flags)); // Flags for this section
826
Greg Clayton68ca8232011-01-25 02:58:48 +0000827 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000828 m_sections_ap->AddSection(segment_sp);
829 }
830
831 struct section_64 sect64;
Greg Claytonddff7cc2011-02-04 21:13:05 +0000832 ::memset (&sect64, 0, sizeof(sect64));
Chris Lattner24943d22010-06-08 16:52:24 +0000833 // Push a section into our mach sections for the section at
Greg Clayton6af4fad2010-10-06 01:26:32 +0000834 // index zero (NListSectionNoSection) if we don't have any
835 // mach sections yet...
836 if (m_mach_sections.empty())
837 m_mach_sections.push_back(sect64);
Chris Lattner24943d22010-06-08 16:52:24 +0000838 uint32_t segment_sect_idx;
839 const lldb::user_id_t first_segment_sectID = sectID + 1;
840
841
Greg Clayton1674b122010-07-21 22:12:05 +0000842 const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
Chris Lattner24943d22010-06-08 16:52:24 +0000843 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
844 {
845 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
846 break;
847 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
848 break;
849 sect64.addr = m_data.GetAddress(&offset);
850 sect64.size = m_data.GetAddress(&offset);
851
852 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
853 break;
854
855 // Keep a list of mach sections around in case we need to
856 // get at data that isn't stored in the abstracted Sections.
857 m_mach_sections.push_back (sect64);
858
859 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
860 if (!segment_name)
861 {
862 // We have a segment with no name so we need to conjure up
863 // segments that correspond to the section's segname if there
864 // isn't already such a section. If there is such a section,
865 // we resize the section so that it spans all sections.
866 // We also mark these sections as fake so address matches don't
867 // hit if they land in the gaps between the child sections.
868 segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
869 segment_sp = m_sections_ap->FindSectionByName (segment_name);
870 if (segment_sp.get())
871 {
872 Section *segment = segment_sp.get();
873 // Grow the section size as needed.
874 const lldb::addr_t sect64_min_addr = sect64.addr;
875 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
876 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
877 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
878 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
879 if (sect64_min_addr >= curr_seg_min_addr)
880 {
881 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
882 // Only grow the section size if needed
883 if (new_seg_byte_size > curr_seg_byte_size)
884 segment->SetByteSize (new_seg_byte_size);
885 }
886 else
887 {
888 // We need to change the base address of the segment and
889 // adjust the child section offsets for all existing children.
890 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
891 segment->Slide(slide_amount, false);
Sean Callanan716a6642012-06-08 02:16:08 +0000892 segment->GetChildren().Slide(-slide_amount, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000893 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
894 }
Greg Clayton661825b2010-06-28 23:51:11 +0000895
896 // Grow the section size as needed.
897 if (sect64.offset)
898 {
899 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
900 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
901
902 const lldb::addr_t section_min_file_offset = sect64.offset;
903 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
904 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
905 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
906 segment->SetFileOffset (new_file_offset);
907 segment->SetFileSize (new_file_size);
908 }
Chris Lattner24943d22010-06-08 16:52:24 +0000909 }
910 else
911 {
912 // Create a fake section for the section's named segment
Greg Clayton3508c382012-02-24 01:59:29 +0000913 segment_sp.reset(new Section (segment_sp, // Parent section
914 module_sp, // Module to which this section belongs
915 ++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
916 segment_name, // Name of this section
917 eSectionTypeContainer, // This section is a container of other sections.
918 sect64.addr, // File VM address == addresses as they are found in the object file
919 sect64.size, // VM size in bytes of this section
920 sect64.offset, // Offset to the data for this section in the file
921 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
922 load_cmd.flags)); // Flags for this section
Chris Lattner24943d22010-06-08 16:52:24 +0000923 segment_sp->SetIsFake(true);
924 m_sections_ap->AddSection(segment_sp);
Greg Clayton68ca8232011-01-25 02:58:48 +0000925 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000926 }
927 }
928 assert (segment_sp.get());
929
Greg Clayton1674b122010-07-21 22:12:05 +0000930 uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
Chris Lattner24943d22010-06-08 16:52:24 +0000931 static ConstString g_sect_name_objc_data ("__objc_data");
932 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
933 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
934 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
935 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
936 static ConstString g_sect_name_objc_const ("__objc_const");
937 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
938 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000939
940 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
941 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
942 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
943 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
944 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
945 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
946 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
947 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
948 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
949 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
950 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
Greg Claytonf6e3de22011-09-28 17:06:40 +0000951 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
952 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
Greg Clayton00db2152011-10-04 22:41:51 +0000953 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
Greg Clayton24a6bd92011-10-27 17:55:14 +0000954 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000955 static ConstString g_sect_name_eh_frame ("__eh_frame");
Greg Clayton3fed8b92010-10-08 00:21:05 +0000956 static ConstString g_sect_name_DATA ("__DATA");
957 static ConstString g_sect_name_TEXT ("__TEXT");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000958
Chris Lattner24943d22010-06-08 16:52:24 +0000959 SectionType sect_type = eSectionTypeOther;
960
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000961 if (section_name == g_sect_name_dwarf_debug_abbrev)
962 sect_type = eSectionTypeDWARFDebugAbbrev;
963 else if (section_name == g_sect_name_dwarf_debug_aranges)
964 sect_type = eSectionTypeDWARFDebugAranges;
965 else if (section_name == g_sect_name_dwarf_debug_frame)
966 sect_type = eSectionTypeDWARFDebugFrame;
967 else if (section_name == g_sect_name_dwarf_debug_info)
968 sect_type = eSectionTypeDWARFDebugInfo;
969 else if (section_name == g_sect_name_dwarf_debug_line)
970 sect_type = eSectionTypeDWARFDebugLine;
971 else if (section_name == g_sect_name_dwarf_debug_loc)
972 sect_type = eSectionTypeDWARFDebugLoc;
973 else if (section_name == g_sect_name_dwarf_debug_macinfo)
974 sect_type = eSectionTypeDWARFDebugMacInfo;
975 else if (section_name == g_sect_name_dwarf_debug_pubnames)
976 sect_type = eSectionTypeDWARFDebugPubNames;
977 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
978 sect_type = eSectionTypeDWARFDebugPubTypes;
979 else if (section_name == g_sect_name_dwarf_debug_ranges)
980 sect_type = eSectionTypeDWARFDebugRanges;
981 else if (section_name == g_sect_name_dwarf_debug_str)
982 sect_type = eSectionTypeDWARFDebugStr;
Greg Claytonf6e3de22011-09-28 17:06:40 +0000983 else if (section_name == g_sect_name_dwarf_apple_names)
984 sect_type = eSectionTypeDWARFAppleNames;
985 else if (section_name == g_sect_name_dwarf_apple_types)
986 sect_type = eSectionTypeDWARFAppleTypes;
Greg Clayton00db2152011-10-04 22:41:51 +0000987 else if (section_name == g_sect_name_dwarf_apple_namespaces)
988 sect_type = eSectionTypeDWARFAppleNamespaces;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000989 else if (section_name == g_sect_name_dwarf_apple_objc)
990 sect_type = eSectionTypeDWARFAppleObjC;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000991 else if (section_name == g_sect_name_objc_selrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000992 sect_type = eSectionTypeDataCStringPointers;
Chris Lattner24943d22010-06-08 16:52:24 +0000993 else if (section_name == g_sect_name_objc_msgrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000994 sect_type = eSectionTypeDataObjCMessageRefs;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000995 else if (section_name == g_sect_name_eh_frame)
996 sect_type = eSectionTypeEHFrame;
997 else if (section_name == g_sect_name_cfstring)
998 sect_type = eSectionTypeDataObjCCFStrings;
Chris Lattner24943d22010-06-08 16:52:24 +0000999 else if (section_name == g_sect_name_objc_data ||
1000 section_name == g_sect_name_objc_classrefs ||
1001 section_name == g_sect_name_objc_superrefs ||
1002 section_name == g_sect_name_objc_const ||
1003 section_name == g_sect_name_objc_classlist)
1004 {
1005 sect_type = eSectionTypeDataPointers;
1006 }
Chris Lattner24943d22010-06-08 16:52:24 +00001007
1008 if (sect_type == eSectionTypeOther)
1009 {
1010 switch (mach_sect_type)
1011 {
1012 // TODO: categorize sections by other flags for regular sections
Greg Clayton3fed8b92010-10-08 00:21:05 +00001013 case SectionTypeRegular:
1014 if (segment_sp->GetName() == g_sect_name_TEXT)
1015 sect_type = eSectionTypeCode;
1016 else if (segment_sp->GetName() == g_sect_name_DATA)
1017 sect_type = eSectionTypeData;
1018 else
1019 sect_type = eSectionTypeOther;
1020 break;
Greg Clayton1674b122010-07-21 22:12:05 +00001021 case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
1022 case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1023 case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1024 case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1025 case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1026 case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1027 case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1028 case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1029 case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1030 case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1031 case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
1032 case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
1033 case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1034 case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1035 case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
1036 case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
Chris Lattner24943d22010-06-08 16:52:24 +00001037 default: break;
1038 }
1039 }
1040
Greg Clayton3508c382012-02-24 01:59:29 +00001041 SectionSP section_sp(new Section (segment_sp,
1042 module_sp,
1043 ++sectID,
1044 section_name,
1045 sect_type,
1046 sect64.addr - segment_sp->GetFileAddress(),
1047 sect64.size,
1048 sect64.offset,
1049 sect64.offset == 0 ? 0 : sect64.size,
1050 sect64.flags));
Greg Clayton68ca8232011-01-25 02:58:48 +00001051 // Set the section to be encrypted to match the segment
Greg Clayton6f7f8da2012-04-24 03:06:13 +00001052
1053 bool section_is_encrypted = false;
1054 if (!segment_is_encrypted && load_cmd.filesize != 0)
1055 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
Greg Clayton68ca8232011-01-25 02:58:48 +00001056
Greg Clayton6f7f8da2012-04-24 03:06:13 +00001057 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +00001058 segment_sp->GetChildren().AddSection(section_sp);
1059
1060 if (segment_sp->IsFake())
1061 {
1062 segment_sp.reset();
1063 segment_name.Clear();
1064 }
1065 }
Greg Clayton0fa51242011-07-19 03:57:15 +00001066 if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
Chris Lattner24943d22010-06-08 16:52:24 +00001067 {
1068 if (first_segment_sectID <= sectID)
1069 {
1070 lldb::user_id_t sect_uid;
1071 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
1072 {
1073 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1074 SectionSP next_section_sp;
1075 if (sect_uid + 1 <= sectID)
1076 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1077
1078 if (curr_section_sp.get())
1079 {
1080 if (curr_section_sp->GetByteSize() == 0)
1081 {
1082 if (next_section_sp.get() != NULL)
1083 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1084 else
1085 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1086 }
1087 }
1088 }
1089 }
1090 }
1091 }
1092 }
1093 }
Greg Clayton1674b122010-07-21 22:12:05 +00001094 else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
Chris Lattner24943d22010-06-08 16:52:24 +00001095 {
1096 m_dysymtab.cmd = load_cmd.cmd;
1097 m_dysymtab.cmdsize = load_cmd.cmdsize;
1098 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1099 }
1100
1101 offset = load_cmd_offset + load_cmd.cmdsize;
1102 }
1103// if (dump_sections)
1104// {
1105// StreamFile s(stdout);
1106// m_sections_ap->Dump(&s, true);
1107// }
1108 return sectID; // Return the number of sections we registered with the module
1109}
1110
1111class MachSymtabSectionInfo
1112{
1113public:
1114
1115 MachSymtabSectionInfo (SectionList *section_list) :
1116 m_section_list (section_list),
1117 m_section_infos()
1118 {
1119 // Get the number of sections down to a depth of 1 to include
1120 // all segments and their sections, but no other sections that
1121 // may be added for debug map or
1122 m_section_infos.resize(section_list->GetNumSections(1));
1123 }
1124
1125
Greg Clayton3508c382012-02-24 01:59:29 +00001126 SectionSP
Chris Lattner24943d22010-06-08 16:52:24 +00001127 GetSection (uint8_t n_sect, addr_t file_addr)
1128 {
1129 if (n_sect == 0)
Greg Clayton3508c382012-02-24 01:59:29 +00001130 return SectionSP();
Chris Lattner24943d22010-06-08 16:52:24 +00001131 if (n_sect < m_section_infos.size())
1132 {
Greg Clayton3508c382012-02-24 01:59:29 +00001133 if (!m_section_infos[n_sect].section_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001134 {
Greg Clayton3508c382012-02-24 01:59:29 +00001135 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1136 m_section_infos[n_sect].section_sp = section_sp;
1137 if (section_sp != NULL)
Greg Clayton5638d2c2011-07-10 17:32:33 +00001138 {
Greg Clayton3508c382012-02-24 01:59:29 +00001139 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1140 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Clayton5638d2c2011-07-10 17:32:33 +00001141 }
1142 else
1143 {
Greg Claytondf6dc882012-01-05 03:57:59 +00001144 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Clayton5638d2c2011-07-10 17:32:33 +00001145 }
Chris Lattner24943d22010-06-08 16:52:24 +00001146 }
1147 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton811b9c52011-08-26 20:01:35 +00001148 {
1149 // Symbol is in section.
Greg Clayton3508c382012-02-24 01:59:29 +00001150 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001151 }
1152 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1153 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1154 {
1155 // Symbol is in section with zero size, but has the same start
1156 // address as the section. This can happen with linker symbols
1157 // (symbols that start with the letter 'l' or 'L'.
Greg Clayton3508c382012-02-24 01:59:29 +00001158 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001159 }
Chris Lattner24943d22010-06-08 16:52:24 +00001160 }
Greg Clayton3508c382012-02-24 01:59:29 +00001161 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner24943d22010-06-08 16:52:24 +00001162 }
1163
1164protected:
1165 struct SectionInfo
1166 {
1167 SectionInfo () :
1168 vm_range(),
Greg Clayton3508c382012-02-24 01:59:29 +00001169 section_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +00001170 {
1171 }
1172
1173 VMRange vm_range;
Greg Clayton3508c382012-02-24 01:59:29 +00001174 SectionSP section_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001175 };
1176 SectionList *m_section_list;
1177 std::vector<SectionInfo> m_section_infos;
1178};
1179
1180
1181
1182size_t
1183ObjectFileMachO::ParseSymtab (bool minimize)
1184{
1185 Timer scoped_timer(__PRETTY_FUNCTION__,
1186 "ObjectFileMachO::ParseSymtab () module = %s",
1187 m_file.GetFilename().AsCString(""));
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001188 ModuleSP module_sp (GetModule());
1189 if (!module_sp)
1190 return 0;
1191
1192 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
1193 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
1194 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
1195 FunctionStarts function_starts;
Chris Lattner24943d22010-06-08 16:52:24 +00001196 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1197 uint32_t i;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001198
Greg Clayton0fea0512011-12-30 00:32:24 +00001199 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
1200
Chris Lattner24943d22010-06-08 16:52:24 +00001201 for (i=0; i<m_header.ncmds; ++i)
1202 {
1203 const uint32_t cmd_offset = offset;
1204 // Read in the load command and load command size
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001205 struct load_command lc;
1206 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001207 break;
1208 // Watch for the symbol table load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001209 switch (lc.cmd)
Chris Lattner24943d22010-06-08 16:52:24 +00001210 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001211 case LoadCommandSymtab:
1212 symtab_load_command.cmd = lc.cmd;
1213 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00001214 // Read in the rest of the symtab load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001215 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
1216 return 0;
1217 if (symtab_load_command.symoff == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001218 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001219 if (log)
1220 module_sp->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
1221 return 0;
1222 }
1223
1224 if (symtab_load_command.stroff == 0)
1225 {
1226 if (log)
1227 module_sp->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
1228 return 0;
1229 }
1230
1231 if (symtab_load_command.nsyms == 0)
1232 {
1233 if (log)
1234 module_sp->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
1235 return 0;
1236 }
1237
1238 if (symtab_load_command.strsize == 0)
1239 {
1240 if (log)
1241 module_sp->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
1242 return 0;
1243 }
1244 break;
1245
1246 case LoadCommandFunctionStarts:
1247 function_starts_load_command.cmd = lc.cmd;
1248 function_starts_load_command.cmdsize = lc.cmdsize;
1249 if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
1250 bzero (&function_starts_load_command, sizeof(function_starts_load_command));
1251 break;
1252
1253 default:
1254 break;
1255 }
1256 offset = cmd_offset + lc.cmdsize;
1257 }
1258
1259 if (symtab_load_command.cmd)
1260 {
1261 Symtab *symtab = m_symtab_ap.get();
1262 SectionList *section_list = GetSectionList();
1263 if (section_list == NULL)
1264 return 0;
1265
1266 ProcessSP process_sp (m_process_wp.lock());
Greg Claytondd29b972012-05-18 23:20:01 +00001267 Process *process = process_sp.get();
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001268
1269 const size_t addr_byte_size = m_data.GetAddressByteSize();
1270 bool bit_width_32 = addr_byte_size == 4;
1271 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
1272
1273 DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1274 DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1275 DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1276
1277 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
1278 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Claytondd29b972012-05-18 23:20:01 +00001279 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
1280 if (process)
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001281 {
Greg Claytondd29b972012-05-18 23:20:01 +00001282 Target &target = process->GetTarget();
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001283 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
1284 // Reading mach file from memory in a process or core file...
1285
1286 if (linkedit_section_sp)
1287 {
1288 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
1289 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
1290 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Claytondd29b972012-05-18 23:20:01 +00001291 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton29021d32012-04-18 05:19:20 +00001292
1293 bool data_was_read = false;
1294
1295#if defined (__APPLE__) && defined (__arm__)
1296 if (m_header.flags & 0x80000000u)
Greg Clayton0fea0512011-12-30 00:32:24 +00001297 {
Greg Clayton29021d32012-04-18 05:19:20 +00001298 // This mach-o memory file is in the dyld shared cache. If this
1299 // program is not remote and this is iOS, then this process will
1300 // share the same shared cache as the process we are debugging and
1301 // we can read the entire __LINKEDIT from the address space in this
1302 // process. This is a needed optimization that is used for local iOS
1303 // debugging only since all shared libraries in the shared cache do
1304 // not have corresponding files that exist in the file system of the
1305 // device. They have been combined into a single file. This means we
1306 // always have to load these files from memory. All of the symbol and
1307 // string tables from all of the __LINKEDIT sections from the shared
1308 // libraries in the shared cache have been merged into a single large
1309 // symbol and string table. Reading all of this symbol and string table
1310 // data across can slow down debug launch times, so we optimize this by
1311 // reading the memory for the __LINKEDIT section from this process.
1312 PlatformSP platform_sp (target.GetPlatform());
1313 if (platform_sp && platform_sp->IsHost())
1314 {
1315 data_was_read = true;
1316 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Claytondd29b972012-05-18 23:20:01 +00001317 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton29021d32012-04-18 05:19:20 +00001318 if (function_starts_load_command.cmd)
1319 {
1320 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1321 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
1322 }
1323 }
1324 }
1325#endif
1326
1327 if (!data_was_read)
1328 {
1329 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
1330 if (nlist_data_sp)
1331 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
Greg Claytondd29b972012-05-18 23:20:01 +00001332 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
1333 //if (strtab_data_sp)
1334 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
Greg Clayton29021d32012-04-18 05:19:20 +00001335 if (function_starts_load_command.cmd)
1336 {
1337 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1338 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
1339 if (func_start_data_sp)
1340 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
1341 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001342 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001343 }
1344 }
1345 else
1346 {
1347 nlist_data.SetData (m_data,
1348 symtab_load_command.symoff,
1349 nlist_data_byte_size);
1350 strtab_data.SetData (m_data,
1351 symtab_load_command.stroff,
1352 strtab_data_byte_size);
1353 if (function_starts_load_command.cmd)
1354 {
1355 function_starts_data.SetData (m_data,
1356 function_starts_load_command.dataoff,
1357 function_starts_load_command.datasize);
1358 }
1359 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001360
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001361 if (nlist_data.GetByteSize() == 0)
1362 {
1363 if (log)
1364 module_sp->LogMessage(log.get(), "failed to read nlist data");
1365 return 0;
1366 }
1367
1368
Greg Clayton3a5dc012012-05-25 17:04:00 +00001369 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
1370 if (!have_strtab_data)
Greg Claytondd29b972012-05-18 23:20:01 +00001371 {
Greg Clayton3a5dc012012-05-25 17:04:00 +00001372 if (process)
1373 {
1374 if (strtab_addr == LLDB_INVALID_ADDRESS)
1375 {
1376 if (log)
1377 module_sp->LogMessage(log.get(), "failed to locate the strtab in memory");
1378 return 0;
1379 }
1380 }
1381 else
Greg Claytondd29b972012-05-18 23:20:01 +00001382 {
1383 if (log)
Greg Clayton3a5dc012012-05-25 17:04:00 +00001384 module_sp->LogMessage(log.get(), "failed to read strtab data");
Greg Claytondd29b972012-05-18 23:20:01 +00001385 return 0;
1386 }
1387 }
Greg Claytondd29b972012-05-18 23:20:01 +00001388
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001389 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
1390 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
1391 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
1392 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
1393 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
1394 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
1395 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
1396 SectionSP eh_frame_section_sp;
1397 if (text_section_sp.get())
1398 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
1399 else
1400 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
1401
Greg Claytond2653c22012-03-14 01:53:24 +00001402 const bool is_arm = (m_header.cputype == llvm::MachO::CPUTypeARM);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001403 if (text_section_sp && function_starts_data.GetByteSize())
1404 {
1405 FunctionStarts::Entry function_start_entry;
1406 function_start_entry.data = false;
1407 uint32_t function_start_offset = 0;
1408 function_start_entry.addr = text_section_sp->GetFileAddress();
1409 uint64_t delta;
1410 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
1411 {
1412 // Now append the current entry
1413 function_start_entry.addr += delta;
1414 function_starts.Append(function_start_entry);
1415 }
1416 }
1417
1418 const uint32_t function_starts_count = function_starts.GetSize();
1419
1420 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
1421
1422 uint32_t nlist_data_offset = 0;
1423
1424 uint32_t N_SO_index = UINT32_MAX;
1425
1426 MachSymtabSectionInfo section_info (section_list);
1427 std::vector<uint32_t> N_FUN_indexes;
1428 std::vector<uint32_t> N_NSYM_indexes;
1429 std::vector<uint32_t> N_INCL_indexes;
1430 std::vector<uint32_t> N_BRAC_indexes;
1431 std::vector<uint32_t> N_COMM_indexes;
1432 typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
1433 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
1434 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
1435 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
1436 // Any symbols that get merged into another will get an entry
1437 // in this map so we know
1438 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
1439 uint32_t nlist_idx = 0;
1440 Symbol *symbol_ptr = NULL;
1441
1442 uint32_t sym_idx = 0;
1443 Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1444 uint32_t num_syms = symtab->GetNumSymbols();
Greg Claytondd29b972012-05-18 23:20:01 +00001445 std::string memory_symbol_name;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001446
1447 //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1448 for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
1449 {
1450 struct nlist_64 nlist;
1451 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
1452 break;
1453
1454 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
1455 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
1456 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
1457 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
1458 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
1459
1460 SymbolType type = eSymbolTypeInvalid;
Greg Claytondd29b972012-05-18 23:20:01 +00001461 const char *symbol_name = NULL;
1462
Greg Clayton3a5dc012012-05-25 17:04:00 +00001463 if (have_strtab_data)
Greg Claytondd29b972012-05-18 23:20:01 +00001464 {
1465 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
1466
1467 if (symbol_name == NULL)
1468 {
1469 // No symbol should be NULL, even the symbols with no
1470 // string values should have an offset zero which points
1471 // to an empty C-string
1472 Host::SystemLog (Host::eSystemLogError,
1473 "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
1474 nlist_idx,
1475 nlist.n_strx,
1476 module_sp->GetFileSpec().GetDirectory().GetCString(),
1477 module_sp->GetFileSpec().GetFilename().GetCString());
1478 continue;
1479 }
1480 if (symbol_name[0] == '\0')
1481 symbol_name = NULL;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001482 }
Greg Clayton3a5dc012012-05-25 17:04:00 +00001483 else
1484 {
1485 const addr_t str_addr = strtab_addr + nlist.n_strx;
1486 Error str_error;
1487 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
1488 symbol_name = memory_symbol_name.c_str();
1489 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001490 const char *symbol_name_non_abi_mangled = NULL;
1491
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001492 SectionSP symbol_section;
1493 uint32_t symbol_byte_size = 0;
1494 bool add_nlist = true;
1495 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
1496
1497 assert (sym_idx < num_syms);
1498
1499 sym[sym_idx].SetDebug (is_debug);
1500
1501 if (is_debug)
1502 {
1503 switch (nlist.n_type)
Greg Clayton0fea0512011-12-30 00:32:24 +00001504 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001505 case StabGlobalSymbol:
1506 // N_GSYM -- global symbol: name,,NO_SECT,type,0
1507 // Sometimes the N_GSYM value contains the address.
1508
1509 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
1510 // have the same address, but we want to ensure that we always find only the real symbol,
1511 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
1512 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
1513 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
1514 // same address.
1515
1516 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
1517 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
1518 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
1519 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
1520 add_nlist = false;
1521 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00001522 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001523 sym[sym_idx].SetExternal(true);
1524 if (nlist.n_value != 0)
1525 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1526 type = eSymbolTypeData;
Greg Claytonb5a8f142012-02-05 02:38:54 +00001527 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001528 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +00001529
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001530 case StabFunctionName:
1531 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
1532 type = eSymbolTypeCompiler;
1533 break;
Greg Clayton0fea0512011-12-30 00:32:24 +00001534
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001535 case StabFunction:
1536 // N_FUN -- procedure: name,,n_sect,linenumber,address
1537 if (symbol_name)
Greg Claytona9c4f312011-10-31 20:50:40 +00001538 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001539 type = eSymbolTypeCode;
1540 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1541
1542 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
1543 // We use the current number of symbols in the symbol table in lieu of
1544 // using nlist_idx in case we ever start trimming entries out
1545 N_FUN_indexes.push_back(sym_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001546 }
1547 else
1548 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001549 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00001550
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001551 if ( !N_FUN_indexes.empty() )
Chris Lattner24943d22010-06-08 16:52:24 +00001552 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001553 // Copy the size of the function into the original STAB entry so we don't have
1554 // to hunt for it later
1555 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
1556 N_FUN_indexes.pop_back();
1557 // We don't really need the end function STAB as it contains the size which
1558 // we already placed with the original symbol, so don't add it if we want a
1559 // minimal symbol table
1560 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001561 add_nlist = false;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001562 }
Greg Clayton3f69eac2011-12-03 02:30:59 +00001563 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001564 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001565
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001566 case StabStaticSymbol:
1567 // N_STSYM -- static symbol: name,,n_sect,type,address
1568 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
1569 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1570 type = eSymbolTypeData;
1571 break;
1572
1573 case StabLocalCommon:
1574 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
1575 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1576 type = eSymbolTypeCommonBlock;
1577 break;
1578
1579 case StabBeginSymbol:
1580 // N_BNSYM
1581 // We use the current number of symbols in the symbol table in lieu of
1582 // using nlist_idx in case we ever start trimming entries out
1583 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001584 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001585 // Skip these if we want minimal symbol tables
1586 add_nlist = false;
1587 }
1588 else
1589 {
1590 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1591 N_NSYM_indexes.push_back(sym_idx);
1592 type = eSymbolTypeScopeBegin;
1593 }
1594 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001595
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001596 case StabEndSymbol:
1597 // N_ENSYM
1598 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
1599 // so that we can always skip the entire symbol if we need to navigate
1600 // more quickly at the source level when parsing STABS
1601 if (minimize)
1602 {
1603 // Skip these if we want minimal symbol tables
1604 add_nlist = false;
1605 }
1606 else
1607 {
1608 if ( !N_NSYM_indexes.empty() )
Greg Clayton3f69eac2011-12-03 02:30:59 +00001609 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001610 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
1611 symbol_ptr->SetByteSize(sym_idx + 1);
1612 symbol_ptr->SetSizeIsSibling(true);
1613 N_NSYM_indexes.pop_back();
1614 }
1615 type = eSymbolTypeScopeEnd;
1616 }
1617 break;
1618
1619
1620 case StabSourceFileOptions:
1621 // N_OPT - emitted with gcc2_compiled and in gcc source
1622 type = eSymbolTypeCompiler;
1623 break;
1624
1625 case StabRegisterSymbol:
1626 // N_RSYM - register sym: name,,NO_SECT,type,register
1627 type = eSymbolTypeVariable;
1628 break;
1629
1630 case StabSourceLine:
1631 // N_SLINE - src line: 0,,n_sect,linenumber,address
1632 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1633 type = eSymbolTypeLineEntry;
1634 break;
1635
1636 case StabStructureType:
1637 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
1638 type = eSymbolTypeVariableType;
1639 break;
1640
1641 case StabSourceFileName:
1642 // N_SO - source file name
1643 type = eSymbolTypeSourceFile;
1644 if (symbol_name == NULL)
1645 {
1646 if (minimize)
1647 add_nlist = false;
1648 if (N_SO_index != UINT32_MAX)
1649 {
1650 // Set the size of the N_SO to the terminating index of this N_SO
1651 // so that we can always skip the entire N_SO if we need to navigate
1652 // more quickly at the source level when parsing STABS
1653 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
1654 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
1655 symbol_ptr->SetSizeIsSibling(true);
1656 }
1657 N_NSYM_indexes.clear();
1658 N_INCL_indexes.clear();
1659 N_BRAC_indexes.clear();
1660 N_COMM_indexes.clear();
1661 N_FUN_indexes.clear();
1662 N_SO_index = UINT32_MAX;
1663 }
1664 else
1665 {
1666 // We use the current number of symbols in the symbol table in lieu of
1667 // using nlist_idx in case we ever start trimming entries out
Greg Clayton5fa6cd32012-05-30 20:20:34 +00001668 const bool N_SO_has_full_path = symbol_name[0] == '/';
1669 if (N_SO_has_full_path)
1670 {
1671 if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1672 {
1673 // We have two consecutive N_SO entries where the first contains a directory
1674 // and the second contains a full path.
1675 sym[sym_idx - 1].GetMangled().SetValue(symbol_name, false);
1676 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1677 add_nlist = false;
1678 }
1679 else
1680 {
1681 // This is the first entry in a N_SO that contains a directory or
1682 // a full path to the source file
1683 N_SO_index = sym_idx;
1684 }
1685 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001686 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1687 {
Greg Clayton5fa6cd32012-05-30 20:20:34 +00001688 // This is usually the second N_SO entry that contains just the filename,
1689 // so here we combine it with the first one if we are minimizing the symbol table
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001690 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
1691 if (so_path && so_path[0])
1692 {
1693 std::string full_so_path (so_path);
1694 if (*full_so_path.rbegin() != '/')
1695 full_so_path += '/';
1696 full_so_path += symbol_name;
1697 sym[sym_idx - 1].GetMangled().SetValue(full_so_path.c_str(), false);
1698 add_nlist = false;
1699 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1700 }
1701 }
1702 }
1703
1704 break;
1705
1706 case StabObjectFileName:
1707 // N_OSO - object file name: name,,0,0,st_mtime
1708 type = eSymbolTypeObjectFile;
1709 break;
1710
1711 case StabLocalSymbol:
1712 // N_LSYM - local sym: name,,NO_SECT,type,offset
1713 type = eSymbolTypeLocal;
1714 break;
1715
1716 //----------------------------------------------------------------------
1717 // INCL scopes
1718 //----------------------------------------------------------------------
1719 case StabBeginIncludeFileName:
1720 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
1721 // We use the current number of symbols in the symbol table in lieu of
1722 // using nlist_idx in case we ever start trimming entries out
1723 N_INCL_indexes.push_back(sym_idx);
1724 type = eSymbolTypeScopeBegin;
1725 break;
1726
1727 case StabEndIncludeFile:
1728 // N_EINCL - include file end: name,,NO_SECT,0,0
1729 // Set the size of the N_BINCL to the terminating index of this N_EINCL
1730 // so that we can always skip the entire symbol if we need to navigate
1731 // more quickly at the source level when parsing STABS
1732 if ( !N_INCL_indexes.empty() )
1733 {
1734 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
1735 symbol_ptr->SetByteSize(sym_idx + 1);
1736 symbol_ptr->SetSizeIsSibling(true);
1737 N_INCL_indexes.pop_back();
1738 }
1739 type = eSymbolTypeScopeEnd;
1740 break;
1741
1742 case StabIncludeFileName:
1743 // N_SOL - #included file name: name,,n_sect,0,address
1744 type = eSymbolTypeHeaderFile;
1745
1746 // We currently don't use the header files on darwin
1747 if (minimize)
1748 add_nlist = false;
1749 break;
1750
1751 case StabCompilerParameters:
1752 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
1753 type = eSymbolTypeCompiler;
1754 break;
1755
1756 case StabCompilerVersion:
1757 // N_VERSION - compiler version: name,,NO_SECT,0,0
1758 type = eSymbolTypeCompiler;
1759 break;
1760
1761 case StabCompilerOptLevel:
1762 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
1763 type = eSymbolTypeCompiler;
1764 break;
1765
1766 case StabParameter:
1767 // N_PSYM - parameter: name,,NO_SECT,type,offset
1768 type = eSymbolTypeVariable;
1769 break;
1770
1771 case StabAlternateEntry:
1772 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
1773 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1774 type = eSymbolTypeLineEntry;
1775 break;
1776
1777 //----------------------------------------------------------------------
1778 // Left and Right Braces
1779 //----------------------------------------------------------------------
1780 case StabLeftBracket:
1781 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
1782 // We use the current number of symbols in the symbol table in lieu of
1783 // using nlist_idx in case we ever start trimming entries out
1784 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1785 N_BRAC_indexes.push_back(sym_idx);
1786 type = eSymbolTypeScopeBegin;
1787 break;
1788
1789 case StabRightBracket:
1790 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
1791 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
1792 // so that we can always skip the entire symbol if we need to navigate
1793 // more quickly at the source level when parsing STABS
1794 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1795 if ( !N_BRAC_indexes.empty() )
1796 {
1797 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
1798 symbol_ptr->SetByteSize(sym_idx + 1);
1799 symbol_ptr->SetSizeIsSibling(true);
1800 N_BRAC_indexes.pop_back();
1801 }
1802 type = eSymbolTypeScopeEnd;
1803 break;
1804
1805 case StabDeletedIncludeFile:
1806 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
1807 type = eSymbolTypeHeaderFile;
1808 break;
1809
1810 //----------------------------------------------------------------------
1811 // COMM scopes
1812 //----------------------------------------------------------------------
1813 case StabBeginCommon:
1814 // N_BCOMM - begin common: name,,NO_SECT,0,0
1815 // We use the current number of symbols in the symbol table in lieu of
1816 // using nlist_idx in case we ever start trimming entries out
1817 type = eSymbolTypeScopeBegin;
1818 N_COMM_indexes.push_back(sym_idx);
1819 break;
1820
1821 case StabEndCommonLocal:
1822 // N_ECOML - end common (local name): 0,,n_sect,0,address
1823 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1824 // Fall through
1825
1826 case StabEndCommon:
1827 // N_ECOMM - end common: name,,n_sect,0,0
1828 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
1829 // so that we can always skip the entire symbol if we need to navigate
1830 // more quickly at the source level when parsing STABS
1831 if ( !N_COMM_indexes.empty() )
1832 {
1833 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
1834 symbol_ptr->SetByteSize(sym_idx + 1);
1835 symbol_ptr->SetSizeIsSibling(true);
1836 N_COMM_indexes.pop_back();
1837 }
1838 type = eSymbolTypeScopeEnd;
1839 break;
1840
1841 case StabLength:
1842 // N_LENG - second stab entry with length information
1843 type = eSymbolTypeAdditional;
1844 break;
1845
1846 default: break;
1847 }
1848 }
1849 else
1850 {
1851 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
1852 uint8_t n_type = NlistMaskType & nlist.n_type;
1853 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
1854
1855 switch (n_type)
1856 {
1857 case NListTypeIndirect: // N_INDR - Fall through
1858 case NListTypePreboundUndefined:// N_PBUD - Fall through
1859 case NListTypeUndefined: // N_UNDF
1860 type = eSymbolTypeUndefined;
1861 break;
1862
1863 case NListTypeAbsolute: // N_ABS
1864 type = eSymbolTypeAbsolute;
1865 break;
1866
1867 case NListTypeSection: // N_SECT
1868 {
1869 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1870
1871 if (symbol_section == NULL)
1872 {
1873 // TODO: warn about this?
1874 add_nlist = false;
1875 break;
1876 }
1877
1878 if (TEXT_eh_frame_sectID == nlist.n_sect)
1879 {
1880 type = eSymbolTypeException;
Chris Lattner24943d22010-06-08 16:52:24 +00001881 }
1882 else
1883 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001884 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
1885
1886 switch (section_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001887 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001888 case SectionTypeRegular: break; // regular section
1889 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
1890 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
1891 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
1892 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
1893 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
1894 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
1895 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
1896 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1897 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
1898 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
1899 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
1900 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
1901 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
1902 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
1903 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
1904 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
1905 default: break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001906 }
Chris Lattner24943d22010-06-08 16:52:24 +00001907
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001908 if (type == eSymbolTypeInvalid)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001909 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001910 const char *symbol_sect_name = symbol_section->GetName().AsCString();
1911 if (symbol_section->IsDescendant (text_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00001912 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001913 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
1914 SectionAttrUserSelfModifyingCode |
1915 SectionAttrSytemSomeInstructions))
1916 type = eSymbolTypeData;
1917 else
1918 type = eSymbolTypeCode;
Greg Clayton576a68b2010-09-08 16:38:06 +00001919 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001920 else
1921 if (symbol_section->IsDescendant(data_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00001922 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001923 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
Greg Clayton7c36fa02010-09-11 03:13:28 +00001924 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001925 type = eSymbolTypeRuntime;
Chris Lattner24943d22010-06-08 16:52:24 +00001926
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001927 if (symbol_name &&
1928 symbol_name[0] == '_' &&
1929 symbol_name[1] == 'O' &&
1930 symbol_name[2] == 'B')
Greg Clayton637029b2010-09-12 05:25:16 +00001931 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001932 llvm::StringRef symbol_name_ref(symbol_name);
1933 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
1934 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
1935 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
1936 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
Chris Lattner24943d22010-06-08 16:52:24 +00001937 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001938 symbol_name_non_abi_mangled = symbol_name + 1;
1939 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
1940 type = eSymbolTypeObjCClass;
Chris Lattner24943d22010-06-08 16:52:24 +00001941 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001942 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
Chris Lattner24943d22010-06-08 16:52:24 +00001943 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001944 symbol_name_non_abi_mangled = symbol_name + 1;
1945 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
1946 type = eSymbolTypeObjCMetaClass;
1947 }
1948 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
1949 {
1950 symbol_name_non_abi_mangled = symbol_name + 1;
1951 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
1952 type = eSymbolTypeObjCIVar;
Chris Lattner24943d22010-06-08 16:52:24 +00001953 }
1954 }
1955 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001956 else
1957 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
1958 {
1959 type = eSymbolTypeException;
1960 }
1961 else
1962 {
1963 type = eSymbolTypeData;
1964 }
1965 }
1966 else
1967 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
1968 {
1969 type = eSymbolTypeTrampoline;
1970 }
1971 else
1972 if (symbol_section->IsDescendant(objc_section_sp.get()))
1973 {
1974 type = eSymbolTypeRuntime;
1975 if (symbol_name && symbol_name[0] == '.')
1976 {
1977 llvm::StringRef symbol_name_ref(symbol_name);
1978 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
1979 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
1980 {
1981 symbol_name_non_abi_mangled = symbol_name;
1982 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
1983 type = eSymbolTypeObjCClass;
1984 }
1985 }
Chris Lattner24943d22010-06-08 16:52:24 +00001986 }
1987 }
1988 }
1989 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001990 break;
1991 }
1992 }
1993
1994 if (add_nlist)
1995 {
1996 uint64_t symbol_value = nlist.n_value;
1997 bool symbol_name_is_mangled = false;
1998
1999 if (symbol_name_non_abi_mangled)
2000 {
2001 sym[sym_idx].GetMangled().SetMangledName (symbol_name_non_abi_mangled);
2002 sym[sym_idx].GetMangled().SetDemangledName (symbol_name);
Chris Lattner24943d22010-06-08 16:52:24 +00002003 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002004 else
2005 {
2006 if (symbol_name && symbol_name[0] == '_')
2007 {
2008 symbol_name_is_mangled = symbol_name[1] == '_';
2009 symbol_name++; // Skip the leading underscore
2010 }
2011
2012 if (symbol_name)
2013 {
2014 sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
2015 }
2016 }
2017
2018 if (is_debug == false)
2019 {
2020 if (type == eSymbolTypeCode)
2021 {
2022 // See if we can find a N_FUN entry for any code symbols.
2023 // If we do find a match, and the name matches, then we
2024 // can merge the two into just the function symbol to avoid
2025 // duplicate entries in the symbol table
2026 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
2027 if (pos != N_FUN_addr_to_sym_idx.end())
2028 {
2029 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2030 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2031 {
2032 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2033 // We just need the flags from the linker symbol, so put these flags
2034 // into the N_FUN flags to avoid duplicate symbols in the symbol table
2035 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2036 sym[sym_idx].Clear();
2037 continue;
2038 }
2039 }
2040 }
2041 else if (type == eSymbolTypeData)
2042 {
2043 // See if we can find a N_STSYM entry for any data symbols.
2044 // If we do find a match, and the name matches, then we
2045 // can merge the two into just the Static symbol to avoid
2046 // duplicate entries in the symbol table
2047 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
2048 if (pos != N_STSYM_addr_to_sym_idx.end())
2049 {
2050 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2051 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2052 {
2053 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2054 // We just need the flags from the linker symbol, so put these flags
2055 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
2056 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2057 sym[sym_idx].Clear();
2058 continue;
2059 }
2060 }
2061 }
2062 }
2063 if (symbol_section)
2064 {
2065 const addr_t section_file_addr = symbol_section->GetFileAddress();
2066 if (symbol_byte_size == 0 && function_starts_count > 0)
2067 {
Greg Claytond2653c22012-03-14 01:53:24 +00002068 addr_t symbol_lookup_file_addr = nlist.n_value;
2069 // Do an exact address match for non-ARM addresses, else get the closest since
2070 // the symbol might be a thumb symbol which has an address with bit zero set
2071 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
2072 if (is_arm && func_start_entry)
2073 {
2074 // Verify that the function start address is the symbol address (ARM)
2075 // or the symbol address + 1 (thumb)
2076 if (func_start_entry->addr != symbol_lookup_file_addr &&
2077 func_start_entry->addr != (symbol_lookup_file_addr + 1))
2078 {
2079 // Not the right entry, NULL it out...
2080 func_start_entry = NULL;
2081 }
2082 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002083 if (func_start_entry)
2084 {
2085 func_start_entry->data = true;
Greg Claytond2653c22012-03-14 01:53:24 +00002086
2087 addr_t symbol_file_addr = func_start_entry->addr;
2088 uint32_t symbol_flags = 0;
2089 if (is_arm)
2090 {
2091 if (symbol_file_addr & 1)
2092 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
2093 symbol_file_addr &= 0xfffffffffffffffeull;
2094 }
2095
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002096 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2097 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2098 if (next_func_start_entry)
2099 {
Greg Claytond2653c22012-03-14 01:53:24 +00002100 addr_t next_symbol_file_addr = next_func_start_entry->addr;
2101 // Be sure the clear the Thumb address bit when we calculate the size
2102 // from the current and next address
2103 if (is_arm)
2104 next_symbol_file_addr &= 0xfffffffffffffffeull;
2105 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 +00002106 }
2107 else
2108 {
Greg Claytond2653c22012-03-14 01:53:24 +00002109 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002110 }
2111 }
2112 }
2113 symbol_value -= section_file_addr;
2114 }
2115
2116 sym[sym_idx].SetID (nlist_idx);
2117 sym[sym_idx].SetType (type);
2118 sym[sym_idx].GetAddress().SetSection (symbol_section);
2119 sym[sym_idx].GetAddress().SetOffset (symbol_value);
2120 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2121
2122 if (symbol_byte_size > 0)
2123 sym[sym_idx].SetByteSize(symbol_byte_size);
2124
2125 ++sym_idx;
2126 }
2127 else
2128 {
2129 sym[sym_idx].Clear();
2130 }
2131
2132 }
2133
2134 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
2135 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
2136 // such entries by figuring out what the address for the global is by looking up this non-STAB
2137 // entry and copying the value into the debug symbol's value to save us the hassle in the
2138 // debug symbol parser.
2139
2140 Symbol *global_symbol = NULL;
2141 for (nlist_idx = 0;
2142 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
2143 nlist_idx++)
2144 {
2145 if (global_symbol->GetAddress().GetFileAddress() == 0)
2146 {
2147 std::vector<uint32_t> indexes;
2148 if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
2149 {
2150 std::vector<uint32_t>::const_iterator pos;
2151 std::vector<uint32_t>::const_iterator end = indexes.end();
2152 for (pos = indexes.begin(); pos != end; ++pos)
2153 {
2154 symbol_ptr = symtab->SymbolAtIndex(*pos);
2155 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
2156 {
2157 global_symbol->GetAddress() = symbol_ptr->GetAddress();
2158 break;
2159 }
2160 }
2161 }
Chris Lattner24943d22010-06-08 16:52:24 +00002162 }
2163 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002164
2165 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
2166
2167
2168 if (function_starts_count > 0)
2169 {
2170 char synthetic_function_symbol[PATH_MAX];
2171 uint32_t num_synthetic_function_symbols = 0;
2172 for (i=0; i<function_starts_count; ++i)
2173 {
2174 if (function_starts.GetEntryRef (i).data == false)
2175 ++num_synthetic_function_symbols;
2176 }
2177
2178 if (num_synthetic_function_symbols > 0)
2179 {
2180 if (num_syms < sym_idx + num_synthetic_function_symbols)
2181 {
2182 num_syms = sym_idx + num_synthetic_function_symbols;
2183 sym = symtab->Resize (num_syms);
2184 }
2185 uint32_t synthetic_function_symbol_idx = 0;
2186 for (i=0; i<function_starts_count; ++i)
2187 {
2188 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
2189 if (func_start_entry->data == false)
2190 {
Greg Claytond2653c22012-03-14 01:53:24 +00002191 addr_t symbol_file_addr = func_start_entry->addr;
2192 uint32_t symbol_flags = 0;
2193 if (is_arm)
2194 {
2195 if (symbol_file_addr & 1)
2196 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
2197 symbol_file_addr &= 0xfffffffffffffffeull;
2198 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002199 Address symbol_addr;
Greg Claytond2653c22012-03-14 01:53:24 +00002200 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002201 {
2202 SectionSP symbol_section (symbol_addr.GetSection());
2203 uint32_t symbol_byte_size = 0;
2204 if (symbol_section)
2205 {
2206 const addr_t section_file_addr = symbol_section->GetFileAddress();
2207 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2208 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2209 if (next_func_start_entry)
2210 {
Greg Claytond2653c22012-03-14 01:53:24 +00002211 addr_t next_symbol_file_addr = next_func_start_entry->addr;
2212 if (is_arm)
2213 next_symbol_file_addr &= 0xfffffffffffffffeull;
2214 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 +00002215 }
2216 else
2217 {
Greg Claytond2653c22012-03-14 01:53:24 +00002218 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002219 }
2220 snprintf (synthetic_function_symbol,
2221 sizeof(synthetic_function_symbol),
2222 "___lldb_unnamed_function%u$$%s",
2223 ++synthetic_function_symbol_idx,
2224 module_sp->GetFileSpec().GetFilename().GetCString());
2225 sym[sym_idx].SetID (synthetic_sym_id++);
2226 sym[sym_idx].GetMangled().SetDemangledName(synthetic_function_symbol);
2227 sym[sym_idx].SetType (eSymbolTypeCode);
2228 sym[sym_idx].SetIsSynthetic (true);
2229 sym[sym_idx].GetAddress() = symbol_addr;
Greg Claytond2653c22012-03-14 01:53:24 +00002230 if (symbol_flags)
2231 sym[sym_idx].SetFlags (symbol_flags);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002232 if (symbol_byte_size)
2233 sym[sym_idx].SetByteSize (symbol_byte_size);
2234 ++sym_idx;
2235 }
2236 }
2237 }
2238 }
2239 }
2240 }
2241
2242 // Trim our symbols down to just what we ended up with after
2243 // removing any symbols.
2244 if (sym_idx < num_syms)
2245 {
2246 num_syms = sym_idx;
2247 sym = symtab->Resize (num_syms);
2248 }
2249
2250 // Now synthesize indirect symbols
2251 if (m_dysymtab.nindirectsyms != 0)
2252 {
2253 DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
2254
2255 if (indirect_symbol_index_data.GetByteSize())
2256 {
2257 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
2258
2259 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
2260 {
2261 if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
2262 {
2263 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
2264 if (symbol_stub_byte_size == 0)
2265 continue;
2266
2267 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
2268
2269 if (num_symbol_stubs == 0)
2270 continue;
2271
2272 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
2273 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
2274 {
2275 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
2276 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
2277 uint32_t symbol_stub_offset = symbol_stub_index * 4;
2278 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
2279 {
2280 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
2281 if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
2282 continue;
2283
2284 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
2285 Symbol *stub_symbol = NULL;
2286 if (index_pos != end_index_pos)
2287 {
2288 // We have a remapping from the original nlist index to
2289 // a current symbol index, so just look this up by index
2290 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
2291 }
2292 else
2293 {
2294 // We need to lookup a symbol using the original nlist
2295 // symbol index since this index is coming from the
2296 // S_SYMBOL_STUBS
2297 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
2298 }
2299
2300 assert (stub_symbol);
2301 if (stub_symbol)
2302 {
2303 Address so_addr(symbol_stub_addr, section_list);
2304
2305 if (stub_symbol->GetType() == eSymbolTypeUndefined)
2306 {
2307 // Change the external symbol into a trampoline that makes sense
2308 // These symbols were N_UNDF N_EXT, and are useless to us, so we
2309 // can re-use them so we don't have to make up a synthetic symbol
2310 // for no good reason.
2311 stub_symbol->SetType (eSymbolTypeTrampoline);
2312 stub_symbol->SetExternal (false);
2313 stub_symbol->GetAddress() = so_addr;
2314 stub_symbol->SetByteSize (symbol_stub_byte_size);
2315 }
2316 else
2317 {
2318 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda2a76fbf2012-04-24 02:09:58 +00002319 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002320 if (sym_idx >= num_syms)
Jason Molenda2a76fbf2012-04-24 02:09:58 +00002321 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002322 sym = symtab->Resize (++num_syms);
Jason Molenda2a76fbf2012-04-24 02:09:58 +00002323 stub_symbol = NULL; // this pointer no longer valid
2324 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002325 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda2a76fbf2012-04-24 02:09:58 +00002326 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002327 sym[sym_idx].SetType (eSymbolTypeTrampoline);
2328 sym[sym_idx].SetIsSynthetic (true);
2329 sym[sym_idx].GetAddress() = so_addr;
2330 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
2331 ++sym_idx;
2332 }
2333 }
2334 }
2335 }
2336 }
2337 }
2338 }
2339 }
2340 return symtab->GetNumSymbols();
Chris Lattner24943d22010-06-08 16:52:24 +00002341 }
2342 return 0;
2343}
2344
2345
2346void
2347ObjectFileMachO::Dump (Stream *s)
2348{
Greg Clayton9482f052012-03-13 23:14:29 +00002349 ModuleSP module_sp(GetModule());
2350 if (module_sp)
2351 {
2352 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2353 s->Printf("%p: ", this);
2354 s->Indent();
2355 if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped)
2356 s->PutCString("ObjectFileMachO64");
2357 else
2358 s->PutCString("ObjectFileMachO32");
Chris Lattner24943d22010-06-08 16:52:24 +00002359
Greg Clayton9482f052012-03-13 23:14:29 +00002360 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +00002361
Greg Clayton9482f052012-03-13 23:14:29 +00002362 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner24943d22010-06-08 16:52:24 +00002363
Greg Clayton9482f052012-03-13 23:14:29 +00002364 if (m_sections_ap.get())
2365 m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00002366
Greg Clayton9482f052012-03-13 23:14:29 +00002367 if (m_symtab_ap.get())
2368 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
2369 }
Chris Lattner24943d22010-06-08 16:52:24 +00002370}
2371
2372
2373bool
Greg Clayton0467c782011-02-04 18:53:10 +00002374ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner24943d22010-06-08 16:52:24 +00002375{
Greg Clayton9482f052012-03-13 23:14:29 +00002376 ModuleSP module_sp(GetModule());
2377 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00002378 {
Greg Clayton9482f052012-03-13 23:14:29 +00002379 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2380 struct uuid_command load_cmd;
2381 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2382 uint32_t i;
2383 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00002384 {
Greg Clayton9482f052012-03-13 23:14:29 +00002385 const uint32_t cmd_offset = offset;
2386 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2387 break;
2388
2389 if (load_cmd.cmd == LoadCommandUUID)
Chris Lattner24943d22010-06-08 16:52:24 +00002390 {
Greg Clayton9482f052012-03-13 23:14:29 +00002391 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
2392 if (uuid_bytes)
2393 {
2394 uuid->SetBytes (uuid_bytes);
2395 return true;
2396 }
2397 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00002398 }
Greg Clayton9482f052012-03-13 23:14:29 +00002399 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00002400 }
Chris Lattner24943d22010-06-08 16:52:24 +00002401 }
2402 return false;
2403}
2404
2405
2406uint32_t
2407ObjectFileMachO::GetDependentModules (FileSpecList& files)
2408{
Chris Lattner24943d22010-06-08 16:52:24 +00002409 uint32_t count = 0;
Greg Clayton9482f052012-03-13 23:14:29 +00002410 ModuleSP module_sp(GetModule());
2411 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00002412 {
Greg Clayton9482f052012-03-13 23:14:29 +00002413 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2414 struct load_command load_cmd;
2415 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2416 const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
2417 uint32_t i;
2418 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00002419 {
Greg Clayton9482f052012-03-13 23:14:29 +00002420 const uint32_t cmd_offset = offset;
2421 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2422 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002423
Greg Clayton9482f052012-03-13 23:14:29 +00002424 switch (load_cmd.cmd)
2425 {
2426 case LoadCommandDylibLoad:
2427 case LoadCommandDylibLoadWeak:
2428 case LoadCommandDylibReexport:
2429 case LoadCommandDynamicLinkerLoad:
2430 case LoadCommandFixedVMShlibLoad:
2431 case LoadCommandDylibLoadUpward:
2432 {
2433 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
2434 const char *path = m_data.PeekCStr(name_offset);
2435 // Skip any path that starts with '@' since these are usually:
2436 // @executable_path/.../file
2437 // @rpath/.../file
2438 if (path && path[0] != '@')
2439 {
2440 FileSpec file_spec(path, resolve_path);
2441 if (files.AppendIfUnique(file_spec))
2442 count++;
2443 }
2444 }
2445 break;
2446
2447 default:
2448 break;
2449 }
2450 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00002451 }
Chris Lattner24943d22010-06-08 16:52:24 +00002452 }
2453 return count;
2454}
2455
Jim Ingham28775942011-03-07 23:44:08 +00002456lldb_private::Address
2457ObjectFileMachO::GetEntryPointAddress ()
2458{
2459 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
2460 // is initialized to an invalid address, so we can just return that.
2461 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
2462
2463 if (!IsExecutable() || m_entry_point_address.IsValid())
2464 return m_entry_point_address;
2465
2466 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
2467 // /usr/include/mach-o.h, but it is basically:
2468 //
2469 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
2470 // uint32_t count - this is the count of longs in the thread state data
2471 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
2472 // <repeat this trio>
2473 //
2474 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
2475 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
2476 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
2477 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
2478 //
2479 // For now we hard-code the offsets and flavors we need:
2480 //
2481 //
2482
Greg Clayton9482f052012-03-13 23:14:29 +00002483 ModuleSP module_sp(GetModule());
2484 if (module_sp)
Jim Ingham28775942011-03-07 23:44:08 +00002485 {
Greg Clayton9482f052012-03-13 23:14:29 +00002486 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2487 struct load_command load_cmd;
2488 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2489 uint32_t i;
2490 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
2491 bool done = false;
2492
2493 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham28775942011-03-07 23:44:08 +00002494 {
Greg Clayton9482f052012-03-13 23:14:29 +00002495 const uint32_t cmd_offset = offset;
2496 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2497 break;
2498
2499 switch (load_cmd.cmd)
Jim Ingham28775942011-03-07 23:44:08 +00002500 {
Greg Clayton9482f052012-03-13 23:14:29 +00002501 case LoadCommandUnixThread:
2502 case LoadCommandThread:
Jim Ingham28775942011-03-07 23:44:08 +00002503 {
Greg Clayton9482f052012-03-13 23:14:29 +00002504 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham28775942011-03-07 23:44:08 +00002505 {
Greg Clayton9482f052012-03-13 23:14:29 +00002506 uint32_t flavor = m_data.GetU32(&offset);
2507 uint32_t count = m_data.GetU32(&offset);
2508 if (count == 0)
2509 {
2510 // We've gotten off somehow, log and exit;
2511 return m_entry_point_address;
Jim Ingham28775942011-03-07 23:44:08 +00002512 }
Greg Clayton9482f052012-03-13 23:14:29 +00002513
2514 switch (m_header.cputype)
2515 {
2516 case llvm::MachO::CPUTypeARM:
2517 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
2518 {
2519 offset += 60; // This is the offset of pc in the GPR thread state data structure.
2520 start_address = m_data.GetU32(&offset);
2521 done = true;
2522 }
Jim Ingham28775942011-03-07 23:44:08 +00002523 break;
Greg Clayton9482f052012-03-13 23:14:29 +00002524 case llvm::MachO::CPUTypeI386:
2525 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
2526 {
2527 offset += 40; // This is the offset of eip in the GPR thread state data structure.
2528 start_address = m_data.GetU32(&offset);
2529 done = true;
2530 }
2531 break;
2532 case llvm::MachO::CPUTypeX86_64:
2533 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
2534 {
2535 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
2536 start_address = m_data.GetU64(&offset);
2537 done = true;
2538 }
2539 break;
2540 default:
2541 return m_entry_point_address;
2542 }
2543 // Haven't found the GPR flavor yet, skip over the data for this flavor:
2544 if (done)
2545 break;
2546 offset += count * 4;
2547 }
Jim Ingham28775942011-03-07 23:44:08 +00002548 }
Greg Clayton9482f052012-03-13 23:14:29 +00002549 break;
2550 case LoadCommandMain:
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002551 {
Greg Clayton9482f052012-03-13 23:14:29 +00002552 ConstString text_segment_name ("__TEXT");
2553 uint64_t entryoffset = m_data.GetU64(&offset);
2554 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
2555 if (text_segment_sp)
2556 {
2557 done = true;
2558 start_address = text_segment_sp->GetFileAddress() + entryoffset;
2559 }
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002560 }
Greg Clayton9482f052012-03-13 23:14:29 +00002561
2562 default:
2563 break;
Sean Callanan6e12c7a2012-03-08 02:39:03 +00002564 }
Greg Clayton9482f052012-03-13 23:14:29 +00002565 if (done)
2566 break;
Jim Ingham28775942011-03-07 23:44:08 +00002567
Greg Clayton9482f052012-03-13 23:14:29 +00002568 // Go to the next load command:
2569 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham28775942011-03-07 23:44:08 +00002570 }
Jim Ingham28775942011-03-07 23:44:08 +00002571
Greg Clayton9482f052012-03-13 23:14:29 +00002572 if (start_address != LLDB_INVALID_ADDRESS)
Greg Clayton3508c382012-02-24 01:59:29 +00002573 {
Greg Clayton9482f052012-03-13 23:14:29 +00002574 // We got the start address from the load commands, so now resolve that address in the sections
2575 // of this ObjectFile:
2576 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Clayton3508c382012-02-24 01:59:29 +00002577 {
Greg Clayton9482f052012-03-13 23:14:29 +00002578 m_entry_point_address.Clear();
2579 }
2580 }
2581 else
2582 {
2583 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
2584 // "start" symbol in the main executable.
2585
2586 ModuleSP module_sp (GetModule());
2587
2588 if (module_sp)
2589 {
2590 SymbolContextList contexts;
2591 SymbolContext context;
2592 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
2593 {
2594 if (contexts.GetContextAtIndex(0, context))
2595 m_entry_point_address = context.symbol->GetAddress();
2596 }
Greg Clayton3508c382012-02-24 01:59:29 +00002597 }
2598 }
Jim Ingham28775942011-03-07 23:44:08 +00002599 }
2600
2601 return m_entry_point_address;
2602
2603}
2604
Greg Claytonb5a8f142012-02-05 02:38:54 +00002605lldb_private::Address
2606ObjectFileMachO::GetHeaderAddress ()
2607{
2608 lldb_private::Address header_addr;
2609 SectionList *section_list = GetSectionList();
2610 if (section_list)
2611 {
2612 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
2613 if (text_segment_sp)
2614 {
Greg Clayton3508c382012-02-24 01:59:29 +00002615 header_addr.SetSection (text_segment_sp);
Greg Claytonb5a8f142012-02-05 02:38:54 +00002616 header_addr.SetOffset (0);
2617 }
2618 }
2619 return header_addr;
2620}
2621
Greg Clayton46c9a352012-02-09 06:16:32 +00002622uint32_t
2623ObjectFileMachO::GetNumThreadContexts ()
2624{
Greg Clayton9482f052012-03-13 23:14:29 +00002625 ModuleSP module_sp(GetModule());
2626 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00002627 {
Greg Clayton9482f052012-03-13 23:14:29 +00002628 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2629 if (!m_thread_context_offsets_valid)
Greg Clayton46c9a352012-02-09 06:16:32 +00002630 {
Greg Clayton9482f052012-03-13 23:14:29 +00002631 m_thread_context_offsets_valid = true;
2632 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2633 FileRangeArray::Entry file_range;
2634 thread_command thread_cmd;
2635 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton46c9a352012-02-09 06:16:32 +00002636 {
Greg Clayton9482f052012-03-13 23:14:29 +00002637 const uint32_t cmd_offset = offset;
2638 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
2639 break;
2640
2641 if (thread_cmd.cmd == LoadCommandThread)
2642 {
2643 file_range.SetRangeBase (offset);
2644 file_range.SetByteSize (thread_cmd.cmdsize - 8);
2645 m_thread_context_offsets.Append (file_range);
2646 }
2647 offset = cmd_offset + thread_cmd.cmdsize;
Greg Clayton46c9a352012-02-09 06:16:32 +00002648 }
Greg Clayton46c9a352012-02-09 06:16:32 +00002649 }
2650 }
2651 return m_thread_context_offsets.GetSize();
2652}
2653
2654lldb::RegisterContextSP
2655ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
2656{
Greg Clayton46c9a352012-02-09 06:16:32 +00002657 lldb::RegisterContextSP reg_ctx_sp;
Greg Clayton9ce95382012-02-13 23:10:39 +00002658
Greg Clayton9482f052012-03-13 23:14:29 +00002659 ModuleSP module_sp(GetModule());
2660 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00002661 {
Greg Clayton9482f052012-03-13 23:14:29 +00002662 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2663 if (!m_thread_context_offsets_valid)
2664 GetNumThreadContexts ();
2665
2666 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
2667
2668 DataExtractor data (m_data,
2669 thread_context_file_range->GetRangeBase(),
2670 thread_context_file_range->GetByteSize());
2671
2672 switch (m_header.cputype)
2673 {
2674 case llvm::MachO::CPUTypeARM:
2675 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
2676 break;
2677
2678 case llvm::MachO::CPUTypeI386:
2679 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
2680 break;
2681
2682 case llvm::MachO::CPUTypeX86_64:
2683 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
2684 break;
2685 }
Greg Clayton46c9a352012-02-09 06:16:32 +00002686 }
2687 return reg_ctx_sp;
2688}
2689
Greg Claytonb5a8f142012-02-05 02:38:54 +00002690
Greg Claytonca319972011-07-09 00:41:34 +00002691ObjectFile::Type
2692ObjectFileMachO::CalculateType()
2693{
2694 switch (m_header.filetype)
2695 {
2696 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2697 if (GetAddressByteSize () == 4)
2698 {
2699 // 32 bit kexts are just object files, but they do have a valid
2700 // UUID load command.
2701 UUID uuid;
2702 if (GetUUID(&uuid))
2703 {
2704 // this checking for the UUID load command is not enough
2705 // we could eventually look for the symbol named
2706 // "OSKextGetCurrentIdentifier" as this is required of kexts
2707 if (m_strata == eStrataInvalid)
2708 m_strata = eStrataKernel;
2709 return eTypeSharedLibrary;
2710 }
2711 }
2712 return eTypeObjectFile;
2713
2714 case HeaderFileTypeExecutable: return eTypeExecutable; // 0x2u MH_EXECUTE
2715 case HeaderFileTypeFixedVMShlib: return eTypeSharedLibrary; // 0x3u MH_FVMLIB
2716 case HeaderFileTypeCore: return eTypeCoreFile; // 0x4u MH_CORE
2717 case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary; // 0x5u MH_PRELOAD
2718 case HeaderFileTypeDynamicShlib: return eTypeSharedLibrary; // 0x6u MH_DYLIB
2719 case HeaderFileTypeDynamicLinkEditor: return eTypeDynamicLinker; // 0x7u MH_DYLINKER
2720 case HeaderFileTypeBundle: return eTypeSharedLibrary; // 0x8u MH_BUNDLE
2721 case HeaderFileTypeDynamicShlibStub: return eTypeStubLibrary; // 0x9u MH_DYLIB_STUB
2722 case HeaderFileTypeDSYM: return eTypeDebugInfo; // 0xAu MH_DSYM
2723 case HeaderFileTypeKextBundle: return eTypeSharedLibrary; // 0xBu MH_KEXT_BUNDLE
2724 default:
2725 break;
2726 }
2727 return eTypeUnknown;
2728}
2729
2730ObjectFile::Strata
2731ObjectFileMachO::CalculateStrata()
2732{
2733 switch (m_header.filetype)
2734 {
2735 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2736 {
2737 // 32 bit kexts are just object files, but they do have a valid
2738 // UUID load command.
2739 UUID uuid;
2740 if (GetUUID(&uuid))
2741 {
2742 // this checking for the UUID load command is not enough
2743 // we could eventually look for the symbol named
2744 // "OSKextGetCurrentIdentifier" as this is required of kexts
2745 if (m_type == eTypeInvalid)
2746 m_type = eTypeSharedLibrary;
2747
2748 return eStrataKernel;
2749 }
2750 }
2751 return eStrataUnknown;
2752
2753 case HeaderFileTypeExecutable: // 0x2u MH_EXECUTE
2754 // Check for the MH_DYLDLINK bit in the flags
2755 if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
Sean Callananac725af2012-02-10 20:22:35 +00002756 {
Greg Claytonca319972011-07-09 00:41:34 +00002757 return eStrataUser;
Sean Callananac725af2012-02-10 20:22:35 +00002758 }
2759 else
2760 {
2761 SectionList *section_list = GetSectionList();
2762 if (section_list)
2763 {
2764 static ConstString g_kld_section_name ("__KLD");
2765 if (section_list->FindSectionByName(g_kld_section_name))
2766 return eStrataKernel;
2767 }
2768 }
2769 return eStrataRawImage;
Greg Claytonca319972011-07-09 00:41:34 +00002770
2771 case HeaderFileTypeFixedVMShlib: return eStrataUser; // 0x3u MH_FVMLIB
2772 case HeaderFileTypeCore: return eStrataUnknown; // 0x4u MH_CORE
Sean Callananac725af2012-02-10 20:22:35 +00002773 case HeaderFileTypePreloadedExecutable: return eStrataRawImage; // 0x5u MH_PRELOAD
Greg Claytonca319972011-07-09 00:41:34 +00002774 case HeaderFileTypeDynamicShlib: return eStrataUser; // 0x6u MH_DYLIB
2775 case HeaderFileTypeDynamicLinkEditor: return eStrataUser; // 0x7u MH_DYLINKER
2776 case HeaderFileTypeBundle: return eStrataUser; // 0x8u MH_BUNDLE
2777 case HeaderFileTypeDynamicShlibStub: return eStrataUser; // 0x9u MH_DYLIB_STUB
2778 case HeaderFileTypeDSYM: return eStrataUnknown; // 0xAu MH_DSYM
2779 case HeaderFileTypeKextBundle: return eStrataKernel; // 0xBu MH_KEXT_BUNDLE
2780 default:
2781 break;
2782 }
2783 return eStrataUnknown;
2784}
2785
2786
Greg Clayton49f4bf22012-02-22 19:41:02 +00002787uint32_t
2788ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
2789{
Greg Clayton9482f052012-03-13 23:14:29 +00002790 ModuleSP module_sp(GetModule());
2791 if (module_sp)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002792 {
Greg Clayton9482f052012-03-13 23:14:29 +00002793 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2794 struct dylib_command load_cmd;
2795 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2796 uint32_t version_cmd = 0;
2797 uint64_t version = 0;
2798 uint32_t i;
2799 for (i=0; i<m_header.ncmds; ++i)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002800 {
Greg Clayton9482f052012-03-13 23:14:29 +00002801 const uint32_t cmd_offset = offset;
2802 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
2803 break;
2804
2805 if (load_cmd.cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002806 {
Greg Clayton9482f052012-03-13 23:14:29 +00002807 if (version_cmd == 0)
2808 {
2809 version_cmd = load_cmd.cmd;
2810 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
2811 break;
2812 version = load_cmd.dylib.current_version;
2813 }
2814 break; // Break for now unless there is another more complete version
2815 // number load command in the future.
Greg Clayton49f4bf22012-02-22 19:41:02 +00002816 }
Greg Clayton9482f052012-03-13 23:14:29 +00002817 offset = cmd_offset + load_cmd.cmdsize;
Greg Clayton49f4bf22012-02-22 19:41:02 +00002818 }
Greg Clayton9482f052012-03-13 23:14:29 +00002819
2820 if (version_cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00002821 {
Greg Clayton9482f052012-03-13 23:14:29 +00002822 if (versions != NULL && num_versions > 0)
2823 {
2824 if (num_versions > 0)
2825 versions[0] = (version & 0xFFFF0000ull) >> 16;
2826 if (num_versions > 1)
2827 versions[1] = (version & 0x0000FF00ull) >> 8;
2828 if (num_versions > 2)
2829 versions[2] = (version & 0x000000FFull);
2830 // Fill in an remaining version numbers with invalid values
2831 for (i=3; i<num_versions; ++i)
2832 versions[i] = UINT32_MAX;
2833 }
2834 // The LC_ID_DYLIB load command has a version with 3 version numbers
2835 // in it, so always return 3
2836 return 3;
Greg Clayton49f4bf22012-02-22 19:41:02 +00002837 }
Greg Clayton49f4bf22012-02-22 19:41:02 +00002838 }
2839 return false;
2840}
2841
Chris Lattner24943d22010-06-08 16:52:24 +00002842bool
Greg Clayton395fc332011-02-15 21:59:32 +00002843ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +00002844{
Greg Clayton9482f052012-03-13 23:14:29 +00002845 ModuleSP module_sp(GetModule());
2846 if (module_sp)
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002847 {
Greg Clayton9482f052012-03-13 23:14:29 +00002848 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
2849 arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
2850
2851 // Files with type MH_PRELOAD are currently used in cases where the image
2852 // debugs at the addresses in the file itself. Below we set the OS to
2853 // unknown to make sure we use the DynamicLoaderStatic()...
2854 if (m_header.filetype == HeaderFileTypePreloadedExecutable)
2855 {
2856 arch.GetTriple().setOS (llvm::Triple::UnknownOS);
2857 }
2858 return true;
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002859 }
Greg Clayton9482f052012-03-13 23:14:29 +00002860 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00002861}
2862
2863
2864//------------------------------------------------------------------
2865// PluginInterface protocol
2866//------------------------------------------------------------------
2867const char *
2868ObjectFileMachO::GetPluginName()
2869{
2870 return "ObjectFileMachO";
2871}
2872
2873const char *
2874ObjectFileMachO::GetShortPluginName()
2875{
2876 return GetPluginNameStatic();
2877}
2878
2879uint32_t
2880ObjectFileMachO::GetPluginVersion()
2881{
2882 return 1;
2883}
2884