blob: 67fe1e4e66f5c2f321c4f88c2d2842e891981277 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ObjectFileMachO.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Greg Clayton3f69eac2011-12-03 02:30:59 +000010#include "llvm/ADT/StringRef.h"
Jim Ingham28775942011-03-07 23:44:08 +000011#include "llvm/Support/MachO.h"
12
Chris Lattner24943d22010-06-08 16:52:24 +000013#include "ObjectFileMachO.h"
14
Chris Lattner24943d22010-06-08 16:52:24 +000015#include "lldb/Core/ArchSpec.h"
16#include "lldb/Core/DataBuffer.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/FileSpecList.h"
18#include "lldb/Core/Module.h"
19#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/Section.h"
21#include "lldb/Core/StreamFile.h"
22#include "lldb/Core/StreamString.h"
23#include "lldb/Core/Timer.h"
24#include "lldb/Core/UUID.h"
Greg Claytondf6dc882012-01-05 03:57:59 +000025#include "lldb/Host/Host.h"
26#include "lldb/Host/FileSpec.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000027#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Symbol/ObjectFile.h"
Greg Claytonb5a8f142012-02-05 02:38:54 +000029#include "lldb/Target/Process.h"
Greg Clayton46c9a352012-02-09 06:16:32 +000030#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031
Chris Lattner24943d22010-06-08 16:52:24 +000032
33using namespace lldb;
34using namespace lldb_private;
Greg Clayton1674b122010-07-21 22:12:05 +000035using namespace llvm::MachO;
Chris Lattner24943d22010-06-08 16:52:24 +000036
Greg Clayton46c9a352012-02-09 06:16:32 +000037class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
38{
39public:
40 RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
41 RegisterContextDarwin_x86_64 (thread, 0)
42 {
43 SetRegisterDataFrom_LC_THREAD (data);
44 }
45
46 virtual void
47 InvalidateAllRegisters ()
48 {
49 // Do nothing... registers are always valid...
50 }
51
52 void
53 SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
54 {
55 int flavor;
56 uint32_t offset = 0;
57 SetError (GPRRegSet, Read, -1);
58 SetError (FPURegSet, Read, -1);
59 SetError (EXCRegSet, Read, -1);
60 while ((flavor = data.GetU32 (&offset)) > 0)
61 {
62 uint32_t i;
63 uint32_t count = data.GetU32 (&offset);
64 switch (flavor)
65 {
66 case 7:
67 case 8:
68 case 9:
69 // Goofy extra flavor inside state...
70 flavor = data.GetU32 (&offset);
71 count = data.GetU32 (&offset);
72 default:
73 break;
74 }
75
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 break;
83 case FPURegSet:
84 // TODO: fill in FPU regs....
85 //SetError (FPURegSet, Read, -1);
86 break;
87 case EXCRegSet:
88 exc.trapno = data.GetU32(&offset);
89 exc.err = data.GetU32(&offset);
90 exc.faultvaddr = data.GetU64(&offset);
91 SetError (EXCRegSet, Read, 0);
92 break;
93 }
94 }
95 }
96protected:
97 virtual int
98 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
99 {
100 return 0;
101 }
102
103 virtual int
104 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
105 {
106 return 0;
107 }
108
109 virtual int
110 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
111 {
112 return 0;
113 }
114
115 virtual int
116 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
117 {
118 return 0;
119 }
120
121 virtual int
122 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
123 {
124 return 0;
125 }
126
127 virtual int
128 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
129 {
130 return 0;
131 }
132};
133
Greg Claytonb1888f22011-03-19 01:12:21 +0000134#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
Chris Lattner24943d22010-06-08 16:52:24 +0000135
136void
137ObjectFileMachO::Initialize()
138{
139 PluginManager::RegisterPlugin (GetPluginNameStatic(),
140 GetPluginDescriptionStatic(),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000141 CreateInstance,
142 CreateMemoryInstance);
Chris Lattner24943d22010-06-08 16:52:24 +0000143}
144
145void
146ObjectFileMachO::Terminate()
147{
148 PluginManager::UnregisterPlugin (CreateInstance);
149}
150
151
152const char *
153ObjectFileMachO::GetPluginNameStatic()
154{
155 return "object-file.mach-o";
156}
157
158const char *
159ObjectFileMachO::GetPluginDescriptionStatic()
160{
161 return "Mach-o object file reader (32 and 64 bit)";
162}
163
164
165ObjectFile *
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000166ObjectFileMachO::CreateInstance (Module* module, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length)
Chris Lattner24943d22010-06-08 16:52:24 +0000167{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000168 if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length))
Chris Lattner24943d22010-06-08 16:52:24 +0000169 {
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000170 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module, data_sp, file, offset, length));
Chris Lattner24943d22010-06-08 16:52:24 +0000171 if (objfile_ap.get() && objfile_ap->ParseHeader())
172 return objfile_ap.release();
173 }
174 return NULL;
175}
176
Greg Claytonb5a8f142012-02-05 02:38:54 +0000177ObjectFile *
178ObjectFileMachO::CreateMemoryInstance (Module* module,
179 DataBufferSP& data_sp,
180 const ProcessSP &process_sp,
181 lldb::addr_t header_addr)
182{
183 if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
184 {
185 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module, data_sp, process_sp, header_addr));
186 if (objfile_ap.get() && objfile_ap->ParseHeader())
187 return objfile_ap.release();
188 }
189 return NULL;
190}
191
192
193const ConstString &
194ObjectFileMachO::GetSegmentNameTEXT()
195{
196 static ConstString g_segment_name_TEXT ("__TEXT");
197 return g_segment_name_TEXT;
198}
199
200const ConstString &
201ObjectFileMachO::GetSegmentNameDATA()
202{
203 static ConstString g_segment_name_DATA ("__DATA");
204 return g_segment_name_DATA;
205}
206
207const ConstString &
208ObjectFileMachO::GetSegmentNameOBJC()
209{
210 static ConstString g_segment_name_OBJC ("__OBJC");
211 return g_segment_name_OBJC;
212}
213
214const ConstString &
215ObjectFileMachO::GetSegmentNameLINKEDIT()
216{
217 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
218 return g_section_name_LINKEDIT;
219}
220
221const ConstString &
222ObjectFileMachO::GetSectionNameEHFrame()
223{
224 static ConstString g_section_name_eh_frame ("__eh_frame");
225 return g_section_name_eh_frame;
226}
227
228
Chris Lattner24943d22010-06-08 16:52:24 +0000229
230static uint32_t
231MachHeaderSizeFromMagic(uint32_t magic)
232{
233 switch (magic)
234 {
Greg Clayton1674b122010-07-21 22:12:05 +0000235 case HeaderMagic32:
236 case HeaderMagic32Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000237 return sizeof(struct mach_header);
238
Greg Clayton1674b122010-07-21 22:12:05 +0000239 case HeaderMagic64:
240 case HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000241 return sizeof(struct mach_header_64);
242 break;
243
244 default:
245 break;
246 }
247 return 0;
248}
249
250
251bool
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000252ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
253 lldb::addr_t data_offset,
254 lldb::addr_t data_length)
Chris Lattner24943d22010-06-08 16:52:24 +0000255{
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000256 DataExtractor data;
257 data.SetData (data_sp, data_offset, data_length);
Chris Lattner24943d22010-06-08 16:52:24 +0000258 uint32_t offset = 0;
259 uint32_t magic = data.GetU32(&offset);
260 return MachHeaderSizeFromMagic(magic) != 0;
261}
262
263
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000264ObjectFileMachO::ObjectFileMachO(Module* module, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) :
265 ObjectFile(module, file, offset, length, data_sp),
Chris Lattner24943d22010-06-08 16:52:24 +0000266 m_mutex (Mutex::eMutexTypeRecursive),
Chris Lattner24943d22010-06-08 16:52:24 +0000267 m_sections_ap(),
Jim Ingham28775942011-03-07 23:44:08 +0000268 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000269 m_mach_segments(),
270 m_mach_sections(),
271 m_entry_point_address(),
272 m_thread_context_offsets(),
273 m_thread_context_offsets_valid(false)
Chris Lattner24943d22010-06-08 16:52:24 +0000274{
Greg Claytonddff7cc2011-02-04 21:13:05 +0000275 ::memset (&m_header, 0, sizeof(m_header));
276 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
Chris Lattner24943d22010-06-08 16:52:24 +0000277}
278
Greg Claytonb5a8f142012-02-05 02:38:54 +0000279ObjectFileMachO::ObjectFileMachO (lldb_private::Module* module,
280 lldb::DataBufferSP& header_data_sp,
281 const lldb::ProcessSP &process_sp,
282 lldb::addr_t header_addr) :
283 ObjectFile(module, process_sp, header_addr, header_data_sp),
284 m_mutex (Mutex::eMutexTypeRecursive),
Greg Claytonb5a8f142012-02-05 02:38:54 +0000285 m_sections_ap(),
286 m_symtab_ap(),
Greg Clayton46c9a352012-02-09 06:16:32 +0000287 m_mach_segments(),
288 m_mach_sections(),
289 m_entry_point_address(),
290 m_thread_context_offsets(),
291 m_thread_context_offsets_valid(false)
Greg Claytonb5a8f142012-02-05 02:38:54 +0000292{
293 ::memset (&m_header, 0, sizeof(m_header));
294 ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
295}
Chris Lattner24943d22010-06-08 16:52:24 +0000296
297ObjectFileMachO::~ObjectFileMachO()
298{
299}
300
301
302bool
303ObjectFileMachO::ParseHeader ()
304{
305 lldb_private::Mutex::Locker locker(m_mutex);
306 bool can_parse = false;
307 uint32_t offset = 0;
Greg Claytoncd548032011-02-01 01:31:41 +0000308 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000309 // Leave magic in the original byte order
310 m_header.magic = m_data.GetU32(&offset);
311 switch (m_header.magic)
312 {
Greg Clayton1674b122010-07-21 22:12:05 +0000313 case HeaderMagic32:
Greg Claytoncd548032011-02-01 01:31:41 +0000314 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000315 m_data.SetAddressByteSize(4);
316 can_parse = true;
317 break;
318
Greg Clayton1674b122010-07-21 22:12:05 +0000319 case HeaderMagic64:
Greg Claytoncd548032011-02-01 01:31:41 +0000320 m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +0000321 m_data.SetAddressByteSize(8);
322 can_parse = true;
323 break;
324
Greg Clayton1674b122010-07-21 22:12:05 +0000325 case HeaderMagic32Swapped:
Greg Claytoncd548032011-02-01 01:31:41 +0000326 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Chris Lattner24943d22010-06-08 16:52:24 +0000327 m_data.SetAddressByteSize(4);
328 can_parse = true;
329 break;
330
Greg Clayton1674b122010-07-21 22:12:05 +0000331 case HeaderMagic64Swapped:
Greg Claytoncd548032011-02-01 01:31:41 +0000332 m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
Chris Lattner24943d22010-06-08 16:52:24 +0000333 m_data.SetAddressByteSize(8);
334 can_parse = true;
335 break;
336
337 default:
338 break;
339 }
340
341 if (can_parse)
342 {
343 m_data.GetU32(&offset, &m_header.cputype, 6);
344
Greg Claytoncf015052010-06-11 03:25:34 +0000345 ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Jim Ingham7508e732010-08-09 23:31:02 +0000346
347 if (SetModulesArchitecture (mach_arch))
Greg Claytonb5a8f142012-02-05 02:38:54 +0000348 {
349 const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
350 if (m_data.GetByteSize() < header_and_lc_size)
351 {
352 DataBufferSP data_sp;
353 ProcessSP process_sp (m_process_wp.lock());
354 if (process_sp)
355 {
356 data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
357 }
358 else
359 {
360 // Read in all only the load command data from the file on disk
361 data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
362 if (data_sp->GetByteSize() != header_and_lc_size)
363 return false;
364 }
365 if (data_sp)
366 m_data.SetData (data_sp);
367 }
368 }
369 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000370 }
371 else
372 {
373 memset(&m_header, 0, sizeof(struct mach_header));
374 }
375 return false;
376}
377
378
379ByteOrder
380ObjectFileMachO::GetByteOrder () const
381{
382 lldb_private::Mutex::Locker locker(m_mutex);
383 return m_data.GetByteOrder ();
384}
385
Jim Ingham7508e732010-08-09 23:31:02 +0000386bool
387ObjectFileMachO::IsExecutable() const
388{
389 return m_header.filetype == HeaderFileTypeExecutable;
390}
Chris Lattner24943d22010-06-08 16:52:24 +0000391
392size_t
393ObjectFileMachO::GetAddressByteSize () const
394{
395 lldb_private::Mutex::Locker locker(m_mutex);
396 return m_data.GetAddressByteSize ();
397}
398
Greg Claytonb3448432011-03-24 21:19:54 +0000399AddressClass
Greg Claytonb1888f22011-03-19 01:12:21 +0000400ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
401{
402 Symtab *symtab = GetSymtab();
403 if (symtab)
404 {
405 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
406 if (symbol)
407 {
408 const AddressRange *range_ptr = symbol->GetAddressRangePtr();
409 if (range_ptr)
410 {
411 const Section *section = range_ptr->GetBaseAddress().GetSection();
412 if (section)
413 {
Greg Claytonb3448432011-03-24 21:19:54 +0000414 const SectionType section_type = section->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000415 switch (section_type)
416 {
417 case eSectionTypeInvalid: return eAddressClassUnknown;
418 case eSectionTypeCode:
419 if (m_header.cputype == llvm::MachO::CPUTypeARM)
420 {
421 // For ARM we have a bit in the n_desc field of the symbol
422 // that tells us ARM/Thumb which is bit 0x0008.
423 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
424 return eAddressClassCodeAlternateISA;
425 }
426 return eAddressClassCode;
427
428 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000429 case eSectionTypeData:
430 case eSectionTypeDataCString:
431 case eSectionTypeDataCStringPointers:
432 case eSectionTypeDataSymbolAddress:
433 case eSectionTypeData4:
434 case eSectionTypeData8:
435 case eSectionTypeData16:
436 case eSectionTypeDataPointers:
437 case eSectionTypeZeroFill:
438 case eSectionTypeDataObjCMessageRefs:
439 case eSectionTypeDataObjCCFStrings:
440 return eAddressClassData;
441 case eSectionTypeDebug:
442 case eSectionTypeDWARFDebugAbbrev:
443 case eSectionTypeDWARFDebugAranges:
444 case eSectionTypeDWARFDebugFrame:
445 case eSectionTypeDWARFDebugInfo:
446 case eSectionTypeDWARFDebugLine:
447 case eSectionTypeDWARFDebugLoc:
448 case eSectionTypeDWARFDebugMacInfo:
449 case eSectionTypeDWARFDebugPubNames:
450 case eSectionTypeDWARFDebugPubTypes:
451 case eSectionTypeDWARFDebugRanges:
452 case eSectionTypeDWARFDebugStr:
453 case eSectionTypeDWARFAppleNames:
454 case eSectionTypeDWARFAppleTypes:
455 case eSectionTypeDWARFAppleNamespaces:
456 case eSectionTypeDWARFAppleObjC:
457 return eAddressClassDebug;
Greg Claytonb1888f22011-03-19 01:12:21 +0000458 case eSectionTypeEHFrame: return eAddressClassRuntime;
459 case eSectionTypeOther: return eAddressClassUnknown;
460 }
461 }
462 }
463
Greg Claytonb3448432011-03-24 21:19:54 +0000464 const SymbolType symbol_type = symbol->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000465 switch (symbol_type)
466 {
467 case eSymbolTypeAny: return eAddressClassUnknown;
468 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Greg Claytonb1888f22011-03-19 01:12:21 +0000469
470 case eSymbolTypeCode:
471 case eSymbolTypeTrampoline:
472 if (m_header.cputype == llvm::MachO::CPUTypeARM)
473 {
474 // For ARM we have a bit in the n_desc field of the symbol
475 // that tells us ARM/Thumb which is bit 0x0008.
476 if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
477 return eAddressClassCodeAlternateISA;
478 }
479 return eAddressClassCode;
480
481 case eSymbolTypeData: return eAddressClassData;
482 case eSymbolTypeRuntime: return eAddressClassRuntime;
483 case eSymbolTypeException: return eAddressClassRuntime;
484 case eSymbolTypeSourceFile: return eAddressClassDebug;
485 case eSymbolTypeHeaderFile: return eAddressClassDebug;
486 case eSymbolTypeObjectFile: return eAddressClassDebug;
487 case eSymbolTypeCommonBlock: return eAddressClassDebug;
488 case eSymbolTypeBlock: return eAddressClassDebug;
489 case eSymbolTypeLocal: return eAddressClassData;
490 case eSymbolTypeParam: return eAddressClassData;
491 case eSymbolTypeVariable: return eAddressClassData;
492 case eSymbolTypeVariableType: return eAddressClassDebug;
493 case eSymbolTypeLineEntry: return eAddressClassDebug;
494 case eSymbolTypeLineHeader: return eAddressClassDebug;
495 case eSymbolTypeScopeBegin: return eAddressClassDebug;
496 case eSymbolTypeScopeEnd: return eAddressClassDebug;
497 case eSymbolTypeAdditional: return eAddressClassUnknown;
498 case eSymbolTypeCompiler: return eAddressClassDebug;
499 case eSymbolTypeInstrumentation:return eAddressClassDebug;
500 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton3f69eac2011-12-03 02:30:59 +0000501 case eSymbolTypeObjCClass: return eAddressClassRuntime;
502 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
503 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Claytonb1888f22011-03-19 01:12:21 +0000504 }
505 }
506 }
507 return eAddressClassUnknown;
508}
Chris Lattner24943d22010-06-08 16:52:24 +0000509
510Symtab *
511ObjectFileMachO::GetSymtab()
512{
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000513 lldb_private::Mutex::Locker symfile_locker(m_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000514 if (m_symtab_ap.get() == NULL)
515 {
516 m_symtab_ap.reset(new Symtab(this));
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000517 Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
Greg Clayton7c36fa02010-09-11 03:13:28 +0000518 ParseSymtab (true);
Greg Clayton0c496cd2011-11-22 18:47:24 +0000519 m_symtab_ap->Finalize ();
Chris Lattner24943d22010-06-08 16:52:24 +0000520 }
521 return m_symtab_ap.get();
522}
523
524
525SectionList *
526ObjectFileMachO::GetSectionList()
527{
528 lldb_private::Mutex::Locker locker(m_mutex);
529 if (m_sections_ap.get() == NULL)
530 {
531 m_sections_ap.reset(new SectionList());
532 ParseSections();
533 }
534 return m_sections_ap.get();
535}
536
537
538size_t
539ObjectFileMachO::ParseSections ()
540{
541 lldb::user_id_t segID = 0;
542 lldb::user_id_t sectID = 0;
543 struct segment_command_64 load_cmd;
544 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
545 uint32_t i;
Greg Clayton46c9a352012-02-09 06:16:32 +0000546 const bool is_core = GetType() == eTypeCoreFile;
Chris Lattner24943d22010-06-08 16:52:24 +0000547 //bool dump_sections = false;
548 for (i=0; i<m_header.ncmds; ++i)
549 {
550 const uint32_t load_cmd_offset = offset;
551 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
552 break;
553
Greg Clayton1674b122010-07-21 22:12:05 +0000554 if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64)
Chris Lattner24943d22010-06-08 16:52:24 +0000555 {
556 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
557 {
558 load_cmd.vmaddr = m_data.GetAddress(&offset);
559 load_cmd.vmsize = m_data.GetAddress(&offset);
560 load_cmd.fileoff = m_data.GetAddress(&offset);
561 load_cmd.filesize = m_data.GetAddress(&offset);
562 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
563 {
Greg Clayton68ca8232011-01-25 02:58:48 +0000564
565 const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
566
Chris Lattner24943d22010-06-08 16:52:24 +0000567 // Keep a list of mach segments around in case we need to
568 // get at data that isn't stored in the abstracted Sections.
569 m_mach_segments.push_back (load_cmd);
570
571 ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
572 // Use a segment ID of the segment index shifted left by 8 so they
573 // never conflict with any of the sections.
574 SectionSP segment_sp;
Greg Clayton46c9a352012-02-09 06:16:32 +0000575 if (segment_name || is_core)
Chris Lattner24943d22010-06-08 16:52:24 +0000576 {
577 segment_sp.reset(new Section (NULL,
578 GetModule(), // Module to which this section belongs
579 ++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
580 segment_name, // Name of this section
581 eSectionTypeContainer, // This section is a container of other sections.
582 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file
583 load_cmd.vmsize, // VM size in bytes of this section
584 load_cmd.fileoff, // Offset to the data for this section in the file
585 load_cmd.filesize, // Size in bytes of this section as found in the the file
586 load_cmd.flags)); // Flags for this section
587
Greg Clayton68ca8232011-01-25 02:58:48 +0000588 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000589 m_sections_ap->AddSection(segment_sp);
590 }
591
592 struct section_64 sect64;
Greg Claytonddff7cc2011-02-04 21:13:05 +0000593 ::memset (&sect64, 0, sizeof(sect64));
Chris Lattner24943d22010-06-08 16:52:24 +0000594 // Push a section into our mach sections for the section at
Greg Clayton6af4fad2010-10-06 01:26:32 +0000595 // index zero (NListSectionNoSection) if we don't have any
596 // mach sections yet...
597 if (m_mach_sections.empty())
598 m_mach_sections.push_back(sect64);
Chris Lattner24943d22010-06-08 16:52:24 +0000599 uint32_t segment_sect_idx;
600 const lldb::user_id_t first_segment_sectID = sectID + 1;
601
602
Greg Clayton1674b122010-07-21 22:12:05 +0000603 const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8;
Chris Lattner24943d22010-06-08 16:52:24 +0000604 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
605 {
606 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
607 break;
608 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
609 break;
610 sect64.addr = m_data.GetAddress(&offset);
611 sect64.size = m_data.GetAddress(&offset);
612
613 if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
614 break;
615
616 // Keep a list of mach sections around in case we need to
617 // get at data that isn't stored in the abstracted Sections.
618 m_mach_sections.push_back (sect64);
619
620 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
621 if (!segment_name)
622 {
623 // We have a segment with no name so we need to conjure up
624 // segments that correspond to the section's segname if there
625 // isn't already such a section. If there is such a section,
626 // we resize the section so that it spans all sections.
627 // We also mark these sections as fake so address matches don't
628 // hit if they land in the gaps between the child sections.
629 segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
630 segment_sp = m_sections_ap->FindSectionByName (segment_name);
631 if (segment_sp.get())
632 {
633 Section *segment = segment_sp.get();
634 // Grow the section size as needed.
635 const lldb::addr_t sect64_min_addr = sect64.addr;
636 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
637 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
638 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
639 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
640 if (sect64_min_addr >= curr_seg_min_addr)
641 {
642 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
643 // Only grow the section size if needed
644 if (new_seg_byte_size > curr_seg_byte_size)
645 segment->SetByteSize (new_seg_byte_size);
646 }
647 else
648 {
649 // We need to change the base address of the segment and
650 // adjust the child section offsets for all existing children.
651 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
652 segment->Slide(slide_amount, false);
653 segment->GetChildren().Slide (-slide_amount, false);
654 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
655 }
Greg Clayton661825b2010-06-28 23:51:11 +0000656
657 // Grow the section size as needed.
658 if (sect64.offset)
659 {
660 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
661 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();
662
663 const lldb::addr_t section_min_file_offset = sect64.offset;
664 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
665 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
666 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
667 segment->SetFileOffset (new_file_offset);
668 segment->SetFileSize (new_file_size);
669 }
Chris Lattner24943d22010-06-08 16:52:24 +0000670 }
671 else
672 {
673 // Create a fake section for the section's named segment
674 segment_sp.reset(new Section(segment_sp.get(), // Parent section
675 GetModule(), // Module to which this section belongs
676 ++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
677 segment_name, // Name of this section
678 eSectionTypeContainer, // This section is a container of other sections.
679 sect64.addr, // File VM address == addresses as they are found in the object file
680 sect64.size, // VM size in bytes of this section
681 sect64.offset, // Offset to the data for this section in the file
682 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
683 load_cmd.flags)); // Flags for this section
684 segment_sp->SetIsFake(true);
685 m_sections_ap->AddSection(segment_sp);
Greg Clayton68ca8232011-01-25 02:58:48 +0000686 segment_sp->SetIsEncrypted (segment_is_encrypted);
Chris Lattner24943d22010-06-08 16:52:24 +0000687 }
688 }
689 assert (segment_sp.get());
690
Greg Clayton1674b122010-07-21 22:12:05 +0000691 uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType;
Chris Lattner24943d22010-06-08 16:52:24 +0000692 static ConstString g_sect_name_objc_data ("__objc_data");
693 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
694 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
695 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
696 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
697 static ConstString g_sect_name_objc_const ("__objc_const");
698 static ConstString g_sect_name_objc_classlist ("__objc_classlist");
699 static ConstString g_sect_name_cfstring ("__cfstring");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000700
701 static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
702 static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
703 static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
704 static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
705 static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
706 static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
707 static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
708 static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
709 static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
710 static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
711 static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
Greg Claytonf6e3de22011-09-28 17:06:40 +0000712 static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
713 static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
Greg Clayton00db2152011-10-04 22:41:51 +0000714 static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
Greg Clayton24a6bd92011-10-27 17:55:14 +0000715 static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000716 static ConstString g_sect_name_eh_frame ("__eh_frame");
Greg Clayton3fed8b92010-10-08 00:21:05 +0000717 static ConstString g_sect_name_DATA ("__DATA");
718 static ConstString g_sect_name_TEXT ("__TEXT");
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000719
Chris Lattner24943d22010-06-08 16:52:24 +0000720 SectionType sect_type = eSectionTypeOther;
721
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000722 if (section_name == g_sect_name_dwarf_debug_abbrev)
723 sect_type = eSectionTypeDWARFDebugAbbrev;
724 else if (section_name == g_sect_name_dwarf_debug_aranges)
725 sect_type = eSectionTypeDWARFDebugAranges;
726 else if (section_name == g_sect_name_dwarf_debug_frame)
727 sect_type = eSectionTypeDWARFDebugFrame;
728 else if (section_name == g_sect_name_dwarf_debug_info)
729 sect_type = eSectionTypeDWARFDebugInfo;
730 else if (section_name == g_sect_name_dwarf_debug_line)
731 sect_type = eSectionTypeDWARFDebugLine;
732 else if (section_name == g_sect_name_dwarf_debug_loc)
733 sect_type = eSectionTypeDWARFDebugLoc;
734 else if (section_name == g_sect_name_dwarf_debug_macinfo)
735 sect_type = eSectionTypeDWARFDebugMacInfo;
736 else if (section_name == g_sect_name_dwarf_debug_pubnames)
737 sect_type = eSectionTypeDWARFDebugPubNames;
738 else if (section_name == g_sect_name_dwarf_debug_pubtypes)
739 sect_type = eSectionTypeDWARFDebugPubTypes;
740 else if (section_name == g_sect_name_dwarf_debug_ranges)
741 sect_type = eSectionTypeDWARFDebugRanges;
742 else if (section_name == g_sect_name_dwarf_debug_str)
743 sect_type = eSectionTypeDWARFDebugStr;
Greg Claytonf6e3de22011-09-28 17:06:40 +0000744 else if (section_name == g_sect_name_dwarf_apple_names)
745 sect_type = eSectionTypeDWARFAppleNames;
746 else if (section_name == g_sect_name_dwarf_apple_types)
747 sect_type = eSectionTypeDWARFAppleTypes;
Greg Clayton00db2152011-10-04 22:41:51 +0000748 else if (section_name == g_sect_name_dwarf_apple_namespaces)
749 sect_type = eSectionTypeDWARFAppleNamespaces;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000750 else if (section_name == g_sect_name_dwarf_apple_objc)
751 sect_type = eSectionTypeDWARFAppleObjC;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000752 else if (section_name == g_sect_name_objc_selrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000753 sect_type = eSectionTypeDataCStringPointers;
Chris Lattner24943d22010-06-08 16:52:24 +0000754 else if (section_name == g_sect_name_objc_msgrefs)
Chris Lattner24943d22010-06-08 16:52:24 +0000755 sect_type = eSectionTypeDataObjCMessageRefs;
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000756 else if (section_name == g_sect_name_eh_frame)
757 sect_type = eSectionTypeEHFrame;
758 else if (section_name == g_sect_name_cfstring)
759 sect_type = eSectionTypeDataObjCCFStrings;
Chris Lattner24943d22010-06-08 16:52:24 +0000760 else if (section_name == g_sect_name_objc_data ||
761 section_name == g_sect_name_objc_classrefs ||
762 section_name == g_sect_name_objc_superrefs ||
763 section_name == g_sect_name_objc_const ||
764 section_name == g_sect_name_objc_classlist)
765 {
766 sect_type = eSectionTypeDataPointers;
767 }
Chris Lattner24943d22010-06-08 16:52:24 +0000768
769 if (sect_type == eSectionTypeOther)
770 {
771 switch (mach_sect_type)
772 {
773 // TODO: categorize sections by other flags for regular sections
Greg Clayton3fed8b92010-10-08 00:21:05 +0000774 case SectionTypeRegular:
775 if (segment_sp->GetName() == g_sect_name_TEXT)
776 sect_type = eSectionTypeCode;
777 else if (segment_sp->GetName() == g_sect_name_DATA)
778 sect_type = eSectionTypeData;
779 else
780 sect_type = eSectionTypeOther;
781 break;
Greg Clayton1674b122010-07-21 22:12:05 +0000782 case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
783 case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
784 case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals
785 case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals
786 case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals
787 case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers
788 case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers
789 case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field
790 case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization
791 case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
792 case SectionTypeCoalesced: sect_type = eSectionTypeOther; break;
793 case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break;
794 case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing
795 case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals
796 case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break;
797 case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break;
Chris Lattner24943d22010-06-08 16:52:24 +0000798 default: break;
799 }
800 }
801
802 SectionSP section_sp(new Section(segment_sp.get(),
803 GetModule(),
804 ++sectID,
805 section_name,
806 sect_type,
807 sect64.addr - segment_sp->GetFileAddress(),
808 sect64.size,
809 sect64.offset,
810 sect64.offset == 0 ? 0 : sect64.size,
811 sect64.flags));
Greg Clayton68ca8232011-01-25 02:58:48 +0000812 // Set the section to be encrypted to match the segment
813 section_sp->SetIsEncrypted (segment_is_encrypted);
814
Chris Lattner24943d22010-06-08 16:52:24 +0000815 segment_sp->GetChildren().AddSection(section_sp);
816
817 if (segment_sp->IsFake())
818 {
819 segment_sp.reset();
820 segment_name.Clear();
821 }
822 }
Greg Clayton0fa51242011-07-19 03:57:15 +0000823 if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
Chris Lattner24943d22010-06-08 16:52:24 +0000824 {
825 if (first_segment_sectID <= sectID)
826 {
827 lldb::user_id_t sect_uid;
828 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
829 {
830 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
831 SectionSP next_section_sp;
832 if (sect_uid + 1 <= sectID)
833 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);
834
835 if (curr_section_sp.get())
836 {
837 if (curr_section_sp->GetByteSize() == 0)
838 {
839 if (next_section_sp.get() != NULL)
840 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
841 else
842 curr_section_sp->SetByteSize ( load_cmd.vmsize );
843 }
844 }
845 }
846 }
847 }
848 }
849 }
850 }
Greg Clayton1674b122010-07-21 22:12:05 +0000851 else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo)
Chris Lattner24943d22010-06-08 16:52:24 +0000852 {
853 m_dysymtab.cmd = load_cmd.cmd;
854 m_dysymtab.cmdsize = load_cmd.cmdsize;
855 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
856 }
857
858 offset = load_cmd_offset + load_cmd.cmdsize;
859 }
860// if (dump_sections)
861// {
862// StreamFile s(stdout);
863// m_sections_ap->Dump(&s, true);
864// }
865 return sectID; // Return the number of sections we registered with the module
866}
867
868class MachSymtabSectionInfo
869{
870public:
871
872 MachSymtabSectionInfo (SectionList *section_list) :
873 m_section_list (section_list),
874 m_section_infos()
875 {
876 // Get the number of sections down to a depth of 1 to include
877 // all segments and their sections, but no other sections that
878 // may be added for debug map or
879 m_section_infos.resize(section_list->GetNumSections(1));
880 }
881
882
883 Section *
884 GetSection (uint8_t n_sect, addr_t file_addr)
885 {
886 if (n_sect == 0)
887 return NULL;
888 if (n_sect < m_section_infos.size())
889 {
890 if (m_section_infos[n_sect].section == NULL)
891 {
892 Section *section = m_section_list->FindSectionByID (n_sect).get();
893 m_section_infos[n_sect].section = section;
Greg Clayton5638d2c2011-07-10 17:32:33 +0000894 if (section != NULL)
895 {
896 m_section_infos[n_sect].vm_range.SetBaseAddress (section->GetFileAddress());
897 m_section_infos[n_sect].vm_range.SetByteSize (section->GetByteSize());
898 }
899 else
900 {
Greg Claytondf6dc882012-01-05 03:57:59 +0000901 Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
Greg Clayton5638d2c2011-07-10 17:32:33 +0000902 }
Chris Lattner24943d22010-06-08 16:52:24 +0000903 }
904 if (m_section_infos[n_sect].vm_range.Contains(file_addr))
Greg Clayton811b9c52011-08-26 20:01:35 +0000905 {
906 // Symbol is in section.
Chris Lattner24943d22010-06-08 16:52:24 +0000907 return m_section_infos[n_sect].section;
Greg Clayton811b9c52011-08-26 20:01:35 +0000908 }
909 else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
910 m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
911 {
912 // Symbol is in section with zero size, but has the same start
913 // address as the section. This can happen with linker symbols
914 // (symbols that start with the letter 'l' or 'L'.
915 return m_section_infos[n_sect].section;
916 }
Chris Lattner24943d22010-06-08 16:52:24 +0000917 }
918 return m_section_list->FindSectionContainingFileAddress(file_addr).get();
919 }
920
921protected:
922 struct SectionInfo
923 {
924 SectionInfo () :
925 vm_range(),
926 section (NULL)
927 {
928 }
929
930 VMRange vm_range;
931 Section *section;
932 };
933 SectionList *m_section_list;
934 std::vector<SectionInfo> m_section_infos;
935};
936
937
938
939size_t
940ObjectFileMachO::ParseSymtab (bool minimize)
941{
942 Timer scoped_timer(__PRETTY_FUNCTION__,
943 "ObjectFileMachO::ParseSymtab () module = %s",
944 m_file.GetFilename().AsCString(""));
945 struct symtab_command symtab_load_command;
946 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
947 uint32_t i;
Greg Clayton0fea0512011-12-30 00:32:24 +0000948
949 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
950
Chris Lattner24943d22010-06-08 16:52:24 +0000951 for (i=0; i<m_header.ncmds; ++i)
952 {
953 const uint32_t cmd_offset = offset;
954 // Read in the load command and load command size
955 if (m_data.GetU32(&offset, &symtab_load_command, 2) == NULL)
956 break;
957 // Watch for the symbol table load command
Greg Clayton1674b122010-07-21 22:12:05 +0000958 if (symtab_load_command.cmd == LoadCommandSymtab)
Chris Lattner24943d22010-06-08 16:52:24 +0000959 {
960 // Read in the rest of the symtab load command
Jason Molendaccfba722010-07-06 22:38:03 +0000961 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4)) // fill in symoff, nsyms, stroff, strsize fields
Chris Lattner24943d22010-06-08 16:52:24 +0000962 {
Greg Clayton0fea0512011-12-30 00:32:24 +0000963 if (symtab_load_command.symoff == 0)
964 {
965 if (log)
966 GetModule()->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
967 return 0;
968 }
969
970 if (symtab_load_command.stroff == 0)
971 {
972 if (log)
973 GetModule()->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
974 return 0;
975 }
976
977 if (symtab_load_command.nsyms == 0)
978 {
979 if (log)
980 GetModule()->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
981 return 0;
982 }
983
984 if (symtab_load_command.strsize == 0)
985 {
986 if (log)
987 GetModule()->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
988 return 0;
989 }
990
Chris Lattner24943d22010-06-08 16:52:24 +0000991 Symtab *symtab = m_symtab_ap.get();
992 SectionList *section_list = GetSectionList();
Greg Clayton0fea0512011-12-30 00:32:24 +0000993 if (section_list == NULL)
994 return 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000995
Greg Claytonb5a8f142012-02-05 02:38:54 +0000996 ProcessSP process_sp (m_process_wp.lock());
997
Greg Clayton0fea0512011-12-30 00:32:24 +0000998 const size_t addr_byte_size = m_data.GetAddressByteSize();
Greg Clayton0fea0512011-12-30 00:32:24 +0000999 bool bit_width_32 = addr_byte_size == 4;
1000 const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
1001
Greg Claytonb5a8f142012-02-05 02:38:54 +00001002 DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1003 DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
1004
1005 const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
1006 const addr_t strtab_data_byte_size = symtab_load_command.strsize;
1007 if (process_sp)
1008 {
1009 Target &target = process_sp->GetTarget();
1010 SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
1011 // Reading mach file from memory in a process or core file...
1012
1013 if (linkedit_section_sp)
1014 {
1015 const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
1016 const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
1017 const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
1018 const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
1019 DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
1020 DataBufferSP strtab_data_sp (ReadMemory (process_sp, stroff_addr, strtab_data_byte_size));
1021 nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
1022 strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
1023 }
1024 }
1025 else
1026 {
1027 nlist_data.SetData (m_data,
1028 symtab_load_command.symoff,
1029 nlist_data_byte_size);
1030 strtab_data.SetData (m_data,
1031 symtab_load_command.stroff,
1032 strtab_data_byte_size);
1033
1034 }
Greg Clayton0fea0512011-12-30 00:32:24 +00001035
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001036 if (nlist_data.GetByteSize() == 0)
Greg Clayton0fea0512011-12-30 00:32:24 +00001037 {
1038 if (log)
1039 GetModule()->LogMessage(log.get(), "failed to read nlist data");
1040 return 0;
1041 }
1042
Greg Clayton0fea0512011-12-30 00:32:24 +00001043
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001044 if (strtab_data.GetByteSize() == 0)
Greg Clayton0fea0512011-12-30 00:32:24 +00001045 {
1046 if (log)
1047 GetModule()->LogMessage(log.get(), "failed to read strtab data");
1048 return 0;
1049 }
Chris Lattner24943d22010-06-08 16:52:24 +00001050
Greg Claytonb5a8f142012-02-05 02:38:54 +00001051 const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
1052 const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
1053 const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
1054 const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
Chris Lattner24943d22010-06-08 16:52:24 +00001055 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
1056 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
1057 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
1058 SectionSP eh_frame_section_sp;
1059 if (text_section_sp.get())
1060 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
1061 else
1062 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
1063
Greg Clayton1674b122010-07-21 22:12:05 +00001064 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
Chris Lattner24943d22010-06-08 16:52:24 +00001065
Greg Clayton0fea0512011-12-30 00:32:24 +00001066 uint32_t nlist_data_offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +00001067
Greg Clayton7c36fa02010-09-11 03:13:28 +00001068 uint32_t N_SO_index = UINT32_MAX;
Chris Lattner24943d22010-06-08 16:52:24 +00001069
1070 MachSymtabSectionInfo section_info (section_list);
1071 std::vector<uint32_t> N_FUN_indexes;
1072 std::vector<uint32_t> N_NSYM_indexes;
1073 std::vector<uint32_t> N_INCL_indexes;
1074 std::vector<uint32_t> N_BRAC_indexes;
1075 std::vector<uint32_t> N_COMM_indexes;
Greg Clayton576a68b2010-09-08 16:38:06 +00001076 typedef std::map <uint64_t, uint32_t> ValueToSymbolIndexMap;
Greg Clayton637029b2010-09-12 05:25:16 +00001077 typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
Greg Clayton576a68b2010-09-08 16:38:06 +00001078 ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
1079 ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001080 // Any symbols that get merged into another will get an entry
1081 // in this map so we know
Greg Clayton637029b2010-09-12 05:25:16 +00001082 NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
Chris Lattner24943d22010-06-08 16:52:24 +00001083 uint32_t nlist_idx = 0;
1084 Symbol *symbol_ptr = NULL;
1085
1086 uint32_t sym_idx = 0;
1087 Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1088 uint32_t num_syms = symtab->GetNumSymbols();
1089
1090 //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
1091 for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
1092 {
1093 struct nlist_64 nlist;
Greg Clayton0fea0512011-12-30 00:32:24 +00001094 if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
1095 break;
1096
1097 nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
1098 nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
1099 nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
1100 nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
1101 nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
Chris Lattner24943d22010-06-08 16:52:24 +00001102
1103 SymbolType type = eSymbolTypeInvalid;
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001104 const char *symbol_name = strtab_data.PeekCStr(nlist.n_strx);
1105 if (symbol_name == NULL)
Greg Claytona9c4f312011-10-31 20:50:40 +00001106 {
1107 // No symbol should be NULL, even the symbols with no
1108 // string values should have an offset zero which points
1109 // to an empty C-string
Greg Claytondf6dc882012-01-05 03:57:59 +00001110 Host::SystemLog (Host::eSystemLogError,
1111 "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
1112 nlist_idx,
1113 nlist.n_strx,
1114 m_module->GetFileSpec().GetDirectory().GetCString(),
1115 m_module->GetFileSpec().GetFilename().GetCString());
Greg Claytona9c4f312011-10-31 20:50:40 +00001116 continue;
1117 }
Greg Clayton3f69eac2011-12-03 02:30:59 +00001118 const char *symbol_name_non_abi_mangled = NULL;
Greg Claytona9c4f312011-10-31 20:50:40 +00001119
Chris Lattner24943d22010-06-08 16:52:24 +00001120 if (symbol_name[0] == '\0')
1121 symbol_name = NULL;
1122 Section* symbol_section = NULL;
1123 bool add_nlist = true;
Greg Clayton1674b122010-07-21 22:12:05 +00001124 bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
Chris Lattner24943d22010-06-08 16:52:24 +00001125
1126 assert (sym_idx < num_syms);
1127
1128 sym[sym_idx].SetDebug (is_debug);
1129
1130 if (is_debug)
1131 {
1132 switch (nlist.n_type)
1133 {
Greg Clayton1674b122010-07-21 22:12:05 +00001134 case StabGlobalSymbol:
1135 // N_GSYM -- global symbol: name,,NO_SECT,type,0
Chris Lattner24943d22010-06-08 16:52:24 +00001136 // Sometimes the N_GSYM value contains the address.
Jim Ingham115213c2011-12-16 00:05:58 +00001137
1138 // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
1139 // have the same address, but we want to ensure that we always find only the real symbol,
1140 // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
1141 // symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
1142 // correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
1143 // same address.
1144
1145 if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
1146 && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
1147 || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
1148 || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
1149 add_nlist = false;
1150 else
1151 {
1152 sym[sym_idx].SetExternal(true);
1153 if (nlist.n_value != 0)
1154 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1155 type = eSymbolTypeData;
1156 }
Chris Lattner24943d22010-06-08 16:52:24 +00001157 break;
1158
Greg Clayton1674b122010-07-21 22:12:05 +00001159 case StabFunctionName:
1160 // N_FNAME -- procedure name (f77 kludge): name,,NO_SECT,0,0
Greg Clayton7c36fa02010-09-11 03:13:28 +00001161 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00001162 break;
1163
Greg Clayton1674b122010-07-21 22:12:05 +00001164 case StabFunction:
1165 // N_FUN -- procedure: name,,n_sect,linenumber,address
Chris Lattner24943d22010-06-08 16:52:24 +00001166 if (symbol_name)
1167 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001168 type = eSymbolTypeCode;
Chris Lattner24943d22010-06-08 16:52:24 +00001169 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Greg Clayton576a68b2010-09-08 16:38:06 +00001170
1171 N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
Chris Lattner24943d22010-06-08 16:52:24 +00001172 // We use the current number of symbols in the symbol table in lieu of
1173 // using nlist_idx in case we ever start trimming entries out
1174 N_FUN_indexes.push_back(sym_idx);
1175 }
1176 else
1177 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001178 type = eSymbolTypeCompiler;
Chris Lattner24943d22010-06-08 16:52:24 +00001179
1180 if ( !N_FUN_indexes.empty() )
1181 {
1182 // Copy the size of the function into the original STAB entry so we don't have
1183 // to hunt for it later
1184 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
1185 N_FUN_indexes.pop_back();
Jason Molendaccfba722010-07-06 22:38:03 +00001186 // We don't really need the end function STAB as it contains the size which
Chris Lattner24943d22010-06-08 16:52:24 +00001187 // we already placed with the original symbol, so don't add it if we want a
1188 // minimal symbol table
1189 if (minimize)
1190 add_nlist = false;
1191 }
1192 }
1193 break;
1194
Greg Clayton1674b122010-07-21 22:12:05 +00001195 case StabStaticSymbol:
1196 // N_STSYM -- static symbol: name,,n_sect,type,address
Greg Clayton576a68b2010-09-08 16:38:06 +00001197 N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
Chris Lattner24943d22010-06-08 16:52:24 +00001198 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
Greg Clayton7c36fa02010-09-11 03:13:28 +00001199 type = eSymbolTypeData;
Chris Lattner24943d22010-06-08 16:52:24 +00001200 break;
1201
Greg Clayton1674b122010-07-21 22:12:05 +00001202 case StabLocalCommon:
1203 // N_LCSYM -- .lcomm symbol: name,,n_sect,type,address
Chris Lattner24943d22010-06-08 16:52:24 +00001204 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1205 type = eSymbolTypeCommonBlock;
1206 break;
1207
Greg Clayton1674b122010-07-21 22:12:05 +00001208 case StabBeginSymbol:
1209 // N_BNSYM
Chris Lattner24943d22010-06-08 16:52:24 +00001210 // We use the current number of symbols in the symbol table in lieu of
1211 // using nlist_idx in case we ever start trimming entries out
1212 if (minimize)
1213 {
1214 // Skip these if we want minimal symbol tables
1215 add_nlist = false;
1216 }
1217 else
1218 {
1219 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1220 N_NSYM_indexes.push_back(sym_idx);
1221 type = eSymbolTypeScopeBegin;
1222 }
1223 break;
1224
Greg Clayton1674b122010-07-21 22:12:05 +00001225 case StabEndSymbol:
1226 // N_ENSYM
Chris Lattner24943d22010-06-08 16:52:24 +00001227 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
1228 // so that we can always skip the entire symbol if we need to navigate
1229 // more quickly at the source level when parsing STABS
1230 if (minimize)
1231 {
1232 // Skip these if we want minimal symbol tables
1233 add_nlist = false;
1234 }
1235 else
1236 {
1237 if ( !N_NSYM_indexes.empty() )
1238 {
1239 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back());
1240 symbol_ptr->SetByteSize(sym_idx + 1);
1241 symbol_ptr->SetSizeIsSibling(true);
1242 N_NSYM_indexes.pop_back();
1243 }
1244 type = eSymbolTypeScopeEnd;
1245 }
1246 break;
1247
1248
Greg Clayton1674b122010-07-21 22:12:05 +00001249 case StabSourceFileOptions:
1250 // N_OPT - emitted with gcc2_compiled and in gcc source
Chris Lattner24943d22010-06-08 16:52:24 +00001251 type = eSymbolTypeCompiler;
1252 break;
1253
Greg Clayton1674b122010-07-21 22:12:05 +00001254 case StabRegisterSymbol:
1255 // N_RSYM - register sym: name,,NO_SECT,type,register
Chris Lattner24943d22010-06-08 16:52:24 +00001256 type = eSymbolTypeVariable;
1257 break;
1258
Greg Clayton1674b122010-07-21 22:12:05 +00001259 case StabSourceLine:
1260 // N_SLINE - src line: 0,,n_sect,linenumber,address
Chris Lattner24943d22010-06-08 16:52:24 +00001261 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1262 type = eSymbolTypeLineEntry;
1263 break;
1264
Greg Clayton1674b122010-07-21 22:12:05 +00001265 case StabStructureType:
1266 // N_SSYM - structure elt: name,,NO_SECT,type,struct_offset
Chris Lattner24943d22010-06-08 16:52:24 +00001267 type = eSymbolTypeVariableType;
1268 break;
1269
Greg Clayton1674b122010-07-21 22:12:05 +00001270 case StabSourceFileName:
1271 // N_SO - source file name
Chris Lattner24943d22010-06-08 16:52:24 +00001272 type = eSymbolTypeSourceFile;
1273 if (symbol_name == NULL)
1274 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001275 if (minimize)
1276 add_nlist = false;
1277 if (N_SO_index != UINT32_MAX)
Chris Lattner24943d22010-06-08 16:52:24 +00001278 {
1279 // Set the size of the N_SO to the terminating index of this N_SO
1280 // so that we can always skip the entire N_SO if we need to navigate
1281 // more quickly at the source level when parsing STABS
1282 symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
Greg Clayton7c36fa02010-09-11 03:13:28 +00001283 symbol_ptr->SetByteSize(sym_idx + (minimize ? 0 : 1));
Chris Lattner24943d22010-06-08 16:52:24 +00001284 symbol_ptr->SetSizeIsSibling(true);
1285 }
1286 N_NSYM_indexes.clear();
1287 N_INCL_indexes.clear();
1288 N_BRAC_indexes.clear();
1289 N_COMM_indexes.clear();
1290 N_FUN_indexes.clear();
Greg Clayton7c36fa02010-09-11 03:13:28 +00001291 N_SO_index = UINT32_MAX;
Chris Lattner24943d22010-06-08 16:52:24 +00001292 }
Greg Clayton7c36fa02010-09-11 03:13:28 +00001293 else
Chris Lattner24943d22010-06-08 16:52:24 +00001294 {
1295 // We use the current number of symbols in the symbol table in lieu of
1296 // using nlist_idx in case we ever start trimming entries out
Greg Clayton7c36fa02010-09-11 03:13:28 +00001297 if (symbol_name[0] == '/')
1298 N_SO_index = sym_idx;
Greg Claytondab471f2011-06-19 04:26:01 +00001299 else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
Greg Clayton7c36fa02010-09-11 03:13:28 +00001300 {
1301 const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
1302 if (so_path && so_path[0])
1303 {
1304 std::string full_so_path (so_path);
1305 if (*full_so_path.rbegin() != '/')
1306 full_so_path += '/';
1307 full_so_path += symbol_name;
1308 sym[sym_idx - 1].GetMangled().SetValue(full_so_path.c_str(), false);
1309 add_nlist = false;
Greg Clayton637029b2010-09-12 05:25:16 +00001310 m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001311 }
1312 }
Chris Lattner24943d22010-06-08 16:52:24 +00001313 }
Greg Clayton7c36fa02010-09-11 03:13:28 +00001314
Chris Lattner24943d22010-06-08 16:52:24 +00001315 break;
1316
Greg Clayton1674b122010-07-21 22:12:05 +00001317 case StabObjectFileName:
1318 // N_OSO - object file name: name,,0,0,st_mtime
Chris Lattner24943d22010-06-08 16:52:24 +00001319 type = eSymbolTypeObjectFile;
1320 break;
1321
Greg Clayton1674b122010-07-21 22:12:05 +00001322 case StabLocalSymbol:
1323 // N_LSYM - local sym: name,,NO_SECT,type,offset
Chris Lattner24943d22010-06-08 16:52:24 +00001324 type = eSymbolTypeLocal;
1325 break;
1326
1327 //----------------------------------------------------------------------
1328 // INCL scopes
1329 //----------------------------------------------------------------------
Greg Clayton1674b122010-07-21 22:12:05 +00001330 case StabBeginIncludeFileName:
1331 // N_BINCL - include file beginning: name,,NO_SECT,0,sum
Chris Lattner24943d22010-06-08 16:52:24 +00001332 // We use the current number of symbols in the symbol table in lieu of
1333 // using nlist_idx in case we ever start trimming entries out
1334 N_INCL_indexes.push_back(sym_idx);
1335 type = eSymbolTypeScopeBegin;
1336 break;
Chris Lattner24943d22010-06-08 16:52:24 +00001337
Greg Clayton1674b122010-07-21 22:12:05 +00001338 case StabEndIncludeFile:
1339 // N_EINCL - include file end: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001340 // Set the size of the N_BINCL to the terminating index of this N_EINCL
1341 // so that we can always skip the entire symbol if we need to navigate
1342 // more quickly at the source level when parsing STABS
1343 if ( !N_INCL_indexes.empty() )
1344 {
1345 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
1346 symbol_ptr->SetByteSize(sym_idx + 1);
1347 symbol_ptr->SetSizeIsSibling(true);
1348 N_INCL_indexes.pop_back();
1349 }
1350 type = eSymbolTypeScopeEnd;
1351 break;
1352
Greg Clayton1674b122010-07-21 22:12:05 +00001353 case StabIncludeFileName:
1354 // N_SOL - #included file name: name,,n_sect,0,address
Chris Lattner24943d22010-06-08 16:52:24 +00001355 type = eSymbolTypeHeaderFile;
Greg Clayton0ad086f2010-09-07 17:36:17 +00001356
1357 // We currently don't use the header files on darwin
1358 if (minimize)
1359 add_nlist = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001360 break;
1361
Greg Clayton1674b122010-07-21 22:12:05 +00001362 case StabCompilerParameters:
1363 // N_PARAMS - compiler parameters: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001364 type = eSymbolTypeCompiler;
1365 break;
1366
Greg Clayton1674b122010-07-21 22:12:05 +00001367 case StabCompilerVersion:
1368 // N_VERSION - compiler version: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001369 type = eSymbolTypeCompiler;
1370 break;
1371
Greg Clayton1674b122010-07-21 22:12:05 +00001372 case StabCompilerOptLevel:
1373 // N_OLEVEL - compiler -O level: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001374 type = eSymbolTypeCompiler;
1375 break;
1376
Greg Clayton1674b122010-07-21 22:12:05 +00001377 case StabParameter:
1378 // N_PSYM - parameter: name,,NO_SECT,type,offset
Chris Lattner24943d22010-06-08 16:52:24 +00001379 type = eSymbolTypeVariable;
1380 break;
1381
Greg Clayton1674b122010-07-21 22:12:05 +00001382 case StabAlternateEntry:
1383 // N_ENTRY - alternate entry: name,,n_sect,linenumber,address
Chris Lattner24943d22010-06-08 16:52:24 +00001384 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1385 type = eSymbolTypeLineEntry;
1386 break;
1387
1388 //----------------------------------------------------------------------
1389 // Left and Right Braces
1390 //----------------------------------------------------------------------
Greg Clayton1674b122010-07-21 22:12:05 +00001391 case StabLeftBracket:
1392 // N_LBRAC - left bracket: 0,,NO_SECT,nesting level,address
Chris Lattner24943d22010-06-08 16:52:24 +00001393 // We use the current number of symbols in the symbol table in lieu of
1394 // using nlist_idx in case we ever start trimming entries out
1395 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1396 N_BRAC_indexes.push_back(sym_idx);
1397 type = eSymbolTypeScopeBegin;
1398 break;
1399
Greg Clayton1674b122010-07-21 22:12:05 +00001400 case StabRightBracket:
1401 // N_RBRAC - right bracket: 0,,NO_SECT,nesting level,address
Chris Lattner24943d22010-06-08 16:52:24 +00001402 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
1403 // so that we can always skip the entire symbol if we need to navigate
1404 // more quickly at the source level when parsing STABS
1405 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1406 if ( !N_BRAC_indexes.empty() )
1407 {
1408 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
1409 symbol_ptr->SetByteSize(sym_idx + 1);
1410 symbol_ptr->SetSizeIsSibling(true);
1411 N_BRAC_indexes.pop_back();
1412 }
1413 type = eSymbolTypeScopeEnd;
1414 break;
1415
Greg Clayton1674b122010-07-21 22:12:05 +00001416 case StabDeletedIncludeFile:
1417 // N_EXCL - deleted include file: name,,NO_SECT,0,sum
Chris Lattner24943d22010-06-08 16:52:24 +00001418 type = eSymbolTypeHeaderFile;
1419 break;
1420
1421 //----------------------------------------------------------------------
1422 // COMM scopes
1423 //----------------------------------------------------------------------
Greg Clayton1674b122010-07-21 22:12:05 +00001424 case StabBeginCommon:
1425 // N_BCOMM - begin common: name,,NO_SECT,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001426 // We use the current number of symbols in the symbol table in lieu of
1427 // using nlist_idx in case we ever start trimming entries out
1428 type = eSymbolTypeScopeBegin;
1429 N_COMM_indexes.push_back(sym_idx);
1430 break;
1431
Greg Clayton1674b122010-07-21 22:12:05 +00001432 case StabEndCommonLocal:
1433 // N_ECOML - end common (local name): 0,,n_sect,0,address
Chris Lattner24943d22010-06-08 16:52:24 +00001434 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1435 // Fall through
1436
Greg Clayton1674b122010-07-21 22:12:05 +00001437 case StabEndCommon:
1438 // N_ECOMM - end common: name,,n_sect,0,0
Chris Lattner24943d22010-06-08 16:52:24 +00001439 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
1440 // so that we can always skip the entire symbol if we need to navigate
1441 // more quickly at the source level when parsing STABS
1442 if ( !N_COMM_indexes.empty() )
1443 {
1444 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
1445 symbol_ptr->SetByteSize(sym_idx + 1);
1446 symbol_ptr->SetSizeIsSibling(true);
1447 N_COMM_indexes.pop_back();
1448 }
1449 type = eSymbolTypeScopeEnd;
1450 break;
1451
Greg Clayton1674b122010-07-21 22:12:05 +00001452 case StabLength:
1453 // N_LENG - second stab entry with length information
Chris Lattner24943d22010-06-08 16:52:24 +00001454 type = eSymbolTypeAdditional;
1455 break;
1456
1457 default: break;
1458 }
1459 }
1460 else
1461 {
Greg Clayton1674b122010-07-21 22:12:05 +00001462 //uint8_t n_pext = NlistMaskPrivateExternal & nlist.n_type;
1463 uint8_t n_type = NlistMaskType & nlist.n_type;
1464 sym[sym_idx].SetExternal((NlistMaskExternal & nlist.n_type) != 0);
Chris Lattner24943d22010-06-08 16:52:24 +00001465
Greg Clayton3f69eac2011-12-03 02:30:59 +00001466 switch (n_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001467 {
Greg Clayton3f69eac2011-12-03 02:30:59 +00001468 case NListTypeIndirect: // N_INDR - Fall through
1469 case NListTypePreboundUndefined:// N_PBUD - Fall through
1470 case NListTypeUndefined: // N_UNDF
1471 type = eSymbolTypeUndefined;
1472 break;
1473
1474 case NListTypeAbsolute: // N_ABS
1475 type = eSymbolTypeAbsolute;
1476 break;
1477
1478 case NListTypeSection: // N_SECT
1479 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
1480
1481 if (symbol_section == NULL)
1482 {
1483 // TODO: warn about this?
1484 add_nlist = false;
1485 break;
1486 }
1487
1488 if (TEXT_eh_frame_sectID == nlist.n_sect)
1489 {
1490 type = eSymbolTypeException;
1491 }
1492 else
1493 {
1494 uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
1495
1496 switch (section_type)
1497 {
1498 case SectionTypeRegular: break; // regular section
1499 //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
1500 case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
1501 case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
1502 case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
1503 case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
1504 case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
1505 case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
1506 case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
1507 case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
1508 case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
1509 //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
1510 //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
1511 case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
1512 case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
1513 case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
1514 case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
1515 default: break;
1516 }
1517
1518 if (type == eSymbolTypeInvalid)
1519 {
1520 const char *symbol_sect_name = symbol_section->GetName().AsCString();
1521 if (symbol_section->IsDescendant (text_section_sp.get()))
1522 {
1523 if (symbol_section->IsClear(SectionAttrUserPureInstructions |
1524 SectionAttrUserSelfModifyingCode |
1525 SectionAttrSytemSomeInstructions))
1526 type = eSymbolTypeData;
1527 else
1528 type = eSymbolTypeCode;
1529 }
1530 else
1531 if (symbol_section->IsDescendant(data_section_sp.get()))
1532 {
1533 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
1534 {
1535 type = eSymbolTypeRuntime;
1536
1537 if (symbol_name &&
1538 symbol_name[0] == '_' &&
1539 symbol_name[1] == 'O' &&
1540 symbol_name[2] == 'B')
1541 {
1542 llvm::StringRef symbol_name_ref(symbol_name);
1543 static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
1544 static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
1545 static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
1546 if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
1547 {
Sean Callanand0b7cfa2011-12-03 04:38:43 +00001548 symbol_name_non_abi_mangled = symbol_name + 1;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001549 symbol_name = symbol_name + g_objc_v2_prefix_class.size();
1550 type = eSymbolTypeObjCClass;
1551 }
1552 else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
1553 {
Sean Callanand0b7cfa2011-12-03 04:38:43 +00001554 symbol_name_non_abi_mangled = symbol_name + 1;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001555 symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
1556 type = eSymbolTypeObjCMetaClass;
1557 }
1558 else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
1559 {
Sean Callanand0b7cfa2011-12-03 04:38:43 +00001560 symbol_name_non_abi_mangled = symbol_name + 1;
Greg Clayton3f69eac2011-12-03 02:30:59 +00001561 symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
1562 type = eSymbolTypeObjCIVar;
1563 }
1564 }
1565 }
1566 else
1567 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
1568 {
1569 type = eSymbolTypeException;
1570 }
1571 else
1572 {
1573 type = eSymbolTypeData;
1574 }
1575 }
1576 else
1577 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
1578 {
1579 type = eSymbolTypeTrampoline;
1580 }
1581 else
1582 if (symbol_section->IsDescendant(objc_section_sp.get()))
1583 {
1584 type = eSymbolTypeRuntime;
1585 if (symbol_name && symbol_name[0] == '.')
1586 {
1587 llvm::StringRef symbol_name_ref(symbol_name);
1588 static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
1589 if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
1590 {
1591 symbol_name_non_abi_mangled = symbol_name;
1592 symbol_name = symbol_name + g_objc_v1_prefix_class.size();
1593 type = eSymbolTypeObjCClass;
1594 }
1595 }
1596 }
1597 }
1598 }
1599 break;
1600 }
1601 }
1602
1603 if (add_nlist)
1604 {
1605 uint64_t symbol_value = nlist.n_value;
1606 bool symbol_name_is_mangled = false;
1607
1608 if (symbol_name_non_abi_mangled)
1609 {
1610 sym[sym_idx].GetMangled().SetMangledName (symbol_name_non_abi_mangled);
1611 sym[sym_idx].GetMangled().SetDemangledName (symbol_name);
Chris Lattner24943d22010-06-08 16:52:24 +00001612 }
1613 else
1614 {
Greg Clayton3f69eac2011-12-03 02:30:59 +00001615 if (symbol_name && symbol_name[0] == '_')
Chris Lattner24943d22010-06-08 16:52:24 +00001616 {
Greg Clayton3f69eac2011-12-03 02:30:59 +00001617 symbol_name_is_mangled = symbol_name[1] == '_';
1618 symbol_name++; // Skip the leading underscore
1619 }
Chris Lattner24943d22010-06-08 16:52:24 +00001620
Greg Clayton038f1c02011-12-03 03:02:17 +00001621 if (symbol_name)
Greg Clayton3f69eac2011-12-03 02:30:59 +00001622 {
1623 sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled);
1624 }
Chris Lattner24943d22010-06-08 16:52:24 +00001625 }
Greg Clayton576a68b2010-09-08 16:38:06 +00001626
Greg Clayton7c36fa02010-09-11 03:13:28 +00001627 if (is_debug == false)
Greg Clayton576a68b2010-09-08 16:38:06 +00001628 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001629 if (type == eSymbolTypeCode)
Greg Clayton576a68b2010-09-08 16:38:06 +00001630 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001631 // See if we can find a N_FUN entry for any code symbols.
1632 // If we do find a match, and the name matches, then we
1633 // can merge the two into just the function symbol to avoid
1634 // duplicate entries in the symbol table
1635 ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value);
1636 if (pos != N_FUN_addr_to_sym_idx.end())
Greg Clayton576a68b2010-09-08 16:38:06 +00001637 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001638 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1639 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1640 {
Greg Clayton637029b2010-09-12 05:25:16 +00001641 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001642 // We just need the flags from the linker symbol, so put these flags
1643 // into the N_FUN flags to avoid duplicate symbols in the symbol table
1644 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1645 sym[sym_idx].Clear();
1646 continue;
1647 }
Greg Clayton576a68b2010-09-08 16:38:06 +00001648 }
1649 }
Greg Clayton7c36fa02010-09-11 03:13:28 +00001650 else if (type == eSymbolTypeData)
Greg Clayton576a68b2010-09-08 16:38:06 +00001651 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001652 // See if we can find a N_STSYM entry for any data symbols.
1653 // If we do find a match, and the name matches, then we
1654 // can merge the two into just the Static symbol to avoid
1655 // duplicate entries in the symbol table
1656 ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value);
1657 if (pos != N_STSYM_addr_to_sym_idx.end())
Greg Clayton576a68b2010-09-08 16:38:06 +00001658 {
Greg Clayton7c36fa02010-09-11 03:13:28 +00001659 if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) ||
1660 (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName()))
1661 {
Greg Clayton637029b2010-09-12 05:25:16 +00001662 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001663 // We just need the flags from the linker symbol, so put these flags
1664 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
1665 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1666 sym[sym_idx].Clear();
1667 continue;
1668 }
Greg Clayton576a68b2010-09-08 16:38:06 +00001669 }
1670 }
1671 }
Chris Lattner24943d22010-06-08 16:52:24 +00001672 if (symbol_section != NULL)
1673 symbol_value -= symbol_section->GetFileAddress();
1674
1675 sym[sym_idx].SetID (nlist_idx);
1676 sym[sym_idx].SetType (type);
Chris Lattner24943d22010-06-08 16:52:24 +00001677 sym[sym_idx].GetAddressRangeRef().GetBaseAddress().SetSection (symbol_section);
1678 sym[sym_idx].GetAddressRangeRef().GetBaseAddress().SetOffset (symbol_value);
1679 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
1680
1681 ++sym_idx;
1682 }
1683 else
1684 {
1685 sym[sym_idx].Clear();
1686 }
1687
1688 }
1689
Chris Lattner24943d22010-06-08 16:52:24 +00001690 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
1691 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
1692 // such entries by figuring out what the address for the global is by looking up this non-STAB
1693 // entry and copying the value into the debug symbol's value to save us the hassle in the
1694 // debug symbol parser.
1695
1696 Symbol *global_symbol = NULL;
1697 for (nlist_idx = 0;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001698 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001699 nlist_idx++)
1700 {
1701 if (global_symbol->GetValue().GetFileAddress() == 0)
1702 {
1703 std::vector<uint32_t> indexes;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001704 if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001705 {
1706 std::vector<uint32_t>::const_iterator pos;
1707 std::vector<uint32_t>::const_iterator end = indexes.end();
1708 for (pos = indexes.begin(); pos != end; ++pos)
1709 {
1710 symbol_ptr = symtab->SymbolAtIndex(*pos);
1711 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
1712 {
1713 global_symbol->SetValue(symbol_ptr->GetValue());
1714 break;
1715 }
1716 }
1717 }
1718 }
1719 }
Greg Clayton637029b2010-09-12 05:25:16 +00001720
1721 // Trim our symbols down to just what we ended up with after
1722 // removing any symbols.
1723 if (sym_idx < num_syms)
1724 {
1725 num_syms = sym_idx;
1726 sym = symtab->Resize (num_syms);
1727 }
1728
Chris Lattner24943d22010-06-08 16:52:24 +00001729 // Now synthesize indirect symbols
1730 if (m_dysymtab.nindirectsyms != 0)
1731 {
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001732 DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
Chris Lattner24943d22010-06-08 16:52:24 +00001733
Greg Claytondb2dc2b2012-01-12 05:25:17 +00001734 if (indirect_symbol_index_data.GetByteSize())
Chris Lattner24943d22010-06-08 16:52:24 +00001735 {
Greg Clayton637029b2010-09-12 05:25:16 +00001736 NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
Chris Lattner24943d22010-06-08 16:52:24 +00001737
1738 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
1739 {
Greg Clayton1674b122010-07-21 22:12:05 +00001740 if ((m_mach_sections[sect_idx].flags & SectionFlagMaskSectionType) == SectionTypeSymbolStubs)
Chris Lattner24943d22010-06-08 16:52:24 +00001741 {
1742 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
1743 if (symbol_stub_byte_size == 0)
1744 continue;
1745
1746 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;
1747
1748 if (num_symbol_stubs == 0)
1749 continue;
1750
1751 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
Greg Clayton637029b2010-09-12 05:25:16 +00001752 uint32_t synthetic_stub_sym_id = symtab_load_command.nsyms;
Chris Lattner24943d22010-06-08 16:52:24 +00001753 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
1754 {
1755 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
1756 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
1757 uint32_t symbol_stub_offset = symbol_stub_index * 4;
1758 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
1759 {
Greg Clayton637029b2010-09-12 05:25:16 +00001760 const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
Greg Clayton6af4fad2010-10-06 01:26:32 +00001761 if (stub_sym_id & (IndirectSymbolAbsolute | IndirectSymbolLocal))
1762 continue;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001763
Greg Clayton637029b2010-09-12 05:25:16 +00001764 NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
1765 Symbol *stub_symbol = NULL;
Greg Clayton7c36fa02010-09-11 03:13:28 +00001766 if (index_pos != end_index_pos)
Greg Clayton637029b2010-09-12 05:25:16 +00001767 {
1768 // We have a remapping from the original nlist index to
1769 // a current symbol index, so just look this up by index
1770 stub_symbol = symtab->SymbolAtIndex (index_pos->second);
1771 }
1772 else
1773 {
1774 // We need to lookup a symbol using the original nlist
1775 // symbol index since this index is coming from the
1776 // S_SYMBOL_STUBS
1777 stub_symbol = symtab->FindSymbolByID (stub_sym_id);
1778 }
Greg Clayton0ad086f2010-09-07 17:36:17 +00001779
1780 assert (stub_symbol);
Chris Lattner24943d22010-06-08 16:52:24 +00001781 if (stub_symbol)
1782 {
1783 Address so_addr(symbol_stub_addr, section_list);
1784
Greg Claytona1b9a902011-11-13 04:15:56 +00001785 if (stub_symbol->GetType() == eSymbolTypeUndefined)
Chris Lattner24943d22010-06-08 16:52:24 +00001786 {
1787 // Change the external symbol into a trampoline that makes sense
1788 // These symbols were N_UNDF N_EXT, and are useless to us, so we
1789 // can re-use them so we don't have to make up a synthetic symbol
1790 // for no good reason.
1791 stub_symbol->SetType (eSymbolTypeTrampoline);
1792 stub_symbol->SetExternal (false);
1793 stub_symbol->GetAddressRangeRef().GetBaseAddress() = so_addr;
1794 stub_symbol->GetAddressRangeRef().SetByteSize (symbol_stub_byte_size);
1795 }
1796 else
1797 {
1798 // Make a synthetic symbol to describe the trampoline stub
1799 if (sym_idx >= num_syms)
Greg Clayton637029b2010-09-12 05:25:16 +00001800 sym = symtab->Resize (++num_syms);
1801 sym[sym_idx].SetID (synthetic_stub_sym_id++);
Chris Lattner24943d22010-06-08 16:52:24 +00001802 sym[sym_idx].GetMangled() = stub_symbol->GetMangled();
1803 sym[sym_idx].SetType (eSymbolTypeTrampoline);
1804 sym[sym_idx].SetIsSynthetic (true);
1805 sym[sym_idx].GetAddressRangeRef().GetBaseAddress() = so_addr;
1806 sym[sym_idx].GetAddressRangeRef().SetByteSize (symbol_stub_byte_size);
1807 ++sym_idx;
1808 }
1809 }
1810 }
1811 }
1812 }
1813 }
1814 }
1815 }
Chris Lattner24943d22010-06-08 16:52:24 +00001816 return symtab->GetNumSymbols();
1817 }
1818 }
1819 offset = cmd_offset + symtab_load_command.cmdsize;
1820 }
1821 return 0;
1822}
1823
1824
1825void
1826ObjectFileMachO::Dump (Stream *s)
1827{
1828 lldb_private::Mutex::Locker locker(m_mutex);
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001829 s->Printf("%p: ", this);
Chris Lattner24943d22010-06-08 16:52:24 +00001830 s->Indent();
Greg Clayton1674b122010-07-21 22:12:05 +00001831 if (m_header.magic == HeaderMagic64 || m_header.magic == HeaderMagic64Swapped)
Chris Lattner24943d22010-06-08 16:52:24 +00001832 s->PutCString("ObjectFileMachO64");
1833 else
1834 s->PutCString("ObjectFileMachO32");
1835
Greg Claytoncf015052010-06-11 03:25:34 +00001836 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +00001837
Greg Clayton940b1032011-02-23 00:35:02 +00001838 *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
Chris Lattner24943d22010-06-08 16:52:24 +00001839
1840 if (m_sections_ap.get())
Greg Clayton58e844b2010-12-08 05:08:21 +00001841 m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00001842
1843 if (m_symtab_ap.get())
Greg Clayton8d3802d2010-10-08 04:20:14 +00001844 m_symtab_ap->Dump(s, NULL, eSortOrderNone);
Chris Lattner24943d22010-06-08 16:52:24 +00001845}
1846
1847
1848bool
Greg Clayton0467c782011-02-04 18:53:10 +00001849ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
Chris Lattner24943d22010-06-08 16:52:24 +00001850{
1851 lldb_private::Mutex::Locker locker(m_mutex);
1852 struct uuid_command load_cmd;
1853 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1854 uint32_t i;
1855 for (i=0; i<m_header.ncmds; ++i)
1856 {
1857 const uint32_t cmd_offset = offset;
1858 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1859 break;
1860
Greg Clayton1674b122010-07-21 22:12:05 +00001861 if (load_cmd.cmd == LoadCommandUUID)
Chris Lattner24943d22010-06-08 16:52:24 +00001862 {
1863 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
1864 if (uuid_bytes)
1865 {
1866 uuid->SetBytes (uuid_bytes);
1867 return true;
1868 }
1869 return false;
1870 }
1871 offset = cmd_offset + load_cmd.cmdsize;
1872 }
1873 return false;
1874}
1875
1876
1877uint32_t
1878ObjectFileMachO::GetDependentModules (FileSpecList& files)
1879{
1880 lldb_private::Mutex::Locker locker(m_mutex);
1881 struct load_command load_cmd;
1882 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1883 uint32_t count = 0;
Greg Clayton54b38412011-05-24 23:06:02 +00001884 const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
Chris Lattner24943d22010-06-08 16:52:24 +00001885 uint32_t i;
1886 for (i=0; i<m_header.ncmds; ++i)
1887 {
1888 const uint32_t cmd_offset = offset;
1889 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1890 break;
1891
1892 switch (load_cmd.cmd)
1893 {
Greg Clayton1674b122010-07-21 22:12:05 +00001894 case LoadCommandDylibLoad:
1895 case LoadCommandDylibLoadWeak:
1896 case LoadCommandDylibReexport:
1897 case LoadCommandDynamicLinkerLoad:
1898 case LoadCommandFixedVMShlibLoad:
Greg Clayton08a73202010-10-09 00:48:53 +00001899 case LoadCommandDylibLoadUpward:
Chris Lattner24943d22010-06-08 16:52:24 +00001900 {
1901 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
1902 const char *path = m_data.PeekCStr(name_offset);
1903 // Skip any path that starts with '@' since these are usually:
1904 // @executable_path/.../file
1905 // @rpath/.../file
1906 if (path && path[0] != '@')
1907 {
Greg Clayton54b38412011-05-24 23:06:02 +00001908 FileSpec file_spec(path, resolve_path);
Chris Lattner24943d22010-06-08 16:52:24 +00001909 if (files.AppendIfUnique(file_spec))
1910 count++;
1911 }
1912 }
1913 break;
1914
1915 default:
1916 break;
1917 }
1918 offset = cmd_offset + load_cmd.cmdsize;
1919 }
1920 return count;
1921}
1922
Jim Ingham28775942011-03-07 23:44:08 +00001923lldb_private::Address
1924ObjectFileMachO::GetEntryPointAddress ()
1925{
1926 // If the object file is not an executable it can't hold the entry point. m_entry_point_address
1927 // is initialized to an invalid address, so we can just return that.
1928 // If m_entry_point_address is valid it means we've found it already, so return the cached value.
1929
1930 if (!IsExecutable() || m_entry_point_address.IsValid())
1931 return m_entry_point_address;
1932
1933 // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
1934 // /usr/include/mach-o.h, but it is basically:
1935 //
1936 // uint32_t flavor - this is the flavor argument you would pass to thread_get_state
1937 // uint32_t count - this is the count of longs in the thread state data
1938 // struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
1939 // <repeat this trio>
1940 //
1941 // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
1942 // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
1943 // out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
1944 // and we'll also need it for the MacOS X Core File process plugin. When we have that we can also use it here.
1945 //
1946 // For now we hard-code the offsets and flavors we need:
1947 //
1948 //
1949
1950 lldb_private::Mutex::Locker locker(m_mutex);
1951 struct load_command load_cmd;
1952 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
1953 uint32_t i;
1954 lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
1955 bool done = false;
1956
1957 for (i=0; i<m_header.ncmds; ++i)
1958 {
1959 const uint32_t cmd_offset = offset;
1960 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
1961 break;
1962
1963 switch (load_cmd.cmd)
1964 {
1965 case LoadCommandUnixThread:
1966 case LoadCommandThread:
1967 {
1968 while (offset < cmd_offset + load_cmd.cmdsize)
1969 {
1970 uint32_t flavor = m_data.GetU32(&offset);
1971 uint32_t count = m_data.GetU32(&offset);
1972 if (count == 0)
1973 {
1974 // We've gotten off somehow, log and exit;
1975 return m_entry_point_address;
1976 }
1977
1978 switch (m_header.cputype)
1979 {
1980 case llvm::MachO::CPUTypeARM:
1981 if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
1982 {
1983 offset += 60; // This is the offset of pc in the GPR thread state data structure.
1984 start_address = m_data.GetU32(&offset);
1985 done = true;
1986 }
1987 break;
1988 case llvm::MachO::CPUTypeI386:
1989 if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
1990 {
1991 offset += 40; // This is the offset of eip in the GPR thread state data structure.
1992 start_address = m_data.GetU32(&offset);
1993 done = true;
1994 }
1995 break;
1996 case llvm::MachO::CPUTypeX86_64:
1997 if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
1998 {
1999 offset += 16 * 8; // This is the offset of rip in the GPR thread state data structure.
2000 start_address = m_data.GetU64(&offset);
2001 done = true;
2002 }
2003 break;
2004 default:
2005 return m_entry_point_address;
2006 }
2007 // Haven't found the GPR flavor yet, skip over the data for this flavor:
2008 if (done)
2009 break;
2010 offset += count * 4;
2011 }
2012 }
2013 break;
2014
2015 default:
2016 break;
2017 }
2018 if (done)
2019 break;
2020
2021 // Go to the next load command:
2022 offset = cmd_offset + load_cmd.cmdsize;
2023 }
2024
2025 if (start_address != LLDB_INVALID_ADDRESS)
2026 {
2027 // We got the start address from the load commands, so now resolve that address in the sections
2028 // of this ObjectFile:
2029 if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
2030 {
2031 m_entry_point_address.Clear();
2032 }
2033 }
2034 else
2035 {
2036 // We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
2037 // "start" symbol in the main executable.
2038
2039 SymbolContextList contexts;
2040 SymbolContext context;
Sean Callananaa4a5532011-10-13 16:49:47 +00002041 if (!m_module->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
Jim Ingham28775942011-03-07 23:44:08 +00002042 return m_entry_point_address;
2043
2044 contexts.GetContextAtIndex(0, context);
2045
2046 m_entry_point_address = context.symbol->GetValue();
2047 }
2048
2049 return m_entry_point_address;
2050
2051}
2052
Greg Claytonb5a8f142012-02-05 02:38:54 +00002053lldb_private::Address
2054ObjectFileMachO::GetHeaderAddress ()
2055{
2056 lldb_private::Address header_addr;
2057 SectionList *section_list = GetSectionList();
2058 if (section_list)
2059 {
2060 SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
2061 if (text_segment_sp)
2062 {
2063 header_addr.SetSection (text_segment_sp.get());
2064 header_addr.SetOffset (0);
2065 }
2066 }
2067 return header_addr;
2068}
2069
Greg Clayton46c9a352012-02-09 06:16:32 +00002070uint32_t
2071ObjectFileMachO::GetNumThreadContexts ()
2072{
2073 lldb_private::Mutex::Locker locker(m_mutex);
2074 if (!m_thread_context_offsets_valid)
2075 {
2076 m_thread_context_offsets_valid = true;
2077 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
2078 FileRangeArray::Entry file_range;
2079 thread_command thread_cmd;
2080 for (uint32_t i=0; i<m_header.ncmds; ++i)
2081 {
2082 const uint32_t cmd_offset = offset;
2083 if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
2084 break;
2085
2086 if (thread_cmd.cmd == LoadCommandThread)
2087 {
2088 file_range.SetRangeBase (offset);
2089 file_range.SetByteSize (thread_cmd.cmdsize - 8);
2090 m_thread_context_offsets.Append (file_range);
2091 }
2092 offset = cmd_offset + thread_cmd.cmdsize;
2093 }
2094 }
2095 return m_thread_context_offsets.GetSize();
2096}
2097
2098lldb::RegisterContextSP
2099ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
2100{
2101 lldb_private::Mutex::Locker locker(m_mutex);
2102 if (!m_thread_context_offsets_valid)
2103 GetNumThreadContexts ();
2104
2105 lldb::RegisterContextSP reg_ctx_sp;
2106 const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
2107 if (thread_context_file_range)
2108 {
2109 DataExtractor data (m_data,
2110 thread_context_file_range->GetRangeBase(),
2111 thread_context_file_range->GetByteSize());
2112 reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
2113 }
2114 return reg_ctx_sp;
2115}
2116
Greg Claytonb5a8f142012-02-05 02:38:54 +00002117
Greg Claytonca319972011-07-09 00:41:34 +00002118ObjectFile::Type
2119ObjectFileMachO::CalculateType()
2120{
2121 switch (m_header.filetype)
2122 {
2123 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2124 if (GetAddressByteSize () == 4)
2125 {
2126 // 32 bit kexts are just object files, but they do have a valid
2127 // UUID load command.
2128 UUID uuid;
2129 if (GetUUID(&uuid))
2130 {
2131 // this checking for the UUID load command is not enough
2132 // we could eventually look for the symbol named
2133 // "OSKextGetCurrentIdentifier" as this is required of kexts
2134 if (m_strata == eStrataInvalid)
2135 m_strata = eStrataKernel;
2136 return eTypeSharedLibrary;
2137 }
2138 }
2139 return eTypeObjectFile;
2140
2141 case HeaderFileTypeExecutable: return eTypeExecutable; // 0x2u MH_EXECUTE
2142 case HeaderFileTypeFixedVMShlib: return eTypeSharedLibrary; // 0x3u MH_FVMLIB
2143 case HeaderFileTypeCore: return eTypeCoreFile; // 0x4u MH_CORE
2144 case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary; // 0x5u MH_PRELOAD
2145 case HeaderFileTypeDynamicShlib: return eTypeSharedLibrary; // 0x6u MH_DYLIB
2146 case HeaderFileTypeDynamicLinkEditor: return eTypeDynamicLinker; // 0x7u MH_DYLINKER
2147 case HeaderFileTypeBundle: return eTypeSharedLibrary; // 0x8u MH_BUNDLE
2148 case HeaderFileTypeDynamicShlibStub: return eTypeStubLibrary; // 0x9u MH_DYLIB_STUB
2149 case HeaderFileTypeDSYM: return eTypeDebugInfo; // 0xAu MH_DSYM
2150 case HeaderFileTypeKextBundle: return eTypeSharedLibrary; // 0xBu MH_KEXT_BUNDLE
2151 default:
2152 break;
2153 }
2154 return eTypeUnknown;
2155}
2156
2157ObjectFile::Strata
2158ObjectFileMachO::CalculateStrata()
2159{
2160 switch (m_header.filetype)
2161 {
2162 case HeaderFileTypeObject: // 0x1u MH_OBJECT
2163 {
2164 // 32 bit kexts are just object files, but they do have a valid
2165 // UUID load command.
2166 UUID uuid;
2167 if (GetUUID(&uuid))
2168 {
2169 // this checking for the UUID load command is not enough
2170 // we could eventually look for the symbol named
2171 // "OSKextGetCurrentIdentifier" as this is required of kexts
2172 if (m_type == eTypeInvalid)
2173 m_type = eTypeSharedLibrary;
2174
2175 return eStrataKernel;
2176 }
2177 }
2178 return eStrataUnknown;
2179
2180 case HeaderFileTypeExecutable: // 0x2u MH_EXECUTE
2181 // Check for the MH_DYLDLINK bit in the flags
2182 if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
2183 return eStrataUser;
2184 return eStrataKernel;
2185
2186 case HeaderFileTypeFixedVMShlib: return eStrataUser; // 0x3u MH_FVMLIB
2187 case HeaderFileTypeCore: return eStrataUnknown; // 0x4u MH_CORE
2188 case HeaderFileTypePreloadedExecutable: return eStrataUser; // 0x5u MH_PRELOAD
2189 case HeaderFileTypeDynamicShlib: return eStrataUser; // 0x6u MH_DYLIB
2190 case HeaderFileTypeDynamicLinkEditor: return eStrataUser; // 0x7u MH_DYLINKER
2191 case HeaderFileTypeBundle: return eStrataUser; // 0x8u MH_BUNDLE
2192 case HeaderFileTypeDynamicShlibStub: return eStrataUser; // 0x9u MH_DYLIB_STUB
2193 case HeaderFileTypeDSYM: return eStrataUnknown; // 0xAu MH_DSYM
2194 case HeaderFileTypeKextBundle: return eStrataKernel; // 0xBu MH_KEXT_BUNDLE
2195 default:
2196 break;
2197 }
2198 return eStrataUnknown;
2199}
2200
2201
Chris Lattner24943d22010-06-08 16:52:24 +00002202bool
Greg Clayton395fc332011-02-15 21:59:32 +00002203ObjectFileMachO::GetArchitecture (ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +00002204{
2205 lldb_private::Mutex::Locker locker(m_mutex);
Greg Claytonb3448432011-03-24 21:19:54 +00002206 arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
Greg Clayton6a64bbf2011-09-21 03:57:31 +00002207
2208 // Files with type MH_PRELOAD are currently used in cases where the image
2209 // debugs at the addresses in the file itself. Below we set the OS to
2210 // unknown to make sure we use the DynamicLoaderStatic()...
2211 if (m_header.filetype == HeaderFileTypePreloadedExecutable)
2212 {
2213 arch.GetTriple().setOS (llvm::Triple::UnknownOS);
2214 }
2215
Greg Clayton395fc332011-02-15 21:59:32 +00002216 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00002217}
2218
2219
2220//------------------------------------------------------------------
2221// PluginInterface protocol
2222//------------------------------------------------------------------
2223const char *
2224ObjectFileMachO::GetPluginName()
2225{
2226 return "ObjectFileMachO";
2227}
2228
2229const char *
2230ObjectFileMachO::GetShortPluginName()
2231{
2232 return GetPluginNameStatic();
2233}
2234
2235uint32_t
2236ObjectFileMachO::GetPluginVersion()
2237{
2238 return 1;
2239}
2240