blob: 2027535a44d9d50be62a37ab5648bdc29acd37e6 [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
Greg Claytond4330e62012-09-05 01:38:55 +000015#include "lldb/lldb-private-log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Core/ArchSpec.h"
17#include "lldb/Core/DataBuffer.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Core/FileSpecList.h"
Greg Claytond4330e62012-09-05 01:38:55 +000019#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Core/Module.h"
21#include "lldb/Core/PluginManager.h"
Greg Clayton6f7f8da2012-04-24 03:06:13 +000022#include "lldb/Core/RangeMap.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Core/Section.h"
24#include "lldb/Core/StreamFile.h"
25#include "lldb/Core/StreamString.h"
26#include "lldb/Core/Timer.h"
27#include "lldb/Core/UUID.h"
Greg Claytondf6dc882012-01-05 03:57:59 +000028#include "lldb/Host/Host.h"
29#include "lldb/Host/FileSpec.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000030#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031#include "lldb/Symbol/ObjectFile.h"
Greg Clayton29021d32012-04-18 05:19:20 +000032#include "lldb/Target/Platform.h"
Greg Claytonb5a8f142012-02-05 02:38:54 +000033#include "lldb/Target/Process.h"
Greg Clayton29021d32012-04-18 05:19:20 +000034#include "lldb/Target/Target.h"
Greg Clayton9ce95382012-02-13 23:10:39 +000035#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
36#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
Greg Clayton46c9a352012-02-09 06:16:32 +000037#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038
Chris Lattner24943d22010-06-08 16:52:24 +000039using namespace lldb;
40using namespace lldb_private;
Greg Clayton1674b122010-07-21 22:12:05 +000041using namespace llvm::MachO;
Chris Lattner24943d22010-06-08 16:52:24 +000042
Greg Clayton46c9a352012-02-09 06:16:32 +000043class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
44{
45public:
46 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
47 RegisterContextDarwin_x86_64 (thread, 0)
48 {
49 SetRegisterDataFrom_LC_THREAD (data);
50 }
51
52 virtual void
53 InvalidateAllRegisters ()
54 {
55 // Do nothing... registers are always valid...
56 }
57
58 void
59 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
60 {
Greg Clayton46c9a352012-02-09 06:16:32 +000061 uint32_t offset = 0;
62 SetError (GPRRegSet, Read, -1);
63 SetError (FPURegSet, Read, -1);
64 SetError (EXCRegSet, Read, -1);
Greg Clayton9ce95382012-02-13 23:10:39 +000065 bool done = false;
66
67 while (!done)
Greg Clayton46c9a352012-02-09 06:16:32 +000068 {
Greg Clayton9ce95382012-02-13 23:10:39 +000069 int flavor = data.GetU32 (&offset);
70 if (flavor == 0)
71 done = true;
72 else
Greg Clayton46c9a352012-02-09 06:16:32 +000073 {
Greg Clayton9ce95382012-02-13 23:10:39 +000074 uint32_t i;
75 uint32_t count = data.GetU32 (&offset);
76 switch (flavor)
77 {
78 case GPRRegSet:
79 for (i=0; i<count; ++i)
80 (&gpr.rax)[i] = data.GetU64(&offset);
81 SetError (GPRRegSet, Read, 0);
82 done = true;
83
84 break;
85 case FPURegSet:
86 // TODO: fill in FPU regs....
87 //SetError (FPURegSet, Read, -1);
88 done = true;
89
90 break;
91 case EXCRegSet:
92 exc.trapno = data.GetU32(&offset);
93 exc.err = data.GetU32(&offset);
94 exc.faultvaddr = data.GetU64(&offset);
95 SetError (EXCRegSet, Read, 0);
96 done = true;
97 break;
98 case 7:
99 case 8:
100 case 9:
101 // fancy flavors that encapsulate of the the above
102 // falvors...
103 break;
104
105 default:
106 done = true;
107 break;
108 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000109 }
Greg Clayton9ce95382012-02-13 23:10:39 +0000110 }
111 }
112protected:
113 virtual int
114 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
115 {
116 return 0;
117 }
118
119 virtual int
120 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
121 {
122 return 0;
123 }
124
125 virtual int
126 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
127 {
128 return 0;
129 }
130
131 virtual int
132 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
133 {
134 return 0;
135 }
136
137 virtual int
138 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
139 {
140 return 0;
141 }
142
143 virtual int
144 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
145 {
146 return 0;
147 }
148};
Greg Clayton46c9a352012-02-09 06:16:32 +0000149
Greg Clayton9ce95382012-02-13 23:10:39 +0000150
151class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
152{
153public:
154 RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
155 RegisterContextDarwin_i386 (thread, 0)
156 {
157 SetRegisterDataFrom_LC_THREAD (data);
158 }
159
160 virtual void
161 InvalidateAllRegisters ()
162 {
163 // Do nothing... registers are always valid...
164 }
165
166 void
167 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
168 {
169 uint32_t offset = 0;
170 SetError (GPRRegSet, Read, -1);
171 SetError (FPURegSet, Read, -1);
172 SetError (EXCRegSet, Read, -1);
173 bool done = false;
174
175 while (!done)
176 {
177 int flavor = data.GetU32 (&offset);
178 if (flavor == 0)
179 done = true;
180 else
Greg Clayton46c9a352012-02-09 06:16:32 +0000181 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000182 uint32_t i;
183 uint32_t count = data.GetU32 (&offset);
184 switch (flavor)
185 {
186 case GPRRegSet:
187 for (i=0; i<count; ++i)
188 (&gpr.eax)[i] = data.GetU32(&offset);
189 SetError (GPRRegSet, Read, 0);
190 done = true;
191
192 break;
193 case FPURegSet:
194 // TODO: fill in FPU regs....
195 //SetError (FPURegSet, Read, -1);
196 done = true;
197
198 break;
199 case EXCRegSet:
200 exc.trapno = data.GetU32(&offset);
201 exc.err = data.GetU32(&offset);
202 exc.faultvaddr = data.GetU32(&offset);
203 SetError (EXCRegSet, Read, 0);
204 done = true;
205 break;
206 case 7:
207 case 8:
208 case 9:
209 // fancy flavors that encapsulate of the the above
210 // falvors...
211 break;
212
213 default:
214 done = true;
215 break;
216 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000217 }
218 }
219 }
220protected:
221 virtual int
222 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
223 {
224 return 0;
225 }
226
227 virtual int
228 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
229 {
230 return 0;
231 }
232
233 virtual int
234 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
235 {
236 return 0;
237 }
238
239 virtual int
240 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
241 {
242 return 0;
243 }
244
245 virtual int
246 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
247 {
248 return 0;
249 }
250
251 virtual int
252 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
253 {
254 return 0;
255 }
256};
257
Greg Clayton9ce95382012-02-13 23:10:39 +0000258class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
259{
260public:
261 RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
262 RegisterContextDarwin_arm (thread, 0)
263 {
264 SetRegisterDataFrom_LC_THREAD (data);
265 }
266
267 virtual void
268 InvalidateAllRegisters ()
269 {
270 // Do nothing... registers are always valid...
271 }
272
273 void
274 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
275 {
276 uint32_t offset = 0;
277 SetError (GPRRegSet, Read, -1);
278 SetError (FPURegSet, Read, -1);
279 SetError (EXCRegSet, Read, -1);
280 int flavor = data.GetU32 (&offset);
281 uint32_t count = data.GetU32 (&offset);
282 switch (flavor)
283 {
284 case GPRRegSet:
285 for (uint32_t i=0; i<count; ++i)
286 gpr.r[i] = data.GetU32(&offset);
287 SetError (GPRRegSet, Read, 0);
288 break;
289 case FPURegSet:
290 // TODO: fill in FPU regs....
291 //SetError (FPURegSet, Read, -1);
292 break;
293 case EXCRegSet:
294 exc.exception = data.GetU32(&offset);
295 exc.fsr = data.GetU32(&offset);
296 exc.far = data.GetU32(&offset);
297 SetError (EXCRegSet, Read, 0);
298 break;
299 }
300 }
301protected:
302 virtual int
303 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
304 {
305 return 0;
306 }
307
308 virtual int
309 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
310 {
311 return 0;
312 }
313
314 virtual int
315 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
316 {
317 return 0;
318 }
319
320 virtual int
321 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
322 {
323 return 0;
324 }
325
326 virtual int
327 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
328 {
329 return 0;
330 }
331
332 virtual int
333 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
334 {
335 return 0;
336 }
337};
338
Greg Claytonb1888f22011-03-19 01:12:21 +0000339#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner24943d22010-06-08 16:52:24 +0000340
341void
342ObjectFileMachO::Initialize()
343{
344 PluginManager::RegisterPlugin (GetPluginNameStatic(),
345 GetPluginDescriptionStatic(),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000346 CreateInstance,
347 CreateMemoryInstance);
Chris Lattner24943d22010-06-08 16:52:24 +0000348}
349
350void
351ObjectFileMachO::Terminate()
352{
353 PluginManager::UnregisterPlugin (CreateInstance);
354}
355
356
357const char *
358ObjectFileMachO::GetPluginNameStatic()
359{
360 return "object-file.mach-o";
361}
362
363const char *
364ObjectFileMachO::GetPluginDescriptionStatic()
365{
366 return "Mach-o object file reader (32 and 64 bit)";
367}
368
369
370ObjectFile *
Greg Clayton3508c382012-02-24 01:59:29 +0000371ObjectFileMachO::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 +0000372{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000373 if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length))
Chris Lattner24943d22010-06-08 16:52:24 +0000374 {
Greg Clayton3508c382012-02-24 01:59:29 +0000375 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, file, offset, length));
Chris Lattner24943d22010-06-08 16:52:24 +0000376 if (objfile_ap.get() && objfile_ap->ParseHeader())
377 return objfile_ap.release();
378 }
379 return NULL;
380}
381
Greg Claytonb5a8f142012-02-05 02:38:54 +0000382ObjectFile *
Greg Clayton3508c382012-02-24 01:59:29 +0000383ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000384 DataBufferSP& data_sp,
385 const ProcessSP &process_sp,
386 lldb::addr_t header_addr)
387{
388 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
389 {
Greg Clayton3508c382012-02-24 01:59:29 +0000390 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
Greg Claytonb5a8f142012-02-05 02:38:54 +0000391 if (objfile_ap.get() && objfile_ap->ParseHeader())
392 return objfile_ap.release();
393 }
394 return NULL;
395}
396
397
398const ConstString &
399ObjectFileMachO::GetSegmentNameTEXT()
400{
401 static ConstString g_segment_name_TEXT ("__TEXT");
402 return g_segment_name_TEXT;
403}
404
405const ConstString &
406ObjectFileMachO::GetSegmentNameDATA()
407{
408 static ConstString g_segment_name_DATA ("__DATA");
409 return g_segment_name_DATA;
410}
411
412const ConstString &
413ObjectFileMachO::GetSegmentNameOBJC()
414{
415 static ConstString g_segment_name_OBJC ("__OBJC");
416 return g_segment_name_OBJC;
417}
418
419const ConstString &
420ObjectFileMachO::GetSegmentNameLINKEDIT()
421{
422 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
423 return g_section_name_LINKEDIT;
424}
425
426const ConstString &
427ObjectFileMachO::GetSectionNameEHFrame()
428{
429 static ConstString g_section_name_eh_frame ("__eh_frame");
430 return g_section_name_eh_frame;
431}
432
433
Chris Lattner24943d22010-06-08 16:52:24 +0000434
435static uint32_t
436MachHeaderSizeFromMagic(uint32_t magic)
437{
438 switch (magic)
439 {
Greg Clayton1674b122010-07-21 22:12:05 +0000440 case HeaderMagic32:
441 case HeaderMagic32Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000442 return sizeof(struct mach_header);
443
Greg Clayton1674b122010-07-21 22:12:05 +0000444 case HeaderMagic64:
445 case HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000446 return sizeof(struct mach_header_64);
447 break;
448
449 default:
450 break;
451 }
452 return 0;
453}
454
455
456bool
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000457ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
458 lldb::addr_t data_offset,
459 lldb::addr_t data_length)
Chris Lattner24943d22010-06-08 16:52:24 +0000460{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000461 DataExtractor data;
462 data.SetData (data_sp, data_offset, data_length);
Chris Lattner24943d22010-06-08 16:52:24 +0000463 uint32_t offset = 0;
464 uint32_t magic = data.GetU32(&offset);
465 return MachHeaderSizeFromMagic(magic) != 0;
466}
467
468
Greg Clayton3508c382012-02-24 01:59:29 +0000469ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) :
470 ObjectFile(module_sp, file, offset, length, data_sp),
Chris Lattner24943d22010-06-08 16:52:24 +0000471 m_sections_ap(),
Jim Ingham28775942011-03-07 23:44:08 +0000472 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000473 m_mach_segments(),
474 m_mach_sections(),
475 m_entry_point_address(),
476 m_thread_context_offsets(),
477 m_thread_context_offsets_valid(false)
Chris Lattner24943d22010-06-08 16:52:24 +0000478{
Greg Claytonddff7cc2011-02-04 21:13:05 +0000479 ::memset (&m_header, 0, sizeof(m_header));
480 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner24943d22010-06-08 16:52:24 +0000481}
482
Greg Clayton3508c382012-02-24 01:59:29 +0000483ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
Greg Claytonb5a8f142012-02-05 02:38:54 +0000484 lldb::DataBufferSP& header_data_sp,
485 const lldb::ProcessSP &process_sp,
486 lldb::addr_t header_addr) :
Greg Clayton3508c382012-02-24 01:59:29 +0000487 ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000488 m_sections_ap(),
489 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000490 m_mach_segments(),
491 m_mach_sections(),
492 m_entry_point_address(),
493 m_thread_context_offsets(),
494 m_thread_context_offsets_valid(false)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000495{
496 ::memset (&m_header, 0, sizeof(m_header));
497 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
498}
Chris Lattner24943d22010-06-08 16:52:24 +0000499
500ObjectFileMachO::~ObjectFileMachO()
501{
502}
503
504
505bool
506ObjectFileMachO::ParseHeader ()
507{
Greg Clayton9482f052012-03-13 23:14:29 +0000508 ModuleSP module_sp(GetModule());
509 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000510 {
Greg Clayton9482f052012-03-13 23:14:29 +0000511 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
512 bool can_parse = false;
513 uint32_t offset = 0;
Greg Claytoncd548032011-02-01 01:31:41 +0000514 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Greg Clayton9482f052012-03-13 23:14:29 +0000515 // Leave magic in the original byte order
516 m_header.magic = m_data.GetU32(&offset);
517 switch (m_header.magic)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000518 {
Greg Clayton9482f052012-03-13 23:14:29 +0000519 case HeaderMagic32:
520 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
521 m_data.SetAddressByteSize(4);
522 can_parse = true;
523 break;
524
525 case HeaderMagic64:
526 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
527 m_data.SetAddressByteSize(8);
528 can_parse = true;
529 break;
530
531 case HeaderMagic32Swapped:
532 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
533 m_data.SetAddressByteSize(4);
534 can_parse = true;
535 break;
536
537 case HeaderMagic64Swapped:
538 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
539 m_data.SetAddressByteSize(8);
540 can_parse = true;
541 break;
542
543 default:
544 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +0000545 }
Greg Clayton9482f052012-03-13 23:14:29 +0000546
547 if (can_parse)
548 {
549 m_data.GetU32(&offset, &m_header.cputype, 6);
550
551 ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
552
553 if (SetModulesArchitecture (mach_arch))
554 {
555 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
556 if (m_data.GetByteSize() < header_and_lc_size)
557 {
558 DataBufferSP data_sp;
559 ProcessSP process_sp (m_process_wp.lock());
560 if (process_sp)
561 {
562 data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
563 }
564 else
565 {
566 // Read in all only the load command data from the file on disk
567 data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
568 if (data_sp->GetByteSize() != header_and_lc_size)
569 return false;
570 }
571 if (data_sp)
572 m_data.SetData (data_sp);
573 }
574 }
575 return true;
576 }
577 else
578 {
579 memset(&m_header, 0, sizeof(struct mach_header));
580 }
Chris Lattner24943d22010-06-08 16:52:24 +0000581 }
582 return false;
583}
584
585
586ByteOrder
587ObjectFileMachO::GetByteOrder () const
588{
Chris Lattner24943d22010-06-08 16:52:24 +0000589 return m_data.GetByteOrder ();
590}
591
Jim Ingham7508e732010-08-09 23:31:02 +0000592bool
593ObjectFileMachO::IsExecutable() const
594{
595 return m_header.filetype == HeaderFileTypeExecutable;
596}
Chris Lattner24943d22010-06-08 16:52:24 +0000597
598size_t
599ObjectFileMachO::GetAddressByteSize () const
600{
Chris Lattner24943d22010-06-08 16:52:24 +0000601 return m_data.GetAddressByteSize ();
602}
603
Greg Claytonb3448432011-03-24 21:19:54 +0000604AddressClass
Greg Claytonb1888f22011-03-19 01:12:21 +0000605ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
606{
607 Symtab *symtab = GetSymtab();
608 if (symtab)
609 {
610 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
611 if (symbol)
612 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000613 if (symbol->ValueIsAddress())
Greg Claytonb1888f22011-03-19 01:12:21 +0000614 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000615 SectionSP section_sp (symbol->GetAddress().GetSection());
Greg Clayton3508c382012-02-24 01:59:29 +0000616 if (section_sp)
Greg Claytonb1888f22011-03-19 01:12:21 +0000617 {
Greg Clayton3508c382012-02-24 01:59:29 +0000618 const SectionType section_type = section_sp->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000619 switch (section_type)
620 {
621 case eSectionTypeInvalid: return eAddressClassUnknown;
622 case eSectionTypeCode:
623 if (m_header.cputype == llvm::MachO::CPUTypeARM)
624 {
625 // For ARM we have a bit in the n_desc field of the symbol
626 // that tells us ARM/Thumb which is bit 0x0008.
627 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
628 return eAddressClassCodeAlternateISA;
629 }
630 return eAddressClassCode;
631
632 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000633 case eSectionTypeData:
634 case eSectionTypeDataCString:
635 case eSectionTypeDataCStringPointers:
636 case eSectionTypeDataSymbolAddress:
637 case eSectionTypeData4:
638 case eSectionTypeData8:
639 case eSectionTypeData16:
640 case eSectionTypeDataPointers:
641 case eSectionTypeZeroFill:
642 case eSectionTypeDataObjCMessageRefs:
643 case eSectionTypeDataObjCCFStrings:
644 return eAddressClassData;
645 case eSectionTypeDebug:
646 case eSectionTypeDWARFDebugAbbrev:
647 case eSectionTypeDWARFDebugAranges:
648 case eSectionTypeDWARFDebugFrame:
649 case eSectionTypeDWARFDebugInfo:
650 case eSectionTypeDWARFDebugLine:
651 case eSectionTypeDWARFDebugLoc:
652 case eSectionTypeDWARFDebugMacInfo:
653 case eSectionTypeDWARFDebugPubNames:
654 case eSectionTypeDWARFDebugPubTypes:
655 case eSectionTypeDWARFDebugRanges:
656 case eSectionTypeDWARFDebugStr:
657 case eSectionTypeDWARFAppleNames:
658 case eSectionTypeDWARFAppleTypes:
659 case eSectionTypeDWARFAppleNamespaces:
660 case eSectionTypeDWARFAppleObjC:
661 return eAddressClassDebug;
Greg Claytonb1888f22011-03-19 01:12:21 +0000662 case eSectionTypeEHFrame: return eAddressClassRuntime;
663 case eSectionTypeOther: return eAddressClassUnknown;
664 }
665 }
666 }
667
Greg Claytonb3448432011-03-24 21:19:54 +0000668 const SymbolType symbol_type = symbol->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000669 switch (symbol_type)
670 {
671 case eSymbolTypeAny: return eAddressClassUnknown;
672 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Greg Claytonb1888f22011-03-19 01:12:21 +0000673
674 case eSymbolTypeCode:
675 case eSymbolTypeTrampoline:
676 if (m_header.cputype == llvm::MachO::CPUTypeARM)
677 {
678 // For ARM we have a bit in the n_desc field of the symbol
679 // that tells us ARM/Thumb which is bit 0x0008.
680 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
681 return eAddressClassCodeAlternateISA;
682 }
683 return eAddressClassCode;
684
685 case eSymbolTypeData: return eAddressClassData;
686 case eSymbolTypeRuntime: return eAddressClassRuntime;
687 case eSymbolTypeException: return eAddressClassRuntime;
688 case eSymbolTypeSourceFile: return eAddressClassDebug;
689 case eSymbolTypeHeaderFile: return eAddressClassDebug;
690 case eSymbolTypeObjectFile: return eAddressClassDebug;
691 case eSymbolTypeCommonBlock: return eAddressClassDebug;
692 case eSymbolTypeBlock: return eAddressClassDebug;
693 case eSymbolTypeLocal: return eAddressClassData;
694 case eSymbolTypeParam: return eAddressClassData;
695 case eSymbolTypeVariable: return eAddressClassData;
696 case eSymbolTypeVariableType: return eAddressClassDebug;
697 case eSymbolTypeLineEntry: return eAddressClassDebug;
698 case eSymbolTypeLineHeader: return eAddressClassDebug;
699 case eSymbolTypeScopeBegin: return eAddressClassDebug;
700 case eSymbolTypeScopeEnd: return eAddressClassDebug;
701 case eSymbolTypeAdditional: return eAddressClassUnknown;
702 case eSymbolTypeCompiler: return eAddressClassDebug;
703 case eSymbolTypeInstrumentation:return eAddressClassDebug;
704 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton3f69eac2011-12-03 02:30:59 +0000705 case eSymbolTypeObjCClass: return eAddressClassRuntime;
706 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
707 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Claytonb1888f22011-03-19 01:12:21 +0000708 }
709 }
710 }
711 return eAddressClassUnknown;
712}
Chris Lattner24943d22010-06-08 16:52:24 +0000713
714Symtab *
715ObjectFileMachO::GetSymtab()
716{
Greg Clayton9482f052012-03-13 23:14:29 +0000717 ModuleSP module_sp(GetModule());
718 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000719 {
Greg Clayton9482f052012-03-13 23:14:29 +0000720 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
721 if (m_symtab_ap.get() == NULL)
722 {
723 m_symtab_ap.reset(new Symtab(this));
724 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
725 ParseSymtab (true);
726 m_symtab_ap->Finalize ();
727 }
Chris Lattner24943d22010-06-08 16:52:24 +0000728 }
729 return m_symtab_ap.get();
730}
731
732
733SectionList *
734ObjectFileMachO::GetSectionList()
735{
Greg Clayton9482f052012-03-13 23:14:29 +0000736 ModuleSP module_sp(GetModule());
737 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000738 {
Greg Clayton9482f052012-03-13 23:14:29 +0000739 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
740 if (m_sections_ap.get() == NULL)
741 {
742 m_sections_ap.reset(new SectionList());
743 ParseSections();
744 }
Chris Lattner24943d22010-06-08 16:52:24 +0000745 }
746 return m_sections_ap.get();
747}
748
749
750size_t
751ObjectFileMachO::ParseSections ()
752{
753 lldb::user_id_t segID = 0;
754 lldb::user_id_t sectID = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000755 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
756 uint32_t i;
Greg Clayton46c9a352012-02-09 06:16:32 +0000757 const bool is_core = GetType() == eTypeCoreFile;
Chris Lattner24943d22010-06-08 16:52:24 +0000758 //bool dump_sections = false;
Greg Clayton3508c382012-02-24 01:59:29 +0000759 ModuleSP module_sp (GetModule());
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000760 // First look up any LC_ENCRYPTION_INFO load commands
761 typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
762 EncryptedFileRanges encrypted_file_ranges;
Greg Clayton54e33712012-05-25 18:09:55 +0000763 encryption_info_command encryption_cmd;
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000764 for (i=0; i<m_header.ncmds; ++i)
765 {
766 const uint32_t load_cmd_offset = offset;
Greg Clayton54e33712012-05-25 18:09:55 +0000767 if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000768 break;
769
Greg Clayton54e33712012-05-25 18:09:55 +0000770 if (encryption_cmd.cmd == LoadCommandEncryptionInfo)
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000771 {
Greg Clayton54e33712012-05-25 18:09:55 +0000772 if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
773 {
774 if (encryption_cmd.cryptid != 0)
775 {
776 EncryptedFileRanges::Entry entry;
777 entry.SetRangeBase(encryption_cmd.cryptoff);
778 entry.SetByteSize(encryption_cmd.cryptsize);
779 encrypted_file_ranges.Append(entry);
780 }
781 }
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000782 }
Greg Clayton54e33712012-05-25 18:09:55 +0000783 offset = load_cmd_offset + encryption_cmd.cmdsize;
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000784 }
785
786 offset = MachHeaderSizeFromMagic(m_header.magic);
787
Greg Clayton54e33712012-05-25 18:09:55 +0000788 struct segment_command_64 load_cmd;
Chris Lattner24943d22010-06-08 16:52:24 +0000789 for (i=0; i<m_header.ncmds; ++i)
790 {
791 const uint32_t load_cmd_offset = offset;
792 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
793 break;
794
Greg Clayton1674b122010-07-21 22:12:05 +0000795 if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
Chris Lattner24943d22010-06-08 16:52:24 +0000796 {
797 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
798 {
799 load_cmd.vmaddr = m_data.GetAddress(&offset);
800 load_cmd.vmsize = m_data.GetAddress(&offset);
801 load_cmd.fileoff = m_data.GetAddress(&offset);
802 load_cmd.filesize = m_data.GetAddress(&offset);
803 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
804 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000805
806 const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
807
Chris Lattner24943d22010-06-08 16:52:24 +0000808 // Keep a list of mach segments around in case we need to
809 // get at data that isn't stored in the abstracted Sections.
810 m_mach_segments.push_back (load_cmd);
811
812 ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
813 // Use a segment ID of the segment index shifted left by 8 so they
814 // never conflict with any of the sections.
815 SectionSP segment_sp;
Greg Clayton46c9a352012-02-09 06:16:32 +0000816 if (segment_name || is_core)
Chris Lattner24943d22010-06-08 16:52:24 +0000817 {
Greg Clayton6f7f8da2012-04-24 03:06:13 +0000818 segment_sp.reset(new Section (module_sp, // Module to which this section belongs
Chris Lattner24943d22010-06-08 16:52:24 +0000819 ++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
820 segment_name, // Name of this section
821 eSectionTypeContainer, // This section is a container of other sections.
822 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
823 load_cmd.vmsize, // VM size in bytes of this section
824 load_cmd.fileoff, // Offset to the data for this section in the file
825 load_cmd.filesize, // Size in bytes of this section as found in the the file
826 load_cmd.flags)); // Flags for this section
827
Greg Clayton68ca8232011-01-25 02:58:48 +0000828 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000829 m_sections_ap->AddSection(segment_sp);
830 }
831
832 struct section_64 sect64;
Greg Claytonddff7cc2011-02-04 21:13:05 +0000833 ::memset (&sect64, 0, sizeof(sect64));
Chris Lattner24943d22010-06-08 16:52:24 +0000834 // Push a section into our mach sections for the section at
Greg Clayton6af4fad2010-10-06 01:26:32 +0000835 // index zero (NListSectionNoSection) if we don't have any
836 // mach sections yet...
837 if (m_mach_sections.empty())
838 m_mach_sections.push_back(sect64);
Chris Lattner24943d22010-06-08 16:52:24 +0000839 uint32_t segment_sect_idx;
840 const lldb::user_id_t first_segment_sectID = sectID + 1;
841
842
Greg Clayton1674b122010-07-21 22:12:05 +0000843 const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
Chris Lattner24943d22010-06-08 16:52:24 +0000844 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
845 {
846 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
847 break;
848 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
849 break;
850 sect64.addr = m_data.GetAddress(&offset);
851 sect64.size = m_data.GetAddress(&offset);
852
853 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
854 break;
855
856 // Keep a list of mach sections around in case we need to
857 // get at data that isn't stored in the abstracted Sections.
858 m_mach_sections.push_back (sect64);
859
860 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
861 if (!segment_name)
862 {
863 // We have a segment with no name so we need to conjure up
864 // segments that correspond to the section's segname if there
865 // isn't already such a section. If there is such a section,
866 // we resize the section so that it spans all sections.
867 // We also mark these sections as fake so address matches don't
868 // hit if they land in the gaps between the child sections.
869 segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
870 segment_sp = m_sections_ap->FindSectionByName (segment_name);
871 if (segment_sp.get())
872 {
873 Section *segment = segment_sp.get();
874 // Grow the section size as needed.
875 const lldb::addr_t sect64_min_addr = sect64.addr;
876 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
877 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
878 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
879 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
880 if (sect64_min_addr >= curr_seg_min_addr)
881 {
882 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
883 // Only grow the section size if needed
884 if (new_seg_byte_size > curr_seg_byte_size)
885 segment->SetByteSize (new_seg_byte_size);
886 }
887 else
888 {
889 // We need to change the base address of the segment and
890 // adjust the child section offsets for all existing children.
891 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
892 segment->Slide(slide_amount, false);
Sean Callanan716a6642012-06-08 02:16:08 +0000893 segment->GetChildren().Slide(-slide_amount, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000894 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
895 }
Greg Clayton661825b2010-06-28 23:51:11 +0000896
897 // Grow the section size as needed.
898 if (sect64.offset)
899 {
900 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
901 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
902
903 const lldb::addr_t section_min_file_offset = sect64.offset;
904 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
905 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
906 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
907 segment->SetFileOffset (new_file_offset);
908 segment->SetFileSize (new_file_size);
909 }
Chris Lattner24943d22010-06-08 16:52:24 +0000910 }
911 else
912 {
913 // Create a fake section for the section's named segment
Greg Clayton3508c382012-02-24 01:59:29 +0000914 segment_sp.reset(new Section (segment_sp, // Parent section
915 module_sp, // Module to which this section belongs
916 ++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
917 segment_name, // Name of this section
918 eSectionTypeContainer, // This section is a container of other sections.
919 sect64.addr, // File VM address == addresses as they are found in the object file
920 sect64.size, // VM size in bytes of this section
921 sect64.offset, // Offset to the data for this section in the file
922 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
923 load_cmd.flags)); // Flags for this section
Chris Lattner24943d22010-06-08 16:52:24 +0000924 segment_sp->SetIsFake(true);
925 m_sections_ap->AddSection(segment_sp);
Greg Clayton68ca8232011-01-25 02:58:48 +0000926 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000927 }
928 }
929 assert (segment_sp.get());
930
Greg Clayton1674b122010-07-21 22:12:05 +0000931 uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
Chris Lattner24943d22010-06-08 16:52:24 +0000932 static ConstString g_sect_name_objc_data ("__objc_data");
933 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
934 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
935 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
936 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
937 static ConstString g_sect_name_objc_const ("__objc_const");
938 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
939 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000940
941 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
942 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
943 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
944 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
945 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
946 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
947 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
948 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
949 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
950 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
951 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
Greg Claytonf6e3de22011-09-28 17:06:40 +0000952 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
953 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
Greg Clayton00db2152011-10-04 22:41:51 +0000954 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
Greg Clayton24a6bd92011-10-27 17:55:14 +0000955 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000956 static ConstString g_sect_name_eh_frame ("__eh_frame");
Greg Clayton3fed8b92010-10-08 00:21:05 +0000957 static ConstString g_sect_name_DATA ("__DATA");
958 static ConstString g_sect_name_TEXT ("__TEXT");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000959
Chris Lattner24943d22010-06-08 16:52:24 +0000960 SectionType sect_type = eSectionTypeOther;
961
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000962 if (section_name == g_sect_name_dwarf_debug_abbrev)
963 sect_type = eSectionTypeDWARFDebugAbbrev;
964 else if (section_name == g_sect_name_dwarf_debug_aranges)
965 sect_type = eSectionTypeDWARFDebugAranges;
966 else if (section_name == g_sect_name_dwarf_debug_frame)
967 sect_type = eSectionTypeDWARFDebugFrame;
968 else if (section_name == g_sect_name_dwarf_debug_info)
969 sect_type = eSectionTypeDWARFDebugInfo;
970 else if (section_name == g_sect_name_dwarf_debug_line)
971 sect_type = eSectionTypeDWARFDebugLine;
972 else if (section_name == g_sect_name_dwarf_debug_loc)
973 sect_type = eSectionTypeDWARFDebugLoc;
974 else if (section_name == g_sect_name_dwarf_debug_macinfo)
975 sect_type = eSectionTypeDWARFDebugMacInfo;
976 else if (section_name == g_sect_name_dwarf_debug_pubnames)
977 sect_type = eSectionTypeDWARFDebugPubNames;
978 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
979 sect_type = eSectionTypeDWARFDebugPubTypes;
980 else if (section_name == g_sect_name_dwarf_debug_ranges)
981 sect_type = eSectionTypeDWARFDebugRanges;
982 else if (section_name == g_sect_name_dwarf_debug_str)
983 sect_type = eSectionTypeDWARFDebugStr;
Greg Claytonf6e3de22011-09-28 17:06:40 +0000984 else if (section_name == g_sect_name_dwarf_apple_names)
985 sect_type = eSectionTypeDWARFAppleNames;
986 else if (section_name == g_sect_name_dwarf_apple_types)
987 sect_type = eSectionTypeDWARFAppleTypes;
Greg Clayton00db2152011-10-04 22:41:51 +0000988 else if (section_name == g_sect_name_dwarf_apple_namespaces)
989 sect_type = eSectionTypeDWARFAppleNamespaces;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000990 else if (section_name == g_sect_name_dwarf_apple_objc)
991 sect_type = eSectionTypeDWARFAppleObjC;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000992 else if (section_name == g_sect_name_objc_selrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000993 sect_type = eSectionTypeDataCStringPointers;
Chris Lattner24943d22010-06-08 16:52:24 +0000994 else if (section_name == g_sect_name_objc_msgrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000995 sect_type = eSectionTypeDataObjCMessageRefs;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000996 else if (section_name == g_sect_name_eh_frame)
997 sect_type = eSectionTypeEHFrame;
998 else if (section_name == g_sect_name_cfstring)
999 sect_type = eSectionTypeDataObjCCFStrings;
Chris Lattner24943d22010-06-08 16:52:24 +00001000 else if (section_name == g_sect_name_objc_data ||
1001 section_name == g_sect_name_objc_classrefs ||
1002 section_name == g_sect_name_objc_superrefs ||
1003 section_name == g_sect_name_objc_const ||
1004 section_name == g_sect_name_objc_classlist)
1005 {
1006 sect_type = eSectionTypeDataPointers;
1007 }
Chris Lattner24943d22010-06-08 16:52:24 +00001008
1009 if (sect_type == eSectionTypeOther)
1010 {
1011 switch (mach_sect_type)
1012 {
1013 // TODO: categorize sections by other flags for regular sections
Greg Clayton3fed8b92010-10-08 00:21:05 +00001014 case SectionTypeRegular:
1015 if (segment_sp->GetName() == g_sect_name_TEXT)
1016 sect_type = eSectionTypeCode;
1017 else if (segment_sp->GetName() == g_sect_name_DATA)
1018 sect_type = eSectionTypeData;
1019 else
1020 sect_type = eSectionTypeOther;
1021 break;
Greg Clayton1674b122010-07-21 22:12:05 +00001022 case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
1023 case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
1024 case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
1025 case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
1026 case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
1027 case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
1028 case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
1029 case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1030 case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
1031 case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
1032 case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
1033 case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
1034 case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
1035 case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
1036 case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
1037 case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
Chris Lattner24943d22010-06-08 16:52:24 +00001038 default: break;
1039 }
1040 }
1041
Greg Clayton3508c382012-02-24 01:59:29 +00001042 SectionSP section_sp(new Section (segment_sp,
1043 module_sp,
1044 ++sectID,
1045 section_name,
1046 sect_type,
1047 sect64.addr - segment_sp->GetFileAddress(),
1048 sect64.size,
1049 sect64.offset,
1050 sect64.offset == 0 ? 0 : sect64.size,
1051 sect64.flags));
Greg Clayton68ca8232011-01-25 02:58:48 +00001052 // Set the section to be encrypted to match the segment
Greg Clayton6f7f8da2012-04-24 03:06:13 +00001053
1054 bool section_is_encrypted = false;
1055 if (!segment_is_encrypted && load_cmd.filesize != 0)
1056 section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
Greg Clayton68ca8232011-01-25 02:58:48 +00001057
Greg Clayton6f7f8da2012-04-24 03:06:13 +00001058 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +00001059 segment_sp->GetChildren().AddSection(section_sp);
1060
1061 if (segment_sp->IsFake())
1062 {
1063 segment_sp.reset();
1064 segment_name.Clear();
1065 }
1066 }
Greg Clayton0fa51242011-07-19 03:57:15 +00001067 if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
Chris Lattner24943d22010-06-08 16:52:24 +00001068 {
1069 if (first_segment_sectID <= sectID)
1070 {
1071 lldb::user_id_t sect_uid;
1072 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
1073 {
1074 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
1075 SectionSP next_section_sp;
1076 if (sect_uid + 1 <= sectID)
1077 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
1078
1079 if (curr_section_sp.get())
1080 {
1081 if (curr_section_sp->GetByteSize() == 0)
1082 {
1083 if (next_section_sp.get() != NULL)
1084 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
1085 else
1086 curr_section_sp->SetByteSize ( load_cmd.vmsize );
1087 }
1088 }
1089 }
1090 }
1091 }
1092 }
1093 }
1094 }
Greg Clayton1674b122010-07-21 22:12:05 +00001095 else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
Chris Lattner24943d22010-06-08 16:52:24 +00001096 {
1097 m_dysymtab.cmd = load_cmd.cmd;
1098 m_dysymtab.cmdsize = load_cmd.cmdsize;
1099 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
1100 }
1101
1102 offset = load_cmd_offset + load_cmd.cmdsize;
1103 }
1104// if (dump_sections)
1105// {
1106// StreamFile s(stdout);
1107// m_sections_ap->Dump(&s, true);
1108// }
1109 return sectID; // Return the number of sections we registered with the module
1110}
1111
1112class MachSymtabSectionInfo
1113{
1114public:
1115
1116 MachSymtabSectionInfo (SectionList *section_list) :
1117 m_section_list (section_list),
1118 m_section_infos()
1119 {
1120 // Get the number of sections down to a depth of 1 to include
1121 // all segments and their sections, but no other sections that
1122 // may be added for debug map or
1123 m_section_infos.resize(section_list->GetNumSections(1));
1124 }
1125
1126
Greg Clayton3508c382012-02-24 01:59:29 +00001127 SectionSP
Chris Lattner24943d22010-06-08 16:52:24 +00001128 GetSection (uint8_t n_sect, addr_t file_addr)
1129 {
1130 if (n_sect == 0)
Greg Clayton3508c382012-02-24 01:59:29 +00001131 return SectionSP();
Chris Lattner24943d22010-06-08 16:52:24 +00001132 if (n_sect < m_section_infos.size())
1133 {
Greg Clayton3508c382012-02-24 01:59:29 +00001134 if (!m_section_infos[n_sect].section_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00001135 {
Greg Clayton3508c382012-02-24 01:59:29 +00001136 SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
1137 m_section_infos[n_sect].section_sp = section_sp;
Sean Callananb386d822012-08-09 00:50:26 +00001138 if (section_sp)
Greg Clayton5638d2c2011-07-10 17:32:33 +00001139 {
Greg Clayton3508c382012-02-24 01:59:29 +00001140 m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
1141 m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
Greg Clayton5638d2c2011-07-10 17:32:33 +00001142 }
1143 else
1144 {
Greg Claytondf6dc882012-01-05 03:57:59 +00001145 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Clayton5638d2c2011-07-10 17:32:33 +00001146 }
Chris Lattner24943d22010-06-08 16:52:24 +00001147 }
1148 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton811b9c52011-08-26 20:01:35 +00001149 {
1150 // Symbol is in section.
Greg Clayton3508c382012-02-24 01:59:29 +00001151 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001152 }
1153 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
1154 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
1155 {
1156 // Symbol is in section with zero size, but has the same start
1157 // address as the section. This can happen with linker symbols
1158 // (symbols that start with the letter 'l' or 'L'.
Greg Clayton3508c382012-02-24 01:59:29 +00001159 return m_section_infos[n_sect].section_sp;
Greg Clayton811b9c52011-08-26 20:01:35 +00001160 }
Chris Lattner24943d22010-06-08 16:52:24 +00001161 }
Greg Clayton3508c382012-02-24 01:59:29 +00001162 return m_section_list->FindSectionContainingFileAddress(file_addr);
Chris Lattner24943d22010-06-08 16:52:24 +00001163 }
1164
1165protected:
1166 struct SectionInfo
1167 {
1168 SectionInfo () :
1169 vm_range(),
Greg Clayton3508c382012-02-24 01:59:29 +00001170 section_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +00001171 {
1172 }
1173
1174 VMRange vm_range;
Greg Clayton3508c382012-02-24 01:59:29 +00001175 SectionSP section_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00001176 };
1177 SectionList *m_section_list;
1178 std::vector<SectionInfo> m_section_infos;
1179};
1180
Chris Lattner24943d22010-06-08 16:52:24 +00001181size_t
1182ObjectFileMachO::ParseSymtab (bool minimize)
1183{
1184 Timer scoped_timer(__PRETTY_FUNCTION__,
1185 "ObjectFileMachO::ParseSymtab () module = %s",
1186 m_file.GetFilename().AsCString(""));
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001187 ModuleSP module_sp (GetModule());
1188 if (!module_sp)
1189 return 0;
1190
1191 struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
1192 struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
1193 typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
1194 FunctionStarts function_starts;
Chris Lattner24943d22010-06-08 16:52:24 +00001195 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1196 uint32_t i;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001197
Greg Clayton0fea0512011-12-30 00:32:24 +00001198 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
1199
Chris Lattner24943d22010-06-08 16:52:24 +00001200 for (i=0; i<m_header.ncmds; ++i)
1201 {
1202 const uint32_t cmd_offset = offset;
1203 // Read in the load command and load command size
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001204 struct load_command lc;
1205 if (m_data.GetU32(&offset, &lc, 2) == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001206 break;
1207 // Watch for the symbol table load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001208 switch (lc.cmd)
Chris Lattner24943d22010-06-08 16:52:24 +00001209 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001210 case LoadCommandSymtab:
1211 symtab_load_command.cmd = lc.cmd;
1212 symtab_load_command.cmdsize = lc.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00001213 // Read in the rest of the symtab load command
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001214 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
1215 return 0;
1216 if (symtab_load_command.symoff == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001217 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001218 if (log)
1219 module_sp->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
1220 return 0;
1221 }
1222
1223 if (symtab_load_command.stroff == 0)
1224 {
1225 if (log)
1226 module_sp->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
1227 return 0;
1228 }
1229
1230 if (symtab_load_command.nsyms == 0)
1231 {
1232 if (log)
1233 module_sp->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
1234 return 0;
1235 }
1236
1237 if (symtab_load_command.strsize == 0)
1238 {
1239 if (log)
1240 module_sp->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
1241 return 0;
1242 }
1243 break;
1244
1245 case LoadCommandFunctionStarts:
1246 function_starts_load_command.cmd = lc.cmd;
1247 function_starts_load_command.cmdsize = lc.cmdsize;
1248 if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
1249 bzero (&function_starts_load_command, sizeof(function_starts_load_command));
1250 break;
1251
1252 default:
1253 break;
1254 }
1255 offset = cmd_offset + lc.cmdsize;
1256 }
1257
1258 if (symtab_load_command.cmd)
1259 {
1260 Symtab *symtab = m_symtab_ap.get();
1261 SectionList *section_list = GetSectionList();
1262 if (section_list == NULL)
1263 return 0;
1264
1265 ProcessSP process_sp (m_process_wp.lock());
Greg Claytondd29b972012-05-18 23:20:01 +00001266 Process *process = process_sp.get();
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001267
1268 const size_t addr_byte_size = m_data.GetAddressByteSize();
1269 bool bit_width_32 = addr_byte_size == 4;
1270 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
1271
1272 DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1273 DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1274 DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1275
1276 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
1277 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
Greg Claytondd29b972012-05-18 23:20:01 +00001278 addr_t strtab_addr = LLDB_INVALID_ADDRESS;
1279 if (process)
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001280 {
Greg Claytondd29b972012-05-18 23:20:01 +00001281 Target &target = process->GetTarget();
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001282 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
1283 // Reading mach file from memory in a process or core file...
1284
1285 if (linkedit_section_sp)
1286 {
1287 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
1288 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
1289 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
Greg Claytondd29b972012-05-18 23:20:01 +00001290 strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
Greg Clayton29021d32012-04-18 05:19:20 +00001291
1292 bool data_was_read = false;
1293
1294#if defined (__APPLE__) && defined (__arm__)
1295 if (m_header.flags & 0x80000000u)
Greg Clayton0fea0512011-12-30 00:32:24 +00001296 {
Greg Clayton29021d32012-04-18 05:19:20 +00001297 // This mach-o memory file is in the dyld shared cache. If this
1298 // program is not remote and this is iOS, then this process will
1299 // share the same shared cache as the process we are debugging and
1300 // we can read the entire __LINKEDIT from the address space in this
1301 // process. This is a needed optimization that is used for local iOS
1302 // debugging only since all shared libraries in the shared cache do
1303 // not have corresponding files that exist in the file system of the
1304 // device. They have been combined into a single file. This means we
1305 // always have to load these files from memory. All of the symbol and
1306 // string tables from all of the __LINKEDIT sections from the shared
1307 // libraries in the shared cache have been merged into a single large
1308 // symbol and string table. Reading all of this symbol and string table
1309 // data across can slow down debug launch times, so we optimize this by
1310 // reading the memory for the __LINKEDIT section from this process.
1311 PlatformSP platform_sp (target.GetPlatform());
1312 if (platform_sp && platform_sp->IsHost())
1313 {
1314 data_was_read = true;
1315 nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
Greg Claytondd29b972012-05-18 23:20:01 +00001316 strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
Greg Clayton29021d32012-04-18 05:19:20 +00001317 if (function_starts_load_command.cmd)
1318 {
1319 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1320 function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
1321 }
1322 }
1323 }
1324#endif
1325
1326 if (!data_was_read)
1327 {
1328 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
1329 if (nlist_data_sp)
1330 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
Greg Claytondd29b972012-05-18 23:20:01 +00001331 //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
1332 //if (strtab_data_sp)
1333 // strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
Greg Clayton29021d32012-04-18 05:19:20 +00001334 if (function_starts_load_command.cmd)
1335 {
1336 const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
1337 DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
1338 if (func_start_data_sp)
1339 function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
1340 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001341 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001342 }
1343 }
1344 else
1345 {
1346 nlist_data.SetData (m_data,
1347 symtab_load_command.symoff,
1348 nlist_data_byte_size);
1349 strtab_data.SetData (m_data,
1350 symtab_load_command.stroff,
1351 strtab_data_byte_size);
1352 if (function_starts_load_command.cmd)
1353 {
1354 function_starts_data.SetData (m_data,
1355 function_starts_load_command.dataoff,
1356 function_starts_load_command.datasize);
1357 }
1358 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001359
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001360 if (nlist_data.GetByteSize() == 0)
1361 {
1362 if (log)
1363 module_sp->LogMessage(log.get(), "failed to read nlist data");
1364 return 0;
1365 }
1366
1367
Greg Clayton3a5dc012012-05-25 17:04:00 +00001368 const bool have_strtab_data = strtab_data.GetByteSize() > 0;
1369 if (!have_strtab_data)
Greg Claytondd29b972012-05-18 23:20:01 +00001370 {
Greg Clayton3a5dc012012-05-25 17:04:00 +00001371 if (process)
1372 {
1373 if (strtab_addr == LLDB_INVALID_ADDRESS)
1374 {
1375 if (log)
1376 module_sp->LogMessage(log.get(), "failed to locate the strtab in memory");
1377 return 0;
1378 }
1379 }
1380 else
Greg Claytondd29b972012-05-18 23:20:01 +00001381 {
1382 if (log)
Greg Clayton3a5dc012012-05-25 17:04:00 +00001383 module_sp->LogMessage(log.get(), "failed to read strtab data");
Greg Claytondd29b972012-05-18 23:20:01 +00001384 return 0;
1385 }
1386 }
Greg Claytondd29b972012-05-18 23:20:01 +00001387
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001388 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
1389 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
1390 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
1391 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
1392 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
1393 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
1394 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
1395 SectionSP eh_frame_section_sp;
1396 if (text_section_sp.get())
1397 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
1398 else
1399 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
1400
Greg Claytond2653c22012-03-14 01:53:24 +00001401 const bool is_arm = (m_header.cputype == llvm::MachO::CPUTypeARM);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001402 if (text_section_sp && function_starts_data.GetByteSize())
1403 {
1404 FunctionStarts::Entry function_start_entry;
1405 function_start_entry.data = false;
1406 uint32_t function_start_offset = 0;
1407 function_start_entry.addr = text_section_sp->GetFileAddress();
1408 uint64_t delta;
1409 while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
1410 {
1411 // Now append the current entry
1412 function_start_entry.addr += delta;
1413 function_starts.Append(function_start_entry);
1414 }
1415 }
1416
1417 const uint32_t function_starts_count = function_starts.GetSize();
1418
1419 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
1420
1421 uint32_t nlist_data_offset = 0;
1422
1423 uint32_t N_SO_index = UINT32_MAX;
1424
1425 MachSymtabSectionInfo section_info (section_list);
1426 std::vector<uint32_t> N_FUN_indexes;
1427 std::vector<uint32_t> N_NSYM_indexes;
1428 std::vector<uint32_t> N_INCL_indexes;
1429 std::vector<uint32_t> N_BRAC_indexes;
1430 std::vector<uint32_t> N_COMM_indexes;
1431 typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
1432 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
1433 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
1434 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
1435 // Any symbols that get merged into another will get an entry
1436 // in this map so we know
1437 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
1438 uint32_t nlist_idx = 0;
1439 Symbol *symbol_ptr = NULL;
1440
1441 uint32_t sym_idx = 0;
Jason Molendab62abd52012-06-21 01:51:02 +00001442 Symbol *sym = NULL;
1443 uint32_t num_syms = 0;
Greg Claytondd29b972012-05-18 23:20:01 +00001444 std::string memory_symbol_name;
Jason Molendab62abd52012-06-21 01:51:02 +00001445 uint32_t unmapped_local_symbols_found = 0;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00001446
Jason Molendab62abd52012-06-21 01:51:02 +00001447#if defined (__APPLE__) && defined (__arm__)
1448
1449 // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
1450 // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
1451 // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
1452 // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
1453 // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
1454 // nlist parser to ignore all LOCAL symbols.
1455
1456 if (m_header.flags & 0x80000000u)
1457 {
1458 // Before we can start mapping the DSC, we need to make certain the target process is actually
1459 // using the cache we can find.
1460
1461 /*
1462 * TODO (FIXME!)
1463 *
1464 * Consider the case of testing with a separate DSC file.
1465 * If we go through the normal code paths, we will give symbols for the wrong DSC, and
1466 * that is bad. We need to read the target process' all_image_infos struct, and look
1467 * at the values of the processDetachedFromSharedRegion field. If that is set, we should skip
1468 * this code section.
1469 */
1470
1471 // Next we need to determine the correct path for the dyld shared cache.
1472
1473 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
1474 char dsc_path[PATH_MAX];
1475
1476 snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
1477 "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
1478 "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
1479 header_arch.GetArchitectureName());
1480
1481 FileSpec dsc_filespec(dsc_path, false);
1482
1483 // We need definitions of two structures in the on-disk DSC, copy them here manually
1484struct lldb_copy_dyld_cache_header
1485{
1486 char magic[16];
1487 uint32_t mappingOffset;
1488 uint32_t mappingCount;
1489 uint32_t imagesOffset;
1490 uint32_t imagesCount;
1491 uint64_t dyldBaseAddress;
1492 uint64_t codeSignatureOffset;
1493 uint64_t codeSignatureSize;
1494 uint64_t slideInfoOffset;
1495 uint64_t slideInfoSize;
1496 uint64_t localSymbolsOffset;
1497 uint64_t localSymbolsSize;
1498};
Jason Molendab62abd52012-06-21 01:51:02 +00001499struct lldb_copy_dyld_cache_local_symbols_info
1500{
1501 uint32_t nlistOffset;
1502 uint32_t nlistCount;
1503 uint32_t stringsOffset;
1504 uint32_t stringsSize;
1505 uint32_t entriesOffset;
1506 uint32_t entriesCount;
1507};
Jason Molendab62abd52012-06-21 01:51:02 +00001508struct lldb_copy_dyld_cache_local_symbols_entry
1509{
1510 uint32_t dylibOffset;
1511 uint32_t nlistStartIndex;
1512 uint32_t nlistCount;
1513};
1514
Jason Molendafd3b35d2012-06-22 03:28:35 +00001515 /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
1516 The dyld_cache_local_symbols_info structure gives us three things:
1517 1. The start and count of the nlist records in the dyld_shared_cache file
1518 2. The start and size of the strings for these nlist records
1519 3. The start and count of dyld_cache_local_symbols_entry entries
1520
1521 There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
1522 The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
1523 The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
1524 and the count of how many nlist records there are for this dylib/framework.
1525 */
1526
Jason Molendab62abd52012-06-21 01:51:02 +00001527 // Process the dsc header to find the unmapped symbols
1528 //
1529 // Save some VM space, do not map the entire cache in one shot.
1530
1531 if (DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header)))
1532 {
1533 DataExtractor dsc_header_data(dsc_data_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1534
Jason Molendafd3b35d2012-06-22 03:28:35 +00001535 uint32_t offset = offsetof (struct lldb_copy_dyld_cache_header, mappingOffset);
Jason Molendab62abd52012-06-21 01:51:02 +00001536 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
1537
1538 // If the mappingOffset points to a location inside the header, we've
1539 // opened an old dyld shared cache, and should not proceed further.
1540 if (mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header))
1541 {
1542
Jason Molendafd3b35d2012-06-22 03:28:35 +00001543 offset = offsetof (struct lldb_copy_dyld_cache_header, localSymbolsOffset);
Jason Molendab62abd52012-06-21 01:51:02 +00001544 uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
1545 uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
1546
1547 if (localSymbolsOffset && localSymbolsSize)
1548 {
1549 // Map the local symbols
1550 if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
1551 {
1552 DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1553
1554 offset = 0;
1555
1556 // Read the local_symbols_infos struct in one shot
1557 struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
1558 dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
1559
1560 // The local_symbols_infos offsets are offsets into local symbols memory, NOT file offsets!
1561 // We first need to identify the local "entry" that matches the current header.
1562 // The "entry" is stored as a file offset in the dyld_shared_cache, so we need to
1563 // adjust the raw m_header value by slide and 0x30000000.
1564
1565 SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
1566
1567 uint32_t header_file_offset = (text_section_sp->GetFileAddress() - 0x30000000);
1568
1569 offset = local_symbols_info.entriesOffset;
1570 for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
1571 {
1572 struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
1573 local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
1574 local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
1575 local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
1576
1577 if (header_file_offset == local_symbols_entry.dylibOffset)
1578 {
1579 unmapped_local_symbols_found = local_symbols_entry.nlistCount;
1580
1581 // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
1582 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
1583 num_syms = symtab->GetNumSymbols();
1584
1585 nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
1586 uint32_t string_table_offset = local_symbols_info.stringsOffset;
1587
1588 for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
1589 {
1590 /////////////////////////////
1591 {
1592 struct nlist_64 nlist;
1593 if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
1594 break;
1595
1596 nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
1597 nlist.n_type = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
1598 nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
1599 nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
1600 nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);
1601
1602 SymbolType type = eSymbolTypeInvalid;
1603 const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);
1604
1605 if (symbol_name == NULL)
1606 {
1607 // No symbol should be NULL, even the symbols with no
1608 // string values should have an offset zero which points
1609 // to an empty C-string
1610 Host::SystemLog (Host::eSystemLogError,
1611 "error: DSC unmapped local symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
1612 entry_index,
1613 nlist.n_strx,
1614 module_sp->GetFileSpec().GetDirectory().GetCString(),
1615 module_sp->GetFileSpec().GetFilename().GetCString());
1616 continue;
1617 }
1618 if (symbol_name[0] == '\0')
1619 symbol_name = NULL;
1620
1621 const char *symbol_name_non_abi_mangled = NULL;
1622
1623 SectionSP symbol_section;
1624 uint32_t symbol_byte_size = 0;
1625 bool add_nlist = true;
1626 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
1627
1628 assert (sym_idx < num_syms);
1629
1630 sym[sym_idx].SetDebug (is_debug);
1631
1632 if (is_debug)
1633 {
1634 switch (nlist.n_type)
1635 {
1636 case StabGlobalSymbol:
1637 // N_GSYM -- global symbol: name,,NO_SECT,type,0
1638 // Sometimes the N_GSYM value contains the address.
1639
1640 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
1641 // have the same address, but we want to ensure that we always find only the real symbol,
1642 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
1643 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
1644 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
1645 // same address.
1646
1647 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
1648 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
1649 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
1650 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
1651 add_nlist = false;
1652 else
1653 {
1654 sym[sym_idx].SetExternal(true);
1655 if (nlist.n_value != 0)
1656 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1657 type = eSymbolTypeData;
1658 }
1659 break;
1660
1661 case StabFunctionName:
1662 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
1663 type = eSymbolTypeCompiler;
1664 break;
1665
1666 case StabFunction:
1667 // N_FUN -- procedure: name,,n_sect,linenumber,address
1668 if (symbol_name)
1669 {
1670 type = eSymbolTypeCode;
1671 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1672
1673 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
1674 // We use the current number of symbols in the symbol table in lieu of
1675 // using nlist_idx in case we ever start trimming entries out
1676 N_FUN_indexes.push_back(sym_idx);
1677 }
1678 else
1679 {
1680 type = eSymbolTypeCompiler;
1681
1682 if ( !N_FUN_indexes.empty() )
1683 {
1684 // Copy the size of the function into the original STAB entry so we don't have
1685 // to hunt for it later
1686 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
1687 N_FUN_indexes.pop_back();
1688 // We don't really need the end function STAB as it contains the size which
1689 // we already placed with the original symbol, so don't add it if we want a
1690 // minimal symbol table
1691 if (minimize)
1692 add_nlist = false;
1693 }
1694 }
1695 break;
1696
1697 case StabStaticSymbol:
1698 // N_STSYM -- static symbol: name,,n_sect,type,address
1699 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
1700 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1701 type = eSymbolTypeData;
1702 break;
1703
1704 case StabLocalCommon:
1705 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
1706 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1707 type = eSymbolTypeCommonBlock;
1708 break;
1709
1710 case StabBeginSymbol:
1711 // N_BNSYM
1712 // We use the current number of symbols in the symbol table in lieu of
1713 // using nlist_idx in case we ever start trimming entries out
1714 if (minimize)
1715 {
1716 // Skip these if we want minimal symbol tables
1717 add_nlist = false;
1718 }
1719 else
1720 {
1721 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1722 N_NSYM_indexes.push_back(sym_idx);
1723 type = eSymbolTypeScopeBegin;
1724 }
1725 break;
1726
1727 case StabEndSymbol:
1728 // N_ENSYM
1729 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
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 (minimize)
1733 {
1734 // Skip these if we want minimal symbol tables
1735 add_nlist = false;
1736 }
1737 else
1738 {
1739 if ( !N_NSYM_indexes.empty() )
1740 {
1741 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
1742 symbol_ptr->SetByteSize(sym_idx + 1);
1743 symbol_ptr->SetSizeIsSibling(true);
1744 N_NSYM_indexes.pop_back();
1745 }
1746 type = eSymbolTypeScopeEnd;
1747 }
1748 break;
1749
1750
1751 case StabSourceFileOptions:
1752 // N_OPT - emitted with gcc2_compiled and in gcc source
1753 type = eSymbolTypeCompiler;
1754 break;
1755
1756 case StabRegisterSymbol:
1757 // N_RSYM - register sym: name,,NO_SECT,type,register
1758 type = eSymbolTypeVariable;
1759 break;
1760
1761 case StabSourceLine:
1762 // N_SLINE - src line: 0,,n_sect,linenumber,address
1763 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1764 type = eSymbolTypeLineEntry;
1765 break;
1766
1767 case StabStructureType:
1768 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
1769 type = eSymbolTypeVariableType;
1770 break;
1771
1772 case StabSourceFileName:
1773 // N_SO - source file name
1774 type = eSymbolTypeSourceFile;
1775 if (symbol_name == NULL)
1776 {
1777 if (minimize)
1778 add_nlist = false;
1779 if (N_SO_index != UINT32_MAX)
1780 {
1781 // Set the size of the N_SO to the terminating index of this N_SO
1782 // so that we can always skip the entire N_SO if we need to navigate
1783 // more quickly at the source level when parsing STABS
1784 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
1785 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
1786 symbol_ptr->SetSizeIsSibling(true);
1787 }
1788 N_NSYM_indexes.clear();
1789 N_INCL_indexes.clear();
1790 N_BRAC_indexes.clear();
1791 N_COMM_indexes.clear();
1792 N_FUN_indexes.clear();
1793 N_SO_index = UINT32_MAX;
1794 }
1795 else
1796 {
1797 // We use the current number of symbols in the symbol table in lieu of
1798 // using nlist_idx in case we ever start trimming entries out
1799 const bool N_SO_has_full_path = symbol_name[0] == '/';
1800 if (N_SO_has_full_path)
1801 {
1802 if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1803 {
1804 // We have two consecutive N_SO entries where the first contains a directory
1805 // and the second contains a full path.
Jason Molenda292cca82012-07-20 03:35:44 +00001806 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Jason Molendab62abd52012-06-21 01:51:02 +00001807 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1808 add_nlist = false;
1809 }
1810 else
1811 {
1812 // This is the first entry in a N_SO that contains a directory or
1813 // a full path to the source file
1814 N_SO_index = sym_idx;
1815 }
1816 }
1817 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
1818 {
1819 // This is usually the second N_SO entry that contains just the filename,
1820 // so here we combine it with the first one if we are minimizing the symbol table
1821 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
1822 if (so_path && so_path[0])
1823 {
1824 std::string full_so_path (so_path);
1825 if (*full_so_path.rbegin() != '/')
1826 full_so_path += '/';
1827 full_so_path += symbol_name;
Jason Molenda292cca82012-07-20 03:35:44 +00001828 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Jason Molendab62abd52012-06-21 01:51:02 +00001829 add_nlist = false;
1830 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
1831 }
1832 }
1833 }
1834
1835 break;
1836
1837 case StabObjectFileName:
1838 // N_OSO - object file name: name,,0,0,st_mtime
1839 type = eSymbolTypeObjectFile;
1840 break;
1841
1842 case StabLocalSymbol:
1843 // N_LSYM - local sym: name,,NO_SECT,type,offset
1844 type = eSymbolTypeLocal;
1845 break;
1846
1847 //----------------------------------------------------------------------
1848 // INCL scopes
1849 //----------------------------------------------------------------------
1850 case StabBeginIncludeFileName:
1851 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
1852 // We use the current number of symbols in the symbol table in lieu of
1853 // using nlist_idx in case we ever start trimming entries out
1854 N_INCL_indexes.push_back(sym_idx);
1855 type = eSymbolTypeScopeBegin;
1856 break;
1857
1858 case StabEndIncludeFile:
1859 // N_EINCL - include file end: name,,NO_SECT,0,0
1860 // Set the size of the N_BINCL to the terminating index of this N_EINCL
1861 // so that we can always skip the entire symbol if we need to navigate
1862 // more quickly at the source level when parsing STABS
1863 if ( !N_INCL_indexes.empty() )
1864 {
1865 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
1866 symbol_ptr->SetByteSize(sym_idx + 1);
1867 symbol_ptr->SetSizeIsSibling(true);
1868 N_INCL_indexes.pop_back();
1869 }
1870 type = eSymbolTypeScopeEnd;
1871 break;
1872
1873 case StabIncludeFileName:
1874 // N_SOL - #included file name: name,,n_sect,0,address
1875 type = eSymbolTypeHeaderFile;
1876
1877 // We currently don't use the header files on darwin
1878 if (minimize)
1879 add_nlist = false;
1880 break;
1881
1882 case StabCompilerParameters:
1883 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
1884 type = eSymbolTypeCompiler;
1885 break;
1886
1887 case StabCompilerVersion:
1888 // N_VERSION - compiler version: name,,NO_SECT,0,0
1889 type = eSymbolTypeCompiler;
1890 break;
1891
1892 case StabCompilerOptLevel:
1893 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
1894 type = eSymbolTypeCompiler;
1895 break;
1896
1897 case StabParameter:
1898 // N_PSYM - parameter: name,,NO_SECT,type,offset
1899 type = eSymbolTypeVariable;
1900 break;
1901
1902 case StabAlternateEntry:
1903 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
1904 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1905 type = eSymbolTypeLineEntry;
1906 break;
1907
1908 //----------------------------------------------------------------------
1909 // Left and Right Braces
1910 //----------------------------------------------------------------------
1911 case StabLeftBracket:
1912 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
1913 // We use the current number of symbols in the symbol table in lieu of
1914 // using nlist_idx in case we ever start trimming entries out
1915 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1916 N_BRAC_indexes.push_back(sym_idx);
1917 type = eSymbolTypeScopeBegin;
1918 break;
1919
1920 case StabRightBracket:
1921 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
1922 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
1923 // so that we can always skip the entire symbol if we need to navigate
1924 // more quickly at the source level when parsing STABS
1925 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1926 if ( !N_BRAC_indexes.empty() )
1927 {
1928 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
1929 symbol_ptr->SetByteSize(sym_idx + 1);
1930 symbol_ptr->SetSizeIsSibling(true);
1931 N_BRAC_indexes.pop_back();
1932 }
1933 type = eSymbolTypeScopeEnd;
1934 break;
1935
1936 case StabDeletedIncludeFile:
1937 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
1938 type = eSymbolTypeHeaderFile;
1939 break;
1940
1941 //----------------------------------------------------------------------
1942 // COMM scopes
1943 //----------------------------------------------------------------------
1944 case StabBeginCommon:
1945 // N_BCOMM - begin common: name,,NO_SECT,0,0
1946 // We use the current number of symbols in the symbol table in lieu of
1947 // using nlist_idx in case we ever start trimming entries out
1948 type = eSymbolTypeScopeBegin;
1949 N_COMM_indexes.push_back(sym_idx);
1950 break;
1951
1952 case StabEndCommonLocal:
1953 // N_ECOML - end common (local name): 0,,n_sect,0,address
1954 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1955 // Fall through
1956
1957 case StabEndCommon:
1958 // N_ECOMM - end common: name,,n_sect,0,0
1959 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
1960 // so that we can always skip the entire symbol if we need to navigate
1961 // more quickly at the source level when parsing STABS
1962 if ( !N_COMM_indexes.empty() )
1963 {
1964 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
1965 symbol_ptr->SetByteSize(sym_idx + 1);
1966 symbol_ptr->SetSizeIsSibling(true);
1967 N_COMM_indexes.pop_back();
1968 }
1969 type = eSymbolTypeScopeEnd;
1970 break;
1971
1972 case StabLength:
1973 // N_LENG - second stab entry with length information
1974 type = eSymbolTypeAdditional;
1975 break;
1976
1977 default: break;
1978 }
1979 }
1980 else
1981 {
1982 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
1983 uint8_t n_type = NlistMaskType & nlist.n_type;
1984 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
1985
1986 switch (n_type)
1987 {
1988 case NListTypeIndirect: // N_INDR - Fall through
1989 case NListTypePreboundUndefined:// N_PBUD - Fall through
1990 case NListTypeUndefined: // N_UNDF
1991 type = eSymbolTypeUndefined;
1992 break;
1993
1994 case NListTypeAbsolute: // N_ABS
1995 type = eSymbolTypeAbsolute;
1996 break;
1997
1998 case NListTypeSection: // N_SECT
1999 {
2000 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2001
2002 if (symbol_section == NULL)
2003 {
2004 // TODO: warn about this?
2005 add_nlist = false;
2006 break;
2007 }
2008
2009 if (TEXT_eh_frame_sectID == nlist.n_sect)
2010 {
2011 type = eSymbolTypeException;
2012 }
2013 else
2014 {
2015 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
2016
2017 switch (section_type)
2018 {
2019 case SectionTypeRegular: break; // regular section
2020 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
2021 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
2022 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
2023 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
2024 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
2025 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
2026 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
2027 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
2028 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
2029 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
2030 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
2031 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
2032 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
2033 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
2034 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
2035 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
2036 default: break;
2037 }
2038
2039 if (type == eSymbolTypeInvalid)
2040 {
2041 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2042 if (symbol_section->IsDescendant (text_section_sp.get()))
2043 {
2044 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
2045 SectionAttrUserSelfModifyingCode |
2046 SectionAttrSytemSomeInstructions))
2047 type = eSymbolTypeData;
2048 else
2049 type = eSymbolTypeCode;
2050 }
2051 else
2052 if (symbol_section->IsDescendant(data_section_sp.get()))
2053 {
2054 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
2055 {
2056 type = eSymbolTypeRuntime;
2057
2058 if (symbol_name &&
2059 symbol_name[0] == '_' &&
2060 symbol_name[1] == 'O' &&
2061 symbol_name[2] == 'B')
2062 {
2063 llvm::StringRef symbol_name_ref(symbol_name);
2064 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2065 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2066 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
2067 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
2068 {
2069 symbol_name_non_abi_mangled = symbol_name + 1;
2070 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2071 type = eSymbolTypeObjCClass;
2072 }
2073 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
2074 {
2075 symbol_name_non_abi_mangled = symbol_name + 1;
2076 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2077 type = eSymbolTypeObjCMetaClass;
2078 }
2079 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
2080 {
2081 symbol_name_non_abi_mangled = symbol_name + 1;
2082 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2083 type = eSymbolTypeObjCIVar;
2084 }
2085 }
2086 }
2087 else
2088 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
2089 {
2090 type = eSymbolTypeException;
2091 }
2092 else
2093 {
2094 type = eSymbolTypeData;
2095 }
2096 }
2097 else
2098 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
2099 {
2100 type = eSymbolTypeTrampoline;
2101 }
2102 else
2103 if (symbol_section->IsDescendant(objc_section_sp.get()))
2104 {
2105 type = eSymbolTypeRuntime;
2106 if (symbol_name && symbol_name[0] == '.')
2107 {
2108 llvm::StringRef symbol_name_ref(symbol_name);
2109 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
2110 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
2111 {
2112 symbol_name_non_abi_mangled = symbol_name;
2113 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
2114 type = eSymbolTypeObjCClass;
2115 }
2116 }
2117 }
2118 }
2119 }
2120 }
2121 break;
2122 }
2123 }
2124
2125 if (add_nlist)
2126 {
2127 uint64_t symbol_value = nlist.n_value;
2128 bool symbol_name_is_mangled = false;
2129
2130 if (symbol_name_non_abi_mangled)
2131 {
Jason Molenda292cca82012-07-20 03:35:44 +00002132 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
2133 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Jason Molendab62abd52012-06-21 01:51:02 +00002134 }
2135 else
2136 {
2137 if (symbol_name && symbol_name[0] == '_')
2138 {
2139 symbol_name_is_mangled = symbol_name[1] == '_';
2140 symbol_name++; // Skip the leading underscore
2141 }
2142
2143 if (symbol_name)
2144 {
Jason Molenda292cca82012-07-20 03:35:44 +00002145 sym[sym_idx].GetMangled().SetValue(ConstString(symbol_name), symbol_name_is_mangled);
Jason Molendab62abd52012-06-21 01:51:02 +00002146 }
2147 }
2148
2149 if (is_debug == false)
2150 {
2151 if (type == eSymbolTypeCode)
2152 {
2153 // See if we can find a N_FUN entry for any code symbols.
2154 // If we do find a match, and the name matches, then we
2155 // can merge the two into just the function symbol to avoid
2156 // duplicate entries in the symbol table
2157 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
2158 if (pos != N_FUN_addr_to_sym_idx.end())
2159 {
2160 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2161 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2162 {
2163 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2164 // We just need the flags from the linker symbol, so put these flags
2165 // into the N_FUN flags to avoid duplicate symbols in the symbol table
2166 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2167 sym[sym_idx].Clear();
2168 continue;
2169 }
2170 }
2171 }
2172 else if (type == eSymbolTypeData)
2173 {
2174 // See if we can find a N_STSYM entry for any data symbols.
2175 // If we do find a match, and the name matches, then we
2176 // can merge the two into just the Static symbol to avoid
2177 // duplicate entries in the symbol table
2178 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
2179 if (pos != N_STSYM_addr_to_sym_idx.end())
2180 {
2181 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2182 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2183 {
2184 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2185 // We just need the flags from the linker symbol, so put these flags
2186 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
2187 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2188 sym[sym_idx].Clear();
2189 continue;
2190 }
2191 }
2192 }
2193 }
2194 if (symbol_section)
2195 {
2196 const addr_t section_file_addr = symbol_section->GetFileAddress();
2197 if (symbol_byte_size == 0 && function_starts_count > 0)
2198 {
2199 addr_t symbol_lookup_file_addr = nlist.n_value;
2200 // Do an exact address match for non-ARM addresses, else get the closest since
2201 // the symbol might be a thumb symbol which has an address with bit zero set
2202 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
2203 if (is_arm && func_start_entry)
2204 {
2205 // Verify that the function start address is the symbol address (ARM)
2206 // or the symbol address + 1 (thumb)
2207 if (func_start_entry->addr != symbol_lookup_file_addr &&
2208 func_start_entry->addr != (symbol_lookup_file_addr + 1))
2209 {
2210 // Not the right entry, NULL it out...
2211 func_start_entry = NULL;
2212 }
2213 }
2214 if (func_start_entry)
2215 {
2216 func_start_entry->data = true;
2217
2218 addr_t symbol_file_addr = func_start_entry->addr;
2219 uint32_t symbol_flags = 0;
2220 if (is_arm)
2221 {
2222 if (symbol_file_addr & 1)
2223 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
2224 symbol_file_addr &= 0xfffffffffffffffeull;
2225 }
2226
2227 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2228 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2229 if (next_func_start_entry)
2230 {
2231 addr_t next_symbol_file_addr = next_func_start_entry->addr;
2232 // Be sure the clear the Thumb address bit when we calculate the size
2233 // from the current and next address
2234 if (is_arm)
2235 next_symbol_file_addr &= 0xfffffffffffffffeull;
2236 symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
2237 }
2238 else
2239 {
2240 symbol_byte_size = section_end_file_addr - symbol_file_addr;
2241 }
2242 }
2243 }
2244 symbol_value -= section_file_addr;
2245 }
2246
2247 sym[sym_idx].SetID (nlist_idx);
2248 sym[sym_idx].SetType (type);
2249 sym[sym_idx].GetAddress().SetSection (symbol_section);
2250 sym[sym_idx].GetAddress().SetOffset (symbol_value);
2251 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2252
2253 if (symbol_byte_size > 0)
2254 sym[sym_idx].SetByteSize(symbol_byte_size);
2255
2256 ++sym_idx;
2257 }
2258 else
2259 {
2260 sym[sym_idx].Clear();
2261 }
2262
2263 }
2264 /////////////////////////////
2265 }
2266 break; // No more entries to consider
2267 }
2268 }
2269 }
2270 }
2271 }
2272 }
2273 }
2274
2275 // Must reset this in case it was mutated above!
2276 nlist_data_offset = 0;
2277#endif
2278
2279 // If the sym array was not created while parsing the DSC unmapped
2280 // symbols, create it now.
2281 if (sym == NULL)
2282 {
2283 sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
2284 num_syms = symtab->GetNumSymbols();
2285 }
2286
2287 if (unmapped_local_symbols_found)
2288 {
2289 assert(m_dysymtab.ilocalsym == 0);
2290 nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
2291 nlist_idx = m_dysymtab.nlocalsym;
2292 }
2293 else
2294 {
2295 nlist_idx = 0;
2296 }
2297
2298 for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002299 {
2300 struct nlist_64 nlist;
2301 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
2302 break;
2303
2304 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
2305 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
2306 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
2307 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
2308 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
2309
2310 SymbolType type = eSymbolTypeInvalid;
Greg Claytondd29b972012-05-18 23:20:01 +00002311 const char *symbol_name = NULL;
2312
Greg Clayton3a5dc012012-05-25 17:04:00 +00002313 if (have_strtab_data)
Greg Claytondd29b972012-05-18 23:20:01 +00002314 {
2315 symbol_name = strtab_data.PeekCStr(nlist.n_strx);
2316
2317 if (symbol_name == NULL)
2318 {
2319 // No symbol should be NULL, even the symbols with no
2320 // string values should have an offset zero which points
2321 // to an empty C-string
2322 Host::SystemLog (Host::eSystemLogError,
2323 "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
2324 nlist_idx,
2325 nlist.n_strx,
2326 module_sp->GetFileSpec().GetDirectory().GetCString(),
2327 module_sp->GetFileSpec().GetFilename().GetCString());
2328 continue;
2329 }
2330 if (symbol_name[0] == '\0')
2331 symbol_name = NULL;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002332 }
Greg Clayton3a5dc012012-05-25 17:04:00 +00002333 else
2334 {
2335 const addr_t str_addr = strtab_addr + nlist.n_strx;
2336 Error str_error;
2337 if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
2338 symbol_name = memory_symbol_name.c_str();
2339 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002340 const char *symbol_name_non_abi_mangled = NULL;
2341
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002342 SectionSP symbol_section;
2343 uint32_t symbol_byte_size = 0;
2344 bool add_nlist = true;
2345 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
2346
2347 assert (sym_idx < num_syms);
2348
2349 sym[sym_idx].SetDebug (is_debug);
2350
2351 if (is_debug)
2352 {
2353 switch (nlist.n_type)
Greg Clayton0fea0512011-12-30 00:32:24 +00002354 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002355 case StabGlobalSymbol:
2356 // N_GSYM -- global symbol: name,,NO_SECT,type,0
2357 // Sometimes the N_GSYM value contains the address.
2358
2359 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
2360 // have the same address, but we want to ensure that we always find only the real symbol,
2361 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
2362 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
2363 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
2364 // same address.
2365
2366 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
2367 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
2368 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
2369 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
2370 add_nlist = false;
2371 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00002372 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002373 sym[sym_idx].SetExternal(true);
2374 if (nlist.n_value != 0)
2375 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2376 type = eSymbolTypeData;
Greg Claytonb5a8f142012-02-05 02:38:54 +00002377 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002378 break;
Greg Claytonb5a8f142012-02-05 02:38:54 +00002379
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002380 case StabFunctionName:
2381 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
2382 type = eSymbolTypeCompiler;
2383 break;
Greg Clayton0fea0512011-12-30 00:32:24 +00002384
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002385 case StabFunction:
2386 // N_FUN -- procedure: name,,n_sect,linenumber,address
2387 if (symbol_name)
Greg Claytona9c4f312011-10-31 20:50:40 +00002388 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002389 type = eSymbolTypeCode;
2390 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2391
2392 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
2393 // We use the current number of symbols in the symbol table in lieu of
2394 // using nlist_idx in case we ever start trimming entries out
2395 N_FUN_indexes.push_back(sym_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00002396 }
2397 else
2398 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002399 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00002400
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002401 if ( !N_FUN_indexes.empty() )
Chris Lattner24943d22010-06-08 16:52:24 +00002402 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002403 // Copy the size of the function into the original STAB entry so we don't have
2404 // to hunt for it later
2405 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
2406 N_FUN_indexes.pop_back();
2407 // We don't really need the end function STAB as it contains the size which
2408 // we already placed with the original symbol, so don't add it if we want a
2409 // minimal symbol table
2410 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00002411 add_nlist = false;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002412 }
Greg Clayton3f69eac2011-12-03 02:30:59 +00002413 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002414 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00002415
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002416 case StabStaticSymbol:
2417 // N_STSYM -- static symbol: name,,n_sect,type,address
2418 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
2419 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2420 type = eSymbolTypeData;
2421 break;
2422
2423 case StabLocalCommon:
2424 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
2425 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2426 type = eSymbolTypeCommonBlock;
2427 break;
2428
2429 case StabBeginSymbol:
2430 // N_BNSYM
2431 // We use the current number of symbols in the symbol table in lieu of
2432 // using nlist_idx in case we ever start trimming entries out
2433 if (minimize)
Greg Clayton3f69eac2011-12-03 02:30:59 +00002434 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002435 // Skip these if we want minimal symbol tables
2436 add_nlist = false;
2437 }
2438 else
2439 {
2440 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2441 N_NSYM_indexes.push_back(sym_idx);
2442 type = eSymbolTypeScopeBegin;
2443 }
2444 break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00002445
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002446 case StabEndSymbol:
2447 // N_ENSYM
2448 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
2449 // so that we can always skip the entire symbol if we need to navigate
2450 // more quickly at the source level when parsing STABS
2451 if (minimize)
2452 {
2453 // Skip these if we want minimal symbol tables
2454 add_nlist = false;
2455 }
2456 else
2457 {
2458 if ( !N_NSYM_indexes.empty() )
Greg Clayton3f69eac2011-12-03 02:30:59 +00002459 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002460 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
2461 symbol_ptr->SetByteSize(sym_idx + 1);
2462 symbol_ptr->SetSizeIsSibling(true);
2463 N_NSYM_indexes.pop_back();
2464 }
2465 type = eSymbolTypeScopeEnd;
2466 }
2467 break;
2468
2469
2470 case StabSourceFileOptions:
2471 // N_OPT - emitted with gcc2_compiled and in gcc source
2472 type = eSymbolTypeCompiler;
2473 break;
2474
2475 case StabRegisterSymbol:
2476 // N_RSYM - register sym: name,,NO_SECT,type,register
2477 type = eSymbolTypeVariable;
2478 break;
2479
2480 case StabSourceLine:
2481 // N_SLINE - src line: 0,,n_sect,linenumber,address
2482 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2483 type = eSymbolTypeLineEntry;
2484 break;
2485
2486 case StabStructureType:
2487 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
2488 type = eSymbolTypeVariableType;
2489 break;
2490
2491 case StabSourceFileName:
2492 // N_SO - source file name
2493 type = eSymbolTypeSourceFile;
2494 if (symbol_name == NULL)
2495 {
2496 if (minimize)
2497 add_nlist = false;
2498 if (N_SO_index != UINT32_MAX)
2499 {
2500 // Set the size of the N_SO to the terminating index of this N_SO
2501 // so that we can always skip the entire N_SO if we need to navigate
2502 // more quickly at the source level when parsing STABS
2503 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
2504 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
2505 symbol_ptr->SetSizeIsSibling(true);
2506 }
2507 N_NSYM_indexes.clear();
2508 N_INCL_indexes.clear();
2509 N_BRAC_indexes.clear();
2510 N_COMM_indexes.clear();
2511 N_FUN_indexes.clear();
2512 N_SO_index = UINT32_MAX;
2513 }
2514 else
2515 {
2516 // We use the current number of symbols in the symbol table in lieu of
2517 // using nlist_idx in case we ever start trimming entries out
Greg Clayton5fa6cd32012-05-30 20:20:34 +00002518 const bool N_SO_has_full_path = symbol_name[0] == '/';
2519 if (N_SO_has_full_path)
2520 {
2521 if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
2522 {
2523 // We have two consecutive N_SO entries where the first contains a directory
2524 // and the second contains a full path.
Greg Claytonc0240042012-07-18 23:18:10 +00002525 sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
Greg Clayton5fa6cd32012-05-30 20:20:34 +00002526 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2527 add_nlist = false;
2528 }
2529 else
2530 {
2531 // This is the first entry in a N_SO that contains a directory or
2532 // a full path to the source file
2533 N_SO_index = sym_idx;
2534 }
2535 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002536 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
2537 {
Greg Clayton5fa6cd32012-05-30 20:20:34 +00002538 // This is usually the second N_SO entry that contains just the filename,
2539 // so here we combine it with the first one if we are minimizing the symbol table
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002540 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
2541 if (so_path && so_path[0])
2542 {
2543 std::string full_so_path (so_path);
2544 if (*full_so_path.rbegin() != '/')
2545 full_so_path += '/';
2546 full_so_path += symbol_name;
Greg Claytonc0240042012-07-18 23:18:10 +00002547 sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002548 add_nlist = false;
2549 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
2550 }
2551 }
2552 }
2553
2554 break;
2555
2556 case StabObjectFileName:
2557 // N_OSO - object file name: name,,0,0,st_mtime
2558 type = eSymbolTypeObjectFile;
2559 break;
2560
2561 case StabLocalSymbol:
2562 // N_LSYM - local sym: name,,NO_SECT,type,offset
2563 type = eSymbolTypeLocal;
2564 break;
2565
2566 //----------------------------------------------------------------------
2567 // INCL scopes
2568 //----------------------------------------------------------------------
2569 case StabBeginIncludeFileName:
2570 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
2571 // We use the current number of symbols in the symbol table in lieu of
2572 // using nlist_idx in case we ever start trimming entries out
2573 N_INCL_indexes.push_back(sym_idx);
2574 type = eSymbolTypeScopeBegin;
2575 break;
2576
2577 case StabEndIncludeFile:
2578 // N_EINCL - include file end: name,,NO_SECT,0,0
2579 // Set the size of the N_BINCL to the terminating index of this N_EINCL
2580 // so that we can always skip the entire symbol if we need to navigate
2581 // more quickly at the source level when parsing STABS
2582 if ( !N_INCL_indexes.empty() )
2583 {
2584 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
2585 symbol_ptr->SetByteSize(sym_idx + 1);
2586 symbol_ptr->SetSizeIsSibling(true);
2587 N_INCL_indexes.pop_back();
2588 }
2589 type = eSymbolTypeScopeEnd;
2590 break;
2591
2592 case StabIncludeFileName:
2593 // N_SOL - #included file name: name,,n_sect,0,address
2594 type = eSymbolTypeHeaderFile;
2595
2596 // We currently don't use the header files on darwin
2597 if (minimize)
2598 add_nlist = false;
2599 break;
2600
2601 case StabCompilerParameters:
2602 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
2603 type = eSymbolTypeCompiler;
2604 break;
2605
2606 case StabCompilerVersion:
2607 // N_VERSION - compiler version: name,,NO_SECT,0,0
2608 type = eSymbolTypeCompiler;
2609 break;
2610
2611 case StabCompilerOptLevel:
2612 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
2613 type = eSymbolTypeCompiler;
2614 break;
2615
2616 case StabParameter:
2617 // N_PSYM - parameter: name,,NO_SECT,type,offset
2618 type = eSymbolTypeVariable;
2619 break;
2620
2621 case StabAlternateEntry:
2622 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
2623 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2624 type = eSymbolTypeLineEntry;
2625 break;
2626
2627 //----------------------------------------------------------------------
2628 // Left and Right Braces
2629 //----------------------------------------------------------------------
2630 case StabLeftBracket:
2631 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
2632 // We use the current number of symbols in the symbol table in lieu of
2633 // using nlist_idx in case we ever start trimming entries out
2634 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2635 N_BRAC_indexes.push_back(sym_idx);
2636 type = eSymbolTypeScopeBegin;
2637 break;
2638
2639 case StabRightBracket:
2640 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
2641 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
2642 // so that we can always skip the entire symbol if we need to navigate
2643 // more quickly at the source level when parsing STABS
2644 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2645 if ( !N_BRAC_indexes.empty() )
2646 {
2647 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
2648 symbol_ptr->SetByteSize(sym_idx + 1);
2649 symbol_ptr->SetSizeIsSibling(true);
2650 N_BRAC_indexes.pop_back();
2651 }
2652 type = eSymbolTypeScopeEnd;
2653 break;
2654
2655 case StabDeletedIncludeFile:
2656 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
2657 type = eSymbolTypeHeaderFile;
2658 break;
2659
2660 //----------------------------------------------------------------------
2661 // COMM scopes
2662 //----------------------------------------------------------------------
2663 case StabBeginCommon:
2664 // N_BCOMM - begin common: name,,NO_SECT,0,0
2665 // We use the current number of symbols in the symbol table in lieu of
2666 // using nlist_idx in case we ever start trimming entries out
2667 type = eSymbolTypeScopeBegin;
2668 N_COMM_indexes.push_back(sym_idx);
2669 break;
2670
2671 case StabEndCommonLocal:
2672 // N_ECOML - end common (local name): 0,,n_sect,0,address
2673 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2674 // Fall through
2675
2676 case StabEndCommon:
2677 // N_ECOMM - end common: name,,n_sect,0,0
2678 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
2679 // so that we can always skip the entire symbol if we need to navigate
2680 // more quickly at the source level when parsing STABS
2681 if ( !N_COMM_indexes.empty() )
2682 {
2683 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
2684 symbol_ptr->SetByteSize(sym_idx + 1);
2685 symbol_ptr->SetSizeIsSibling(true);
2686 N_COMM_indexes.pop_back();
2687 }
2688 type = eSymbolTypeScopeEnd;
2689 break;
2690
2691 case StabLength:
2692 // N_LENG - second stab entry with length information
2693 type = eSymbolTypeAdditional;
2694 break;
2695
2696 default: break;
2697 }
2698 }
2699 else
2700 {
2701 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
2702 uint8_t n_type = NlistMaskType & nlist.n_type;
2703 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
2704
2705 switch (n_type)
2706 {
2707 case NListTypeIndirect: // N_INDR - Fall through
2708 case NListTypePreboundUndefined:// N_PBUD - Fall through
2709 case NListTypeUndefined: // N_UNDF
2710 type = eSymbolTypeUndefined;
2711 break;
2712
2713 case NListTypeAbsolute: // N_ABS
2714 type = eSymbolTypeAbsolute;
2715 break;
2716
2717 case NListTypeSection: // N_SECT
2718 {
2719 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
2720
Sean Callananb386d822012-08-09 00:50:26 +00002721 if (!symbol_section)
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002722 {
2723 // TODO: warn about this?
2724 add_nlist = false;
2725 break;
2726 }
2727
2728 if (TEXT_eh_frame_sectID == nlist.n_sect)
2729 {
2730 type = eSymbolTypeException;
Chris Lattner24943d22010-06-08 16:52:24 +00002731 }
2732 else
2733 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002734 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
2735
2736 switch (section_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002737 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002738 case SectionTypeRegular: break; // regular section
2739 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
2740 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
2741 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
2742 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
2743 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
2744 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
2745 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
2746 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
2747 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
2748 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
2749 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
2750 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
2751 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
2752 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
2753 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
2754 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
2755 default: break;
Greg Clayton3f69eac2011-12-03 02:30:59 +00002756 }
Chris Lattner24943d22010-06-08 16:52:24 +00002757
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002758 if (type == eSymbolTypeInvalid)
Greg Clayton3f69eac2011-12-03 02:30:59 +00002759 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002760 const char *symbol_sect_name = symbol_section->GetName().AsCString();
2761 if (symbol_section->IsDescendant (text_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00002762 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002763 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
2764 SectionAttrUserSelfModifyingCode |
2765 SectionAttrSytemSomeInstructions))
2766 type = eSymbolTypeData;
2767 else
2768 type = eSymbolTypeCode;
Greg Clayton576a68b2010-09-08 16:38:06 +00002769 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002770 else
2771 if (symbol_section->IsDescendant(data_section_sp.get()))
Greg Clayton576a68b2010-09-08 16:38:06 +00002772 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002773 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
Greg Clayton7c36fa02010-09-11 03:13:28 +00002774 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002775 type = eSymbolTypeRuntime;
Chris Lattner24943d22010-06-08 16:52:24 +00002776
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002777 if (symbol_name &&
2778 symbol_name[0] == '_' &&
2779 symbol_name[1] == 'O' &&
2780 symbol_name[2] == 'B')
Greg Clayton637029b2010-09-12 05:25:16 +00002781 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002782 llvm::StringRef symbol_name_ref(symbol_name);
2783 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
2784 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
2785 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
2786 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
Chris Lattner24943d22010-06-08 16:52:24 +00002787 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002788 symbol_name_non_abi_mangled = symbol_name + 1;
2789 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
2790 type = eSymbolTypeObjCClass;
Chris Lattner24943d22010-06-08 16:52:24 +00002791 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002792 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
Chris Lattner24943d22010-06-08 16:52:24 +00002793 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002794 symbol_name_non_abi_mangled = symbol_name + 1;
2795 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
2796 type = eSymbolTypeObjCMetaClass;
2797 }
2798 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
2799 {
2800 symbol_name_non_abi_mangled = symbol_name + 1;
2801 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
2802 type = eSymbolTypeObjCIVar;
Chris Lattner24943d22010-06-08 16:52:24 +00002803 }
2804 }
2805 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002806 else
2807 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
2808 {
2809 type = eSymbolTypeException;
2810 }
2811 else
2812 {
2813 type = eSymbolTypeData;
2814 }
2815 }
2816 else
2817 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
2818 {
2819 type = eSymbolTypeTrampoline;
2820 }
2821 else
2822 if (symbol_section->IsDescendant(objc_section_sp.get()))
2823 {
2824 type = eSymbolTypeRuntime;
2825 if (symbol_name && symbol_name[0] == '.')
2826 {
2827 llvm::StringRef symbol_name_ref(symbol_name);
2828 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
2829 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
2830 {
2831 symbol_name_non_abi_mangled = symbol_name;
2832 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
2833 type = eSymbolTypeObjCClass;
2834 }
2835 }
Chris Lattner24943d22010-06-08 16:52:24 +00002836 }
2837 }
2838 }
2839 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002840 break;
2841 }
2842 }
2843
2844 if (add_nlist)
2845 {
2846 uint64_t symbol_value = nlist.n_value;
2847 bool symbol_name_is_mangled = false;
2848
2849 if (symbol_name_non_abi_mangled)
2850 {
Greg Claytonc0240042012-07-18 23:18:10 +00002851 sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
2852 sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
Chris Lattner24943d22010-06-08 16:52:24 +00002853 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002854 else
2855 {
2856 if (symbol_name && symbol_name[0] == '_')
2857 {
2858 symbol_name_is_mangled = symbol_name[1] == '_';
2859 symbol_name++; // Skip the leading underscore
2860 }
2861
2862 if (symbol_name)
2863 {
Greg Claytonc0240042012-07-18 23:18:10 +00002864 sym[sym_idx].GetMangled().SetValue(ConstString(symbol_name), symbol_name_is_mangled);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002865 }
2866 }
2867
2868 if (is_debug == false)
2869 {
2870 if (type == eSymbolTypeCode)
2871 {
2872 // See if we can find a N_FUN entry for any code symbols.
2873 // If we do find a match, and the name matches, then we
2874 // can merge the two into just the function symbol to avoid
2875 // duplicate entries in the symbol table
2876 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
2877 if (pos != N_FUN_addr_to_sym_idx.end())
2878 {
2879 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2880 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2881 {
2882 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2883 // We just need the flags from the linker symbol, so put these flags
2884 // into the N_FUN flags to avoid duplicate symbols in the symbol table
2885 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2886 sym[sym_idx].Clear();
2887 continue;
2888 }
2889 }
2890 }
2891 else if (type == eSymbolTypeData)
2892 {
2893 // See if we can find a N_STSYM entry for any data symbols.
2894 // If we do find a match, and the name matches, then we
2895 // can merge the two into just the Static symbol to avoid
2896 // duplicate entries in the symbol table
2897 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
2898 if (pos != N_STSYM_addr_to_sym_idx.end())
2899 {
2900 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
2901 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
2902 {
2903 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
2904 // We just need the flags from the linker symbol, so put these flags
2905 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
2906 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2907 sym[sym_idx].Clear();
2908 continue;
2909 }
2910 }
2911 }
2912 }
2913 if (symbol_section)
2914 {
2915 const addr_t section_file_addr = symbol_section->GetFileAddress();
2916 if (symbol_byte_size == 0 && function_starts_count > 0)
2917 {
Greg Claytond2653c22012-03-14 01:53:24 +00002918 addr_t symbol_lookup_file_addr = nlist.n_value;
2919 // Do an exact address match for non-ARM addresses, else get the closest since
2920 // the symbol might be a thumb symbol which has an address with bit zero set
2921 FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
2922 if (is_arm && func_start_entry)
2923 {
2924 // Verify that the function start address is the symbol address (ARM)
2925 // or the symbol address + 1 (thumb)
2926 if (func_start_entry->addr != symbol_lookup_file_addr &&
2927 func_start_entry->addr != (symbol_lookup_file_addr + 1))
2928 {
2929 // Not the right entry, NULL it out...
2930 func_start_entry = NULL;
2931 }
2932 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002933 if (func_start_entry)
2934 {
2935 func_start_entry->data = true;
Greg Claytond2653c22012-03-14 01:53:24 +00002936
2937 addr_t symbol_file_addr = func_start_entry->addr;
Greg Claytond2653c22012-03-14 01:53:24 +00002938 if (is_arm)
Greg Claytond2653c22012-03-14 01:53:24 +00002939 symbol_file_addr &= 0xfffffffffffffffeull;
Greg Claytond2653c22012-03-14 01:53:24 +00002940
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002941 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
2942 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
2943 if (next_func_start_entry)
2944 {
Greg Claytond2653c22012-03-14 01:53:24 +00002945 addr_t next_symbol_file_addr = next_func_start_entry->addr;
2946 // Be sure the clear the Thumb address bit when we calculate the size
2947 // from the current and next address
2948 if (is_arm)
2949 next_symbol_file_addr &= 0xfffffffffffffffeull;
2950 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 +00002951 }
2952 else
2953 {
Greg Claytond2653c22012-03-14 01:53:24 +00002954 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00002955 }
2956 }
2957 }
2958 symbol_value -= section_file_addr;
2959 }
2960
2961 sym[sym_idx].SetID (nlist_idx);
2962 sym[sym_idx].SetType (type);
2963 sym[sym_idx].GetAddress().SetSection (symbol_section);
2964 sym[sym_idx].GetAddress().SetOffset (symbol_value);
2965 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
2966
2967 if (symbol_byte_size > 0)
2968 sym[sym_idx].SetByteSize(symbol_byte_size);
2969
2970 ++sym_idx;
2971 }
2972 else
2973 {
2974 sym[sym_idx].Clear();
2975 }
2976
2977 }
2978
2979 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
2980 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
2981 // such entries by figuring out what the address for the global is by looking up this non-STAB
2982 // entry and copying the value into the debug symbol's value to save us the hassle in the
2983 // debug symbol parser.
2984
2985 Symbol *global_symbol = NULL;
2986 for (nlist_idx = 0;
2987 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
2988 nlist_idx++)
2989 {
2990 if (global_symbol->GetAddress().GetFileAddress() == 0)
2991 {
2992 std::vector<uint32_t> indexes;
2993 if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
2994 {
2995 std::vector<uint32_t>::const_iterator pos;
2996 std::vector<uint32_t>::const_iterator end = indexes.end();
2997 for (pos = indexes.begin(); pos != end; ++pos)
2998 {
2999 symbol_ptr = symtab->SymbolAtIndex(*pos);
3000 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
3001 {
3002 global_symbol->GetAddress() = symbol_ptr->GetAddress();
3003 break;
3004 }
3005 }
3006 }
Chris Lattner24943d22010-06-08 16:52:24 +00003007 }
3008 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003009
3010 uint32_t synthetic_sym_id = symtab_load_command.nsyms;
3011
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003012 if (function_starts_count > 0)
3013 {
3014 char synthetic_function_symbol[PATH_MAX];
3015 uint32_t num_synthetic_function_symbols = 0;
3016 for (i=0; i<function_starts_count; ++i)
3017 {
3018 if (function_starts.GetEntryRef (i).data == false)
3019 ++num_synthetic_function_symbols;
3020 }
3021
3022 if (num_synthetic_function_symbols > 0)
3023 {
3024 if (num_syms < sym_idx + num_synthetic_function_symbols)
3025 {
3026 num_syms = sym_idx + num_synthetic_function_symbols;
3027 sym = symtab->Resize (num_syms);
3028 }
3029 uint32_t synthetic_function_symbol_idx = 0;
3030 for (i=0; i<function_starts_count; ++i)
3031 {
3032 const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
3033 if (func_start_entry->data == false)
3034 {
Greg Claytond2653c22012-03-14 01:53:24 +00003035 addr_t symbol_file_addr = func_start_entry->addr;
3036 uint32_t symbol_flags = 0;
3037 if (is_arm)
3038 {
3039 if (symbol_file_addr & 1)
3040 symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
3041 symbol_file_addr &= 0xfffffffffffffffeull;
3042 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003043 Address symbol_addr;
Greg Claytond2653c22012-03-14 01:53:24 +00003044 if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003045 {
3046 SectionSP symbol_section (symbol_addr.GetSection());
3047 uint32_t symbol_byte_size = 0;
3048 if (symbol_section)
3049 {
3050 const addr_t section_file_addr = symbol_section->GetFileAddress();
3051 const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
3052 const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
3053 if (next_func_start_entry)
3054 {
Greg Claytond2653c22012-03-14 01:53:24 +00003055 addr_t next_symbol_file_addr = next_func_start_entry->addr;
3056 if (is_arm)
3057 next_symbol_file_addr &= 0xfffffffffffffffeull;
3058 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 +00003059 }
3060 else
3061 {
Greg Claytond2653c22012-03-14 01:53:24 +00003062 symbol_byte_size = section_end_file_addr - symbol_file_addr;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003063 }
3064 snprintf (synthetic_function_symbol,
3065 sizeof(synthetic_function_symbol),
3066 "___lldb_unnamed_function%u$$%s",
3067 ++synthetic_function_symbol_idx,
3068 module_sp->GetFileSpec().GetFilename().GetCString());
3069 sym[sym_idx].SetID (synthetic_sym_id++);
Greg Claytonc0240042012-07-18 23:18:10 +00003070 sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003071 sym[sym_idx].SetType (eSymbolTypeCode);
3072 sym[sym_idx].SetIsSynthetic (true);
3073 sym[sym_idx].GetAddress() = symbol_addr;
Greg Claytond2653c22012-03-14 01:53:24 +00003074 if (symbol_flags)
3075 sym[sym_idx].SetFlags (symbol_flags);
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003076 if (symbol_byte_size)
3077 sym[sym_idx].SetByteSize (symbol_byte_size);
3078 ++sym_idx;
3079 }
3080 }
3081 }
3082 }
3083 }
3084 }
3085
3086 // Trim our symbols down to just what we ended up with after
3087 // removing any symbols.
3088 if (sym_idx < num_syms)
3089 {
3090 num_syms = sym_idx;
3091 sym = symtab->Resize (num_syms);
3092 }
3093
3094 // Now synthesize indirect symbols
3095 if (m_dysymtab.nindirectsyms != 0)
3096 {
3097 DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
3098
3099 if (indirect_symbol_index_data.GetByteSize())
3100 {
3101 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
3102
3103 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
3104 {
3105 if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
3106 {
3107 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
3108 if (symbol_stub_byte_size == 0)
3109 continue;
3110
3111 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
3112
3113 if (num_symbol_stubs == 0)
3114 continue;
3115
3116 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
3117 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
3118 {
3119 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
3120 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
3121 uint32_t symbol_stub_offset = symbol_stub_index * 4;
3122 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
3123 {
3124 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
3125 if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
3126 continue;
3127
3128 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
3129 Symbol *stub_symbol = NULL;
3130 if (index_pos != end_index_pos)
3131 {
3132 // We have a remapping from the original nlist index to
3133 // a current symbol index, so just look this up by index
3134 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
3135 }
3136 else
3137 {
3138 // We need to lookup a symbol using the original nlist
3139 // symbol index since this index is coming from the
3140 // S_SYMBOL_STUBS
3141 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
3142 }
3143
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003144 if (stub_symbol)
3145 {
3146 Address so_addr(symbol_stub_addr, section_list);
3147
3148 if (stub_symbol->GetType() == eSymbolTypeUndefined)
3149 {
3150 // Change the external symbol into a trampoline that makes sense
3151 // These symbols were N_UNDF N_EXT, and are useless to us, so we
3152 // can re-use them so we don't have to make up a synthetic symbol
3153 // for no good reason.
3154 stub_symbol->SetType (eSymbolTypeTrampoline);
3155 stub_symbol->SetExternal (false);
3156 stub_symbol->GetAddress() = so_addr;
3157 stub_symbol->SetByteSize (symbol_stub_byte_size);
3158 }
3159 else
3160 {
3161 // Make a synthetic symbol to describe the trampoline stub
Jason Molenda2a76fbf2012-04-24 02:09:58 +00003162 Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003163 if (sym_idx >= num_syms)
Jason Molenda2a76fbf2012-04-24 02:09:58 +00003164 {
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003165 sym = symtab->Resize (++num_syms);
Jason Molenda2a76fbf2012-04-24 02:09:58 +00003166 stub_symbol = NULL; // this pointer no longer valid
3167 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003168 sym[sym_idx].SetID (synthetic_sym_id++);
Jason Molenda2a76fbf2012-04-24 02:09:58 +00003169 sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003170 sym[sym_idx].SetType (eSymbolTypeTrampoline);
3171 sym[sym_idx].SetIsSynthetic (true);
3172 sym[sym_idx].GetAddress() = so_addr;
3173 sym[sym_idx].SetByteSize (symbol_stub_byte_size);
3174 ++sym_idx;
3175 }
3176 }
Greg Claytond4330e62012-09-05 01:38:55 +00003177 else
3178 {
3179 if (log)
3180 log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
3181 }
Greg Clayton4aa2edf2012-03-09 04:26:05 +00003182 }
3183 }
3184 }
3185 }
3186 }
3187 }
3188 return symtab->GetNumSymbols();
Chris Lattner24943d22010-06-08 16:52:24 +00003189 }
3190 return 0;
3191}
3192
3193
3194void
3195ObjectFileMachO::Dump (Stream *s)
3196{
Greg Clayton9482f052012-03-13 23:14:29 +00003197 ModuleSP module_sp(GetModule());
3198 if (module_sp)
3199 {
3200 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3201 s->Printf("%p: ", this);
3202 s->Indent();
3203 if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped)
3204 s->PutCString("ObjectFileMachO64");
3205 else
3206 s->PutCString("ObjectFileMachO32");
Chris Lattner24943d22010-06-08 16:52:24 +00003207
Greg Clayton9482f052012-03-13 23:14:29 +00003208 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +00003209
Greg Clayton9482f052012-03-13 23:14:29 +00003210 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner24943d22010-06-08 16:52:24 +00003211
Greg Clayton9482f052012-03-13 23:14:29 +00003212 if (m_sections_ap.get())
3213 m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00003214
Greg Clayton9482f052012-03-13 23:14:29 +00003215 if (m_symtab_ap.get())
3216 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
3217 }
Chris Lattner24943d22010-06-08 16:52:24 +00003218}
3219
3220
3221bool
Greg Clayton0467c782011-02-04 18:53:10 +00003222ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner24943d22010-06-08 16:52:24 +00003223{
Greg Clayton9482f052012-03-13 23:14:29 +00003224 ModuleSP module_sp(GetModule());
3225 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00003226 {
Greg Clayton9482f052012-03-13 23:14:29 +00003227 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3228 struct uuid_command load_cmd;
3229 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3230 uint32_t i;
3231 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00003232 {
Greg Clayton9482f052012-03-13 23:14:29 +00003233 const uint32_t cmd_offset = offset;
3234 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
3235 break;
3236
3237 if (load_cmd.cmd == LoadCommandUUID)
Chris Lattner24943d22010-06-08 16:52:24 +00003238 {
Greg Clayton9482f052012-03-13 23:14:29 +00003239 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
Sean Callanana5689d52012-07-12 18:04:03 +00003240
Greg Clayton9482f052012-03-13 23:14:29 +00003241 if (uuid_bytes)
3242 {
Sean Callanana5689d52012-07-12 18:04:03 +00003243 // OpenCL on Mac OS X uses the same UUID for each of its object files.
3244 // We pretend these object files have no UUID to prevent crashing.
3245
3246 const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
3247 0x3b, 0xa8,
3248 0x4b, 0x16,
3249 0xb6, 0xa4,
3250 0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
3251
3252 if (!memcmp(uuid_bytes, opencl_uuid, 16))
3253 return false;
3254
Greg Clayton9482f052012-03-13 23:14:29 +00003255 uuid->SetBytes (uuid_bytes);
3256 return true;
3257 }
3258 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00003259 }
Greg Clayton9482f052012-03-13 23:14:29 +00003260 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00003261 }
Chris Lattner24943d22010-06-08 16:52:24 +00003262 }
3263 return false;
3264}
3265
3266
3267uint32_t
3268ObjectFileMachO::GetDependentModules (FileSpecList& files)
3269{
Chris Lattner24943d22010-06-08 16:52:24 +00003270 uint32_t count = 0;
Greg Clayton9482f052012-03-13 23:14:29 +00003271 ModuleSP module_sp(GetModule());
3272 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00003273 {
Greg Clayton9482f052012-03-13 23:14:29 +00003274 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3275 struct load_command load_cmd;
3276 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3277 const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
3278 uint32_t i;
3279 for (i=0; i<m_header.ncmds; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00003280 {
Greg Clayton9482f052012-03-13 23:14:29 +00003281 const uint32_t cmd_offset = offset;
3282 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
3283 break;
Chris Lattner24943d22010-06-08 16:52:24 +00003284
Greg Clayton9482f052012-03-13 23:14:29 +00003285 switch (load_cmd.cmd)
3286 {
3287 case LoadCommandDylibLoad:
3288 case LoadCommandDylibLoadWeak:
3289 case LoadCommandDylibReexport:
3290 case LoadCommandDynamicLinkerLoad:
3291 case LoadCommandFixedVMShlibLoad:
3292 case LoadCommandDylibLoadUpward:
3293 {
3294 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
3295 const char *path = m_data.PeekCStr(name_offset);
3296 // Skip any path that starts with '@' since these are usually:
3297 // @executable_path/.../file
3298 // @rpath/.../file
3299 if (path && path[0] != '@')
3300 {
3301 FileSpec file_spec(path, resolve_path);
3302 if (files.AppendIfUnique(file_spec))
3303 count++;
3304 }
3305 }
3306 break;
3307
3308 default:
3309 break;
3310 }
3311 offset = cmd_offset + load_cmd.cmdsize;
Chris Lattner24943d22010-06-08 16:52:24 +00003312 }
Chris Lattner24943d22010-06-08 16:52:24 +00003313 }
3314 return count;
3315}
3316
Jim Ingham28775942011-03-07 23:44:08 +00003317lldb_private::Address
3318ObjectFileMachO::GetEntryPointAddress ()
3319{
3320 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
3321 // is initialized to an invalid address, so we can just return that.
3322 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
3323
3324 if (!IsExecutable() || m_entry_point_address.IsValid())
3325 return m_entry_point_address;
3326
3327 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
3328 // /usr/include/mach-o.h, but it is basically:
3329 //
3330 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
3331 // uint32_t count - this is the count of longs in the thread state data
3332 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
3333 // <repeat this trio>
3334 //
3335 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
3336 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
3337 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
3338 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
3339 //
3340 // For now we hard-code the offsets and flavors we need:
3341 //
3342 //
3343
Greg Clayton9482f052012-03-13 23:14:29 +00003344 ModuleSP module_sp(GetModule());
3345 if (module_sp)
Jim Ingham28775942011-03-07 23:44:08 +00003346 {
Greg Clayton9482f052012-03-13 23:14:29 +00003347 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3348 struct load_command load_cmd;
3349 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3350 uint32_t i;
3351 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
3352 bool done = false;
3353
3354 for (i=0; i<m_header.ncmds; ++i)
Jim Ingham28775942011-03-07 23:44:08 +00003355 {
Greg Clayton9482f052012-03-13 23:14:29 +00003356 const uint32_t cmd_offset = offset;
3357 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
3358 break;
3359
3360 switch (load_cmd.cmd)
Jim Ingham28775942011-03-07 23:44:08 +00003361 {
Greg Clayton9482f052012-03-13 23:14:29 +00003362 case LoadCommandUnixThread:
3363 case LoadCommandThread:
Jim Ingham28775942011-03-07 23:44:08 +00003364 {
Greg Clayton9482f052012-03-13 23:14:29 +00003365 while (offset < cmd_offset + load_cmd.cmdsize)
Jim Ingham28775942011-03-07 23:44:08 +00003366 {
Greg Clayton9482f052012-03-13 23:14:29 +00003367 uint32_t flavor = m_data.GetU32(&offset);
3368 uint32_t count = m_data.GetU32(&offset);
3369 if (count == 0)
3370 {
3371 // We've gotten off somehow, log and exit;
3372 return m_entry_point_address;
Jim Ingham28775942011-03-07 23:44:08 +00003373 }
Greg Clayton9482f052012-03-13 23:14:29 +00003374
3375 switch (m_header.cputype)
3376 {
3377 case llvm::MachO::CPUTypeARM:
3378 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
3379 {
3380 offset += 60; // This is the offset of pc in the GPR thread state data structure.
3381 start_address = m_data.GetU32(&offset);
3382 done = true;
3383 }
Jim Ingham28775942011-03-07 23:44:08 +00003384 break;
Greg Clayton9482f052012-03-13 23:14:29 +00003385 case llvm::MachO::CPUTypeI386:
3386 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
3387 {
3388 offset += 40; // This is the offset of eip in the GPR thread state data structure.
3389 start_address = m_data.GetU32(&offset);
3390 done = true;
3391 }
3392 break;
3393 case llvm::MachO::CPUTypeX86_64:
3394 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
3395 {
3396 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
3397 start_address = m_data.GetU64(&offset);
3398 done = true;
3399 }
3400 break;
3401 default:
3402 return m_entry_point_address;
3403 }
3404 // Haven't found the GPR flavor yet, skip over the data for this flavor:
3405 if (done)
3406 break;
3407 offset += count * 4;
3408 }
Jim Ingham28775942011-03-07 23:44:08 +00003409 }
Greg Clayton9482f052012-03-13 23:14:29 +00003410 break;
3411 case LoadCommandMain:
Sean Callanan6e12c7a2012-03-08 02:39:03 +00003412 {
Greg Clayton9482f052012-03-13 23:14:29 +00003413 ConstString text_segment_name ("__TEXT");
3414 uint64_t entryoffset = m_data.GetU64(&offset);
3415 SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
3416 if (text_segment_sp)
3417 {
3418 done = true;
3419 start_address = text_segment_sp->GetFileAddress() + entryoffset;
3420 }
Sean Callanan6e12c7a2012-03-08 02:39:03 +00003421 }
Greg Clayton9482f052012-03-13 23:14:29 +00003422
3423 default:
3424 break;
Sean Callanan6e12c7a2012-03-08 02:39:03 +00003425 }
Greg Clayton9482f052012-03-13 23:14:29 +00003426 if (done)
3427 break;
Jim Ingham28775942011-03-07 23:44:08 +00003428
Greg Clayton9482f052012-03-13 23:14:29 +00003429 // Go to the next load command:
3430 offset = cmd_offset + load_cmd.cmdsize;
Jim Ingham28775942011-03-07 23:44:08 +00003431 }
Jim Ingham28775942011-03-07 23:44:08 +00003432
Greg Clayton9482f052012-03-13 23:14:29 +00003433 if (start_address != LLDB_INVALID_ADDRESS)
Greg Clayton3508c382012-02-24 01:59:29 +00003434 {
Greg Clayton9482f052012-03-13 23:14:29 +00003435 // We got the start address from the load commands, so now resolve that address in the sections
3436 // of this ObjectFile:
3437 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
Greg Clayton3508c382012-02-24 01:59:29 +00003438 {
Greg Clayton9482f052012-03-13 23:14:29 +00003439 m_entry_point_address.Clear();
3440 }
3441 }
3442 else
3443 {
3444 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
3445 // "start" symbol in the main executable.
3446
3447 ModuleSP module_sp (GetModule());
3448
3449 if (module_sp)
3450 {
3451 SymbolContextList contexts;
3452 SymbolContext context;
3453 if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
3454 {
3455 if (contexts.GetContextAtIndex(0, context))
3456 m_entry_point_address = context.symbol->GetAddress();
3457 }
Greg Clayton3508c382012-02-24 01:59:29 +00003458 }
3459 }
Jim Ingham28775942011-03-07 23:44:08 +00003460 }
3461
3462 return m_entry_point_address;
3463
3464}
3465
Greg Claytonb5a8f142012-02-05 02:38:54 +00003466lldb_private::Address
3467ObjectFileMachO::GetHeaderAddress ()
3468{
3469 lldb_private::Address header_addr;
3470 SectionList *section_list = GetSectionList();
3471 if (section_list)
3472 {
3473 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
3474 if (text_segment_sp)
3475 {
Greg Clayton3508c382012-02-24 01:59:29 +00003476 header_addr.SetSection (text_segment_sp);
Greg Claytonb5a8f142012-02-05 02:38:54 +00003477 header_addr.SetOffset (0);
3478 }
3479 }
3480 return header_addr;
3481}
3482
Greg Clayton46c9a352012-02-09 06:16:32 +00003483uint32_t
3484ObjectFileMachO::GetNumThreadContexts ()
3485{
Greg Clayton9482f052012-03-13 23:14:29 +00003486 ModuleSP module_sp(GetModule());
3487 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00003488 {
Greg Clayton9482f052012-03-13 23:14:29 +00003489 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3490 if (!m_thread_context_offsets_valid)
Greg Clayton46c9a352012-02-09 06:16:32 +00003491 {
Greg Clayton9482f052012-03-13 23:14:29 +00003492 m_thread_context_offsets_valid = true;
3493 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3494 FileRangeArray::Entry file_range;
3495 thread_command thread_cmd;
3496 for (uint32_t i=0; i<m_header.ncmds; ++i)
Greg Clayton46c9a352012-02-09 06:16:32 +00003497 {
Greg Clayton9482f052012-03-13 23:14:29 +00003498 const uint32_t cmd_offset = offset;
3499 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
3500 break;
3501
3502 if (thread_cmd.cmd == LoadCommandThread)
3503 {
3504 file_range.SetRangeBase (offset);
3505 file_range.SetByteSize (thread_cmd.cmdsize - 8);
3506 m_thread_context_offsets.Append (file_range);
3507 }
3508 offset = cmd_offset + thread_cmd.cmdsize;
Greg Clayton46c9a352012-02-09 06:16:32 +00003509 }
Greg Clayton46c9a352012-02-09 06:16:32 +00003510 }
3511 }
3512 return m_thread_context_offsets.GetSize();
3513}
3514
3515lldb::RegisterContextSP
3516ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
3517{
Greg Clayton46c9a352012-02-09 06:16:32 +00003518 lldb::RegisterContextSP reg_ctx_sp;
Greg Clayton9ce95382012-02-13 23:10:39 +00003519
Greg Clayton9482f052012-03-13 23:14:29 +00003520 ModuleSP module_sp(GetModule());
3521 if (module_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +00003522 {
Greg Clayton9482f052012-03-13 23:14:29 +00003523 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3524 if (!m_thread_context_offsets_valid)
3525 GetNumThreadContexts ();
3526
3527 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
3528
3529 DataExtractor data (m_data,
3530 thread_context_file_range->GetRangeBase(),
3531 thread_context_file_range->GetByteSize());
3532
3533 switch (m_header.cputype)
3534 {
3535 case llvm::MachO::CPUTypeARM:
3536 reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
3537 break;
3538
3539 case llvm::MachO::CPUTypeI386:
3540 reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
3541 break;
3542
3543 case llvm::MachO::CPUTypeX86_64:
3544 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
3545 break;
3546 }
Greg Clayton46c9a352012-02-09 06:16:32 +00003547 }
3548 return reg_ctx_sp;
3549}
3550
Greg Claytonb5a8f142012-02-05 02:38:54 +00003551
Greg Claytonca319972011-07-09 00:41:34 +00003552ObjectFile::Type
3553ObjectFileMachO::CalculateType()
3554{
3555 switch (m_header.filetype)
3556 {
3557 case HeaderFileTypeObject: // 0x1u MH_OBJECT
3558 if (GetAddressByteSize () == 4)
3559 {
3560 // 32 bit kexts are just object files, but they do have a valid
3561 // UUID load command.
3562 UUID uuid;
3563 if (GetUUID(&uuid))
3564 {
3565 // this checking for the UUID load command is not enough
3566 // we could eventually look for the symbol named
3567 // "OSKextGetCurrentIdentifier" as this is required of kexts
3568 if (m_strata == eStrataInvalid)
3569 m_strata = eStrataKernel;
3570 return eTypeSharedLibrary;
3571 }
3572 }
3573 return eTypeObjectFile;
3574
3575 case HeaderFileTypeExecutable: return eTypeExecutable; // 0x2u MH_EXECUTE
3576 case HeaderFileTypeFixedVMShlib: return eTypeSharedLibrary; // 0x3u MH_FVMLIB
3577 case HeaderFileTypeCore: return eTypeCoreFile; // 0x4u MH_CORE
3578 case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary; // 0x5u MH_PRELOAD
3579 case HeaderFileTypeDynamicShlib: return eTypeSharedLibrary; // 0x6u MH_DYLIB
3580 case HeaderFileTypeDynamicLinkEditor: return eTypeDynamicLinker; // 0x7u MH_DYLINKER
3581 case HeaderFileTypeBundle: return eTypeSharedLibrary; // 0x8u MH_BUNDLE
3582 case HeaderFileTypeDynamicShlibStub: return eTypeStubLibrary; // 0x9u MH_DYLIB_STUB
3583 case HeaderFileTypeDSYM: return eTypeDebugInfo; // 0xAu MH_DSYM
3584 case HeaderFileTypeKextBundle: return eTypeSharedLibrary; // 0xBu MH_KEXT_BUNDLE
3585 default:
3586 break;
3587 }
3588 return eTypeUnknown;
3589}
3590
3591ObjectFile::Strata
3592ObjectFileMachO::CalculateStrata()
3593{
3594 switch (m_header.filetype)
3595 {
3596 case HeaderFileTypeObject: // 0x1u MH_OBJECT
3597 {
3598 // 32 bit kexts are just object files, but they do have a valid
3599 // UUID load command.
3600 UUID uuid;
3601 if (GetUUID(&uuid))
3602 {
3603 // this checking for the UUID load command is not enough
3604 // we could eventually look for the symbol named
3605 // "OSKextGetCurrentIdentifier" as this is required of kexts
3606 if (m_type == eTypeInvalid)
3607 m_type = eTypeSharedLibrary;
3608
3609 return eStrataKernel;
3610 }
3611 }
3612 return eStrataUnknown;
3613
3614 case HeaderFileTypeExecutable: // 0x2u MH_EXECUTE
3615 // Check for the MH_DYLDLINK bit in the flags
3616 if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
Sean Callananac725af2012-02-10 20:22:35 +00003617 {
Greg Claytonca319972011-07-09 00:41:34 +00003618 return eStrataUser;
Sean Callananac725af2012-02-10 20:22:35 +00003619 }
3620 else
3621 {
3622 SectionList *section_list = GetSectionList();
3623 if (section_list)
3624 {
3625 static ConstString g_kld_section_name ("__KLD");
3626 if (section_list->FindSectionByName(g_kld_section_name))
3627 return eStrataKernel;
3628 }
3629 }
3630 return eStrataRawImage;
Greg Claytonca319972011-07-09 00:41:34 +00003631
3632 case HeaderFileTypeFixedVMShlib: return eStrataUser; // 0x3u MH_FVMLIB
3633 case HeaderFileTypeCore: return eStrataUnknown; // 0x4u MH_CORE
Sean Callananac725af2012-02-10 20:22:35 +00003634 case HeaderFileTypePreloadedExecutable: return eStrataRawImage; // 0x5u MH_PRELOAD
Greg Claytonca319972011-07-09 00:41:34 +00003635 case HeaderFileTypeDynamicShlib: return eStrataUser; // 0x6u MH_DYLIB
3636 case HeaderFileTypeDynamicLinkEditor: return eStrataUser; // 0x7u MH_DYLINKER
3637 case HeaderFileTypeBundle: return eStrataUser; // 0x8u MH_BUNDLE
3638 case HeaderFileTypeDynamicShlibStub: return eStrataUser; // 0x9u MH_DYLIB_STUB
3639 case HeaderFileTypeDSYM: return eStrataUnknown; // 0xAu MH_DSYM
3640 case HeaderFileTypeKextBundle: return eStrataKernel; // 0xBu MH_KEXT_BUNDLE
3641 default:
3642 break;
3643 }
3644 return eStrataUnknown;
3645}
3646
3647
Greg Clayton49f4bf22012-02-22 19:41:02 +00003648uint32_t
3649ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
3650{
Greg Clayton9482f052012-03-13 23:14:29 +00003651 ModuleSP module_sp(GetModule());
3652 if (module_sp)
Greg Clayton49f4bf22012-02-22 19:41:02 +00003653 {
Greg Clayton9482f052012-03-13 23:14:29 +00003654 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3655 struct dylib_command load_cmd;
3656 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
3657 uint32_t version_cmd = 0;
3658 uint64_t version = 0;
3659 uint32_t i;
3660 for (i=0; i<m_header.ncmds; ++i)
Greg Clayton49f4bf22012-02-22 19:41:02 +00003661 {
Greg Clayton9482f052012-03-13 23:14:29 +00003662 const uint32_t cmd_offset = offset;
3663 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
3664 break;
3665
3666 if (load_cmd.cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00003667 {
Greg Clayton9482f052012-03-13 23:14:29 +00003668 if (version_cmd == 0)
3669 {
3670 version_cmd = load_cmd.cmd;
3671 if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
3672 break;
3673 version = load_cmd.dylib.current_version;
3674 }
3675 break; // Break for now unless there is another more complete version
3676 // number load command in the future.
Greg Clayton49f4bf22012-02-22 19:41:02 +00003677 }
Greg Clayton9482f052012-03-13 23:14:29 +00003678 offset = cmd_offset + load_cmd.cmdsize;
Greg Clayton49f4bf22012-02-22 19:41:02 +00003679 }
Greg Clayton9482f052012-03-13 23:14:29 +00003680
3681 if (version_cmd == LoadCommandDylibIdent)
Greg Clayton49f4bf22012-02-22 19:41:02 +00003682 {
Greg Clayton9482f052012-03-13 23:14:29 +00003683 if (versions != NULL && num_versions > 0)
3684 {
3685 if (num_versions > 0)
3686 versions[0] = (version & 0xFFFF0000ull) >> 16;
3687 if (num_versions > 1)
3688 versions[1] = (version & 0x0000FF00ull) >> 8;
3689 if (num_versions > 2)
3690 versions[2] = (version & 0x000000FFull);
3691 // Fill in an remaining version numbers with invalid values
3692 for (i=3; i<num_versions; ++i)
3693 versions[i] = UINT32_MAX;
3694 }
3695 // The LC_ID_DYLIB load command has a version with 3 version numbers
3696 // in it, so always return 3
3697 return 3;
Greg Clayton49f4bf22012-02-22 19:41:02 +00003698 }
Greg Clayton49f4bf22012-02-22 19:41:02 +00003699 }
3700 return false;
3701}
3702
Chris Lattner24943d22010-06-08 16:52:24 +00003703bool
Greg Clayton395fc332011-02-15 21:59:32 +00003704ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +00003705{
Greg Clayton9482f052012-03-13 23:14:29 +00003706 ModuleSP module_sp(GetModule());
3707 if (module_sp)
Greg Clayton6a64bbf2011-09-21 03:57:31 +00003708 {
Greg Clayton9482f052012-03-13 23:14:29 +00003709 lldb_private::Mutex::Locker locker(module_sp->GetMutex());
3710 arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
3711
3712 // Files with type MH_PRELOAD are currently used in cases where the image
3713 // debugs at the addresses in the file itself. Below we set the OS to
3714 // unknown to make sure we use the DynamicLoaderStatic()...
3715 if (m_header.filetype == HeaderFileTypePreloadedExecutable)
3716 {
3717 arch.GetTriple().setOS (llvm::Triple::UnknownOS);
3718 }
3719 return true;
Greg Clayton6a64bbf2011-09-21 03:57:31 +00003720 }
Greg Clayton9482f052012-03-13 23:14:29 +00003721 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00003722}
3723
3724
3725//------------------------------------------------------------------
3726// PluginInterface protocol
3727//------------------------------------------------------------------
3728const char *
3729ObjectFileMachO::GetPluginName()
3730{
3731 return "ObjectFileMachO";
3732}
3733
3734const char *
3735ObjectFileMachO::GetShortPluginName()
3736{
3737 return GetPluginNameStatic();
3738}
3739
3740uint32_t
3741ObjectFileMachO::GetPluginVersion()
3742{
3743 return 1;
3744}
3745