1 //===-- 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 10 #include "ObjectFileMachO.h" 11 12 #include <mach-o/nlist.h> 13 #include <mach-o/stab.h> 14 15 #include "lldb/Core/ArchSpec.h" 16 #include "lldb/Core/DataBuffer.h" 17 #include "lldb/Core/FileSpec.h" 18 #include "lldb/Core/FileSpecList.h" 19 #include "lldb/Core/Module.h" 20 #include "lldb/Core/PluginManager.h" 21 #include "lldb/Core/Section.h" 22 #include "lldb/Core/StreamFile.h" 23 #include "lldb/Core/StreamString.h" 24 #include "lldb/Core/Timer.h" 25 #include "lldb/Core/UUID.h" 26 #include "lldb/Symbol/ObjectFile.h" 27 28 #ifndef S_DTRACE_DOF 29 // section contains DTrace Object Format 30 #define S_DTRACE_DOF 0xf 31 #endif 32 33 #ifndef S_LAZY_DYLIB_SYMBOL_POINTERS 34 // section with only lazy symbol pointers to lazy loaded dylibs 35 #define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 36 #endif 37 38 using namespace lldb; 39 using namespace lldb_private; 40 41 42 void 43 ObjectFileMachO::Initialize() 44 { 45 PluginManager::RegisterPlugin (GetPluginNameStatic(), 46 GetPluginDescriptionStatic(), 47 CreateInstance); 48 } 49 50 void 51 ObjectFileMachO::Terminate() 52 { 53 PluginManager::UnregisterPlugin (CreateInstance); 54 } 55 56 57 const char * 58 ObjectFileMachO::GetPluginNameStatic() 59 { 60 return "object-file.mach-o"; 61 } 62 63 const char * 64 ObjectFileMachO::GetPluginDescriptionStatic() 65 { 66 return "Mach-o object file reader (32 and 64 bit)"; 67 } 68 69 70 ObjectFile * 71 ObjectFileMachO::CreateInstance (Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length) 72 { 73 if (ObjectFileMachO::MagicBytesMatch(dataSP)) 74 { 75 std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module, dataSP, file, offset, length)); 76 if (objfile_ap.get() && objfile_ap->ParseHeader()) 77 return objfile_ap.release(); 78 } 79 return NULL; 80 } 81 82 83 static uint32_t 84 MachHeaderSizeFromMagic(uint32_t magic) 85 { 86 switch (magic) 87 { 88 case MH_MAGIC: 89 case MH_CIGAM: 90 return sizeof(struct mach_header); 91 92 case MH_MAGIC_64: 93 case MH_CIGAM_64: 94 return sizeof(struct mach_header_64); 95 break; 96 97 default: 98 break; 99 } 100 return 0; 101 } 102 103 104 bool 105 ObjectFileMachO::MagicBytesMatch (DataBufferSP& dataSP) 106 { 107 DataExtractor data(dataSP, eByteOrderHost, 4); 108 uint32_t offset = 0; 109 uint32_t magic = data.GetU32(&offset); 110 return MachHeaderSizeFromMagic(magic) != 0; 111 } 112 113 114 ObjectFileMachO::ObjectFileMachO(Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length) : 115 ObjectFile(module, file, offset, length, dataSP), 116 m_mutex (Mutex::eMutexTypeRecursive), 117 m_header(), 118 m_sections_ap(), 119 m_symtab_ap() 120 { 121 ::bzero (&m_header, sizeof(m_header)); 122 ::bzero (&m_dysymtab, sizeof(m_dysymtab)); 123 } 124 125 126 ObjectFileMachO::~ObjectFileMachO() 127 { 128 } 129 130 131 bool 132 ObjectFileMachO::ParseHeader () 133 { 134 lldb_private::Mutex::Locker locker(m_mutex); 135 bool can_parse = false; 136 uint32_t offset = 0; 137 m_data.SetByteOrder (eByteOrderHost); 138 // Leave magic in the original byte order 139 m_header.magic = m_data.GetU32(&offset); 140 switch (m_header.magic) 141 { 142 case MH_MAGIC: 143 m_data.SetByteOrder (eByteOrderHost); 144 m_data.SetAddressByteSize(4); 145 can_parse = true; 146 break; 147 148 case MH_MAGIC_64: 149 m_data.SetByteOrder (eByteOrderHost); 150 m_data.SetAddressByteSize(8); 151 can_parse = true; 152 break; 153 154 case MH_CIGAM: 155 m_data.SetByteOrder(eByteOrderHost == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); 156 m_data.SetAddressByteSize(4); 157 can_parse = true; 158 break; 159 160 case MH_CIGAM_64: 161 m_data.SetByteOrder(eByteOrderHost == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); 162 m_data.SetAddressByteSize(8); 163 can_parse = true; 164 break; 165 166 default: 167 break; 168 } 169 170 if (can_parse) 171 { 172 m_data.GetU32(&offset, &m_header.cputype, 6); 173 174 ArchSpec mach_arch(m_header.cputype, m_header.cpusubtype); 175 if (mach_arch == m_module->GetArchitecture()) 176 { 177 // Read in all only the load command data 178 DataBufferSP data_sp(m_file.ReadFileContents(m_offset, m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic))); 179 m_data.SetData (data_sp); 180 return true; 181 } 182 } 183 else 184 { 185 memset(&m_header, 0, sizeof(struct mach_header)); 186 } 187 return false; 188 } 189 190 191 ByteOrder 192 ObjectFileMachO::GetByteOrder () const 193 { 194 lldb_private::Mutex::Locker locker(m_mutex); 195 return m_data.GetByteOrder (); 196 } 197 198 199 size_t 200 ObjectFileMachO::GetAddressByteSize () const 201 { 202 lldb_private::Mutex::Locker locker(m_mutex); 203 return m_data.GetAddressByteSize (); 204 } 205 206 207 Symtab * 208 ObjectFileMachO::GetSymtab() 209 { 210 lldb_private::Mutex::Locker locker(m_mutex); 211 if (m_symtab_ap.get() == NULL) 212 { 213 m_symtab_ap.reset(new Symtab(this)); 214 ParseSymtab(false); 215 } 216 return m_symtab_ap.get(); 217 } 218 219 220 SectionList * 221 ObjectFileMachO::GetSectionList() 222 { 223 lldb_private::Mutex::Locker locker(m_mutex); 224 if (m_sections_ap.get() == NULL) 225 { 226 m_sections_ap.reset(new SectionList()); 227 ParseSections(); 228 } 229 return m_sections_ap.get(); 230 } 231 232 233 size_t 234 ObjectFileMachO::ParseSections () 235 { 236 lldb::user_id_t segID = 0; 237 lldb::user_id_t sectID = 0; 238 struct segment_command_64 load_cmd; 239 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); 240 uint32_t i; 241 //bool dump_sections = false; 242 for (i=0; i<m_header.ncmds; ++i) 243 { 244 const uint32_t load_cmd_offset = offset; 245 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) 246 break; 247 248 if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64) 249 { 250 if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16)) 251 { 252 load_cmd.vmaddr = m_data.GetAddress(&offset); 253 load_cmd.vmsize = m_data.GetAddress(&offset); 254 load_cmd.fileoff = m_data.GetAddress(&offset); 255 load_cmd.filesize = m_data.GetAddress(&offset); 256 if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) 257 { 258 // Keep a list of mach segments around in case we need to 259 // get at data that isn't stored in the abstracted Sections. 260 m_mach_segments.push_back (load_cmd); 261 262 ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname))); 263 // Use a segment ID of the segment index shifted left by 8 so they 264 // never conflict with any of the sections. 265 SectionSP segment_sp; 266 if (segment_name) 267 { 268 segment_sp.reset(new Section (NULL, 269 GetModule(), // Module to which this section belongs 270 ++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 271 segment_name, // Name of this section 272 eSectionTypeContainer, // This section is a container of other sections. 273 load_cmd.vmaddr, // File VM address == addresses as they are found in the object file 274 load_cmd.vmsize, // VM size in bytes of this section 275 load_cmd.fileoff, // Offset to the data for this section in the file 276 load_cmd.filesize, // Size in bytes of this section as found in the the file 277 load_cmd.flags)); // Flags for this section 278 279 m_sections_ap->AddSection(segment_sp); 280 } 281 282 struct section_64 sect64; 283 ::bzero (§64, sizeof(sect64)); 284 // Push a section into our mach sections for the section at 285 // index zero (NO_SECT) 286 m_mach_sections.push_back(sect64); 287 uint32_t segment_sect_idx; 288 const lldb::user_id_t first_segment_sectID = sectID + 1; 289 290 291 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8; 292 for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx) 293 { 294 if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL) 295 break; 296 if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL) 297 break; 298 sect64.addr = m_data.GetAddress(&offset); 299 sect64.size = m_data.GetAddress(&offset); 300 301 if (m_data.GetU32(&offset, §64.offset, num_u32s) == NULL) 302 break; 303 304 // Keep a list of mach sections around in case we need to 305 // get at data that isn't stored in the abstracted Sections. 306 m_mach_sections.push_back (sect64); 307 308 ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname))); 309 if (!segment_name) 310 { 311 // We have a segment with no name so we need to conjure up 312 // segments that correspond to the section's segname if there 313 // isn't already such a section. If there is such a section, 314 // we resize the section so that it spans all sections. 315 // We also mark these sections as fake so address matches don't 316 // hit if they land in the gaps between the child sections. 317 segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname)); 318 segment_sp = m_sections_ap->FindSectionByName (segment_name); 319 if (segment_sp.get()) 320 { 321 Section *segment = segment_sp.get(); 322 // Grow the section size as needed. 323 const lldb::addr_t sect64_min_addr = sect64.addr; 324 const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size; 325 const lldb::addr_t curr_seg_byte_size = segment->GetByteSize(); 326 const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress(); 327 const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size; 328 if (sect64_min_addr >= curr_seg_min_addr) 329 { 330 const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr; 331 // Only grow the section size if needed 332 if (new_seg_byte_size > curr_seg_byte_size) 333 segment->SetByteSize (new_seg_byte_size); 334 } 335 else 336 { 337 // We need to change the base address of the segment and 338 // adjust the child section offsets for all existing children. 339 const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr; 340 segment->Slide(slide_amount, false); 341 segment->GetChildren().Slide (-slide_amount, false); 342 segment->SetByteSize (curr_seg_max_addr - sect64_min_addr); 343 } 344 } 345 else 346 { 347 // Create a fake section for the section's named segment 348 segment_sp.reset(new Section(segment_sp.get(), // Parent section 349 GetModule(), // Module to which this section belongs 350 ++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 351 segment_name, // Name of this section 352 eSectionTypeContainer, // This section is a container of other sections. 353 sect64.addr, // File VM address == addresses as they are found in the object file 354 sect64.size, // VM size in bytes of this section 355 sect64.offset, // Offset to the data for this section in the file 356 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file 357 load_cmd.flags)); // Flags for this section 358 segment_sp->SetIsFake(true); 359 m_sections_ap->AddSection(segment_sp); 360 } 361 } 362 assert (segment_sp.get()); 363 364 uint32_t mach_sect_type = sect64.flags & SECTION_TYPE; 365 static ConstString g_sect_name_objc_data ("__objc_data"); 366 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs"); 367 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs"); 368 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs"); 369 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs"); 370 static ConstString g_sect_name_objc_const ("__objc_const"); 371 static ConstString g_sect_name_objc_classlist ("__objc_classlist"); 372 static ConstString g_sect_name_cfstring ("__cfstring"); 373 SectionType sect_type = eSectionTypeOther; 374 375 if (section_name == g_sect_name_objc_selrefs) 376 { 377 sect_type = eSectionTypeDataCStringPointers; 378 } 379 else if (section_name == g_sect_name_objc_msgrefs) 380 { 381 sect_type = eSectionTypeDataObjCMessageRefs; 382 } 383 else if (section_name == g_sect_name_objc_data || 384 section_name == g_sect_name_objc_classrefs || 385 section_name == g_sect_name_objc_superrefs || 386 section_name == g_sect_name_objc_const || 387 section_name == g_sect_name_objc_classlist) 388 { 389 sect_type = eSectionTypeDataPointers; 390 } 391 else if (section_name == g_sect_name_cfstring) 392 { 393 sect_type = eSectionTypeDataObjCCFStrings; 394 } 395 396 if (sect_type == eSectionTypeOther) 397 { 398 switch (mach_sect_type) 399 { 400 // TODO: categorize sections by other flags for regular sections 401 case S_REGULAR: 402 403 sect_type = eSectionTypeOther; 404 break; 405 case S_ZEROFILL: sect_type = eSectionTypeZeroFill; break; 406 case S_CSTRING_LITERALS: sect_type = eSectionTypeDataCString; break; // section with only literal C strings 407 case S_4BYTE_LITERALS: sect_type = eSectionTypeData4; break; // section with only 4 byte literals 408 case S_8BYTE_LITERALS: sect_type = eSectionTypeData8; break; // section with only 8 byte literals 409 case S_LITERAL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals 410 case S_NON_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers 411 case S_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers 412 case S_SYMBOL_STUBS: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field 413 case S_MOD_INIT_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization 414 case S_MOD_TERM_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination 415 case S_COALESCED: sect_type = eSectionTypeOther; break; 416 case S_GB_ZEROFILL: sect_type = eSectionTypeZeroFill; break; 417 case S_INTERPOSING: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing 418 case S_16BYTE_LITERALS: sect_type = eSectionTypeData16; break; // section with only 16 byte literals 419 case S_DTRACE_DOF: sect_type = eSectionTypeDebug; break; 420 case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; 421 default: break; 422 } 423 } 424 425 SectionSP section_sp(new Section(segment_sp.get(), 426 GetModule(), 427 ++sectID, 428 section_name, 429 sect_type, 430 sect64.addr - segment_sp->GetFileAddress(), 431 sect64.size, 432 sect64.offset, 433 sect64.offset == 0 ? 0 : sect64.size, 434 sect64.flags)); 435 segment_sp->GetChildren().AddSection(section_sp); 436 437 if (segment_sp->IsFake()) 438 { 439 segment_sp.reset(); 440 segment_name.Clear(); 441 } 442 } 443 if (m_header.filetype == MH_DSYM) 444 { 445 if (first_segment_sectID <= sectID) 446 { 447 lldb::user_id_t sect_uid; 448 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid) 449 { 450 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid)); 451 SectionSP next_section_sp; 452 if (sect_uid + 1 <= sectID) 453 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1); 454 455 if (curr_section_sp.get()) 456 { 457 if (curr_section_sp->GetByteSize() == 0) 458 { 459 if (next_section_sp.get() != NULL) 460 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() ); 461 else 462 curr_section_sp->SetByteSize ( load_cmd.vmsize ); 463 } 464 } 465 } 466 } 467 } 468 } 469 } 470 } 471 else if (load_cmd.cmd == LC_DYSYMTAB) 472 { 473 m_dysymtab.cmd = load_cmd.cmd; 474 m_dysymtab.cmdsize = load_cmd.cmdsize; 475 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2); 476 } 477 478 offset = load_cmd_offset + load_cmd.cmdsize; 479 } 480 // if (dump_sections) 481 // { 482 // StreamFile s(stdout); 483 // m_sections_ap->Dump(&s, true); 484 // } 485 return sectID; // Return the number of sections we registered with the module 486 } 487 488 class MachSymtabSectionInfo 489 { 490 public: 491 492 MachSymtabSectionInfo (SectionList *section_list) : 493 m_section_list (section_list), 494 m_section_infos() 495 { 496 // Get the number of sections down to a depth of 1 to include 497 // all segments and their sections, but no other sections that 498 // may be added for debug map or 499 m_section_infos.resize(section_list->GetNumSections(1)); 500 } 501 502 503 Section * 504 GetSection (uint8_t n_sect, addr_t file_addr) 505 { 506 if (n_sect == 0) 507 return NULL; 508 if (n_sect < m_section_infos.size()) 509 { 510 if (m_section_infos[n_sect].section == NULL) 511 { 512 Section *section = m_section_list->FindSectionByID (n_sect).get(); 513 m_section_infos[n_sect].section = section; 514 assert (section != NULL); 515 m_section_infos[n_sect].vm_range.SetBaseAddress (section->GetFileAddress()); 516 m_section_infos[n_sect].vm_range.SetByteSize (section->GetByteSize()); 517 } 518 if (m_section_infos[n_sect].vm_range.Contains(file_addr)) 519 return m_section_infos[n_sect].section; 520 } 521 return m_section_list->FindSectionContainingFileAddress(file_addr).get(); 522 } 523 524 protected: 525 struct SectionInfo 526 { 527 SectionInfo () : 528 vm_range(), 529 section (NULL) 530 { 531 } 532 533 VMRange vm_range; 534 Section *section; 535 }; 536 SectionList *m_section_list; 537 std::vector<SectionInfo> m_section_infos; 538 }; 539 540 541 542 size_t 543 ObjectFileMachO::ParseSymtab (bool minimize) 544 { 545 Timer scoped_timer(__PRETTY_FUNCTION__, 546 "ObjectFileMachO::ParseSymtab () module = %s", 547 m_file.GetFilename().AsCString("")); 548 struct symtab_command symtab_load_command; 549 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); 550 uint32_t i; 551 for (i=0; i<m_header.ncmds; ++i) 552 { 553 const uint32_t cmd_offset = offset; 554 // Read in the load command and load command size 555 if (m_data.GetU32(&offset, &symtab_load_command, 2) == NULL) 556 break; 557 // Watch for the symbol table load command 558 if (symtab_load_command.cmd == LC_SYMTAB) 559 { 560 // Read in the rest of the symtab load command 561 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4)) 562 { 563 Symtab *symtab = m_symtab_ap.get(); 564 SectionList *section_list = GetSectionList(); 565 assert(section_list); 566 const size_t addr_size = m_data.GetAddressByteSize(); 567 const ByteOrder endian = m_data.GetByteOrder(); 568 bool bit_width_32 = addr_size == 4; 569 const size_t nlist_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64); 570 571 DataBufferSP symtab_data_sp(m_file.ReadFileContents(m_offset + symtab_load_command.symoff, symtab_load_command.nsyms * nlist_size)); 572 DataBufferSP strtab_data_sp(m_file.ReadFileContents(m_offset + symtab_load_command.stroff, symtab_load_command.strsize)); 573 574 const char *strtab_data = (const char *)strtab_data_sp->GetBytes(); 575 // DataExtractor symtab_data(symtab_data_sp, endian, addr_size); 576 // DataExtractor strtab_data(strtab_data_sp, endian, addr_size); 577 578 static ConstString g_segment_name_TEXT ("__TEXT"); 579 static ConstString g_segment_name_DATA ("__DATA"); 580 static ConstString g_segment_name_OBJC ("__OBJC"); 581 static ConstString g_section_name_eh_frame ("__eh_frame"); 582 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT)); 583 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA)); 584 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC)); 585 SectionSP eh_frame_section_sp; 586 if (text_section_sp.get()) 587 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame); 588 else 589 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame); 590 591 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NO_SECT; 592 //uint32_t symtab_offset = 0; 593 const uint8_t* nlist_data = symtab_data_sp->GetBytes(); 594 assert (symtab_data_sp->GetByteSize()/nlist_size >= symtab_load_command.nsyms); 595 596 597 if (endian != eByteOrderHost) 598 { 599 // ... 600 assert (!"UNIMPLEMENTED: Swap all nlist entries"); 601 } 602 uint32_t N_SO_index = UINT_MAX; 603 604 MachSymtabSectionInfo section_info (section_list); 605 std::vector<uint32_t> N_FUN_indexes; 606 std::vector<uint32_t> N_NSYM_indexes; 607 std::vector<uint32_t> N_INCL_indexes; 608 std::vector<uint32_t> N_BRAC_indexes; 609 std::vector<uint32_t> N_COMM_indexes; 610 uint32_t nlist_idx = 0; 611 Symbol *symbol_ptr = NULL; 612 613 uint32_t sym_idx = 0; 614 Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms); 615 uint32_t num_syms = symtab->GetNumSymbols(); 616 617 //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms); 618 for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) 619 { 620 struct nlist_64 nlist; 621 if (bit_width_32) 622 { 623 struct nlist* nlist32_ptr = (struct nlist*)(nlist_data + (nlist_idx * nlist_size)); 624 nlist.n_un.n_strx = nlist32_ptr->n_un.n_strx; 625 nlist.n_type = nlist32_ptr->n_type; 626 nlist.n_sect = nlist32_ptr->n_sect; 627 nlist.n_desc = nlist32_ptr->n_desc; 628 nlist.n_value = nlist32_ptr->n_value; 629 } 630 else 631 { 632 nlist = *((struct nlist_64*)(nlist_data + (nlist_idx * nlist_size))); 633 } 634 635 SymbolType type = eSymbolTypeInvalid; 636 const char* symbol_name = &strtab_data[nlist.n_un.n_strx]; 637 if (symbol_name[0] == '\0') 638 symbol_name = NULL; 639 Section* symbol_section = NULL; 640 bool add_nlist = true; 641 bool is_debug = ((nlist.n_type & N_STAB) != 0); 642 643 assert (sym_idx < num_syms); 644 645 sym[sym_idx].SetDebug (is_debug); 646 647 if (is_debug) 648 { 649 switch (nlist.n_type) 650 { 651 case N_GSYM: // global symbol: name,,NO_SECT,type,0 652 // Sometimes the N_GSYM value contains the address. 653 if (nlist.n_value != 0) 654 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 655 type = eSymbolTypeGlobal; 656 break; 657 658 case N_FNAME: // procedure name (f77 kludge): name,,NO_SECT,0,0 659 type = eSymbolTypeFunction; 660 break; 661 662 case N_FUN: // procedure: name,,n_sect,linenumber,address 663 if (symbol_name) 664 { 665 type = eSymbolTypeFunction; 666 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 667 // We use the current number of symbols in the symbol table in lieu of 668 // using nlist_idx in case we ever start trimming entries out 669 N_FUN_indexes.push_back(sym_idx); 670 } 671 else 672 { 673 type = eSymbolTypeFunctionEnd; 674 675 if ( !N_FUN_indexes.empty() ) 676 { 677 // Copy the size of the function into the original STAB entry so we don't have 678 // to hunt for it later 679 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value); 680 N_FUN_indexes.pop_back(); 681 // We dont' really need the end function STAB as it contains the size which 682 // we already placed with the original symbol, so don't add it if we want a 683 // minimal symbol table 684 if (minimize) 685 add_nlist = false; 686 } 687 } 688 break; 689 690 case N_STSYM: // static symbol: name,,n_sect,type,address 691 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 692 type = eSymbolTypeStatic; 693 break; 694 695 case N_LCSYM: // .lcomm symbol: name,,n_sect,type,address 696 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 697 type = eSymbolTypeCommonBlock; 698 break; 699 700 case N_BNSYM: 701 // We use the current number of symbols in the symbol table in lieu of 702 // using nlist_idx in case we ever start trimming entries out 703 if (minimize) 704 { 705 // Skip these if we want minimal symbol tables 706 add_nlist = false; 707 } 708 else 709 { 710 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 711 N_NSYM_indexes.push_back(sym_idx); 712 type = eSymbolTypeScopeBegin; 713 } 714 break; 715 716 case N_ENSYM: 717 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM 718 // so that we can always skip the entire symbol if we need to navigate 719 // more quickly at the source level when parsing STABS 720 if (minimize) 721 { 722 // Skip these if we want minimal symbol tables 723 add_nlist = false; 724 } 725 else 726 { 727 if ( !N_NSYM_indexes.empty() ) 728 { 729 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back()); 730 symbol_ptr->SetByteSize(sym_idx + 1); 731 symbol_ptr->SetSizeIsSibling(true); 732 N_NSYM_indexes.pop_back(); 733 } 734 type = eSymbolTypeScopeEnd; 735 } 736 break; 737 738 739 case N_OPT: // emitted with gcc2_compiled and in gcc source 740 type = eSymbolTypeCompiler; 741 break; 742 743 case N_RSYM: // register sym: name,,NO_SECT,type,register 744 type = eSymbolTypeVariable; 745 break; 746 747 case N_SLINE: // src line: 0,,n_sect,linenumber,address 748 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 749 type = eSymbolTypeLineEntry; 750 break; 751 752 case N_SSYM: // structure elt: name,,NO_SECT,type,struct_offset 753 type = eSymbolTypeVariableType; 754 break; 755 756 case N_SO: 757 type = eSymbolTypeSourceFile; 758 if (symbol_name == NULL) 759 { 760 if (N_SO_index == UINT_MAX) 761 { 762 // Skip the extra blank N_SO entries that happen when the entire 763 // path is contained in the second consecutive N_SO STAB. 764 if (minimize) 765 add_nlist = false; 766 } 767 else 768 { 769 // Set the size of the N_SO to the terminating index of this N_SO 770 // so that we can always skip the entire N_SO if we need to navigate 771 // more quickly at the source level when parsing STABS 772 symbol_ptr = symtab->SymbolAtIndex(N_SO_index); 773 symbol_ptr->SetByteSize(sym_idx + 1); 774 symbol_ptr->SetSizeIsSibling(true); 775 } 776 N_NSYM_indexes.clear(); 777 N_INCL_indexes.clear(); 778 N_BRAC_indexes.clear(); 779 N_COMM_indexes.clear(); 780 N_FUN_indexes.clear(); 781 N_SO_index = UINT_MAX; 782 } 783 else if (symbol_name[0] == '/') 784 { 785 // We use the current number of symbols in the symbol table in lieu of 786 // using nlist_idx in case we ever start trimming entries out 787 N_SO_index = sym_idx; 788 } 789 break; 790 791 case N_OSO: // object file name: name,,0,0,st_mtime 792 type = eSymbolTypeObjectFile; 793 break; 794 795 case N_LSYM: // local sym: name,,NO_SECT,type,offset 796 type = eSymbolTypeLocal; 797 break; 798 799 //---------------------------------------------------------------------- 800 // INCL scopes 801 //---------------------------------------------------------------------- 802 case N_BINCL: // include file beginning: name,,NO_SECT,0,sum 803 // We use the current number of symbols in the symbol table in lieu of 804 // using nlist_idx in case we ever start trimming entries out 805 N_INCL_indexes.push_back(sym_idx); 806 type = eSymbolTypeScopeBegin; 807 break; 808 case N_EINCL: // include file end: name,,NO_SECT,0,0 809 810 // Set the size of the N_BINCL to the terminating index of this N_EINCL 811 // so that we can always skip the entire symbol if we need to navigate 812 // more quickly at the source level when parsing STABS 813 if ( !N_INCL_indexes.empty() ) 814 { 815 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back()); 816 symbol_ptr->SetByteSize(sym_idx + 1); 817 symbol_ptr->SetSizeIsSibling(true); 818 N_INCL_indexes.pop_back(); 819 } 820 type = eSymbolTypeScopeEnd; 821 break; 822 823 case N_SOL: // #included file name: name,,n_sect,0,address 824 type = eSymbolTypeHeaderFile; 825 break; 826 827 case N_PARAMS: // compiler parameters: name,,NO_SECT,0,0 828 type = eSymbolTypeCompiler; 829 break; 830 831 case N_VERSION: // compiler version: name,,NO_SECT,0,0 832 type = eSymbolTypeCompiler; 833 break; 834 835 case N_OLEVEL: // compiler -O level: name,,NO_SECT,0,0 836 type = eSymbolTypeCompiler; 837 break; 838 839 case N_PSYM: // parameter: name,,NO_SECT,type,offset 840 type = eSymbolTypeVariable; 841 break; 842 843 case N_ENTRY: // alternate entry: name,,n_sect,linenumber,address 844 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 845 type = eSymbolTypeLineEntry; 846 break; 847 848 //---------------------------------------------------------------------- 849 // Left and Right Braces 850 //---------------------------------------------------------------------- 851 case N_LBRAC: // left bracket: 0,,NO_SECT,nesting level,address 852 // We use the current number of symbols in the symbol table in lieu of 853 // using nlist_idx in case we ever start trimming entries out 854 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 855 N_BRAC_indexes.push_back(sym_idx); 856 type = eSymbolTypeScopeBegin; 857 break; 858 859 case N_RBRAC: // right bracket: 0,,NO_SECT,nesting level,address 860 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC 861 // so that we can always skip the entire symbol if we need to navigate 862 // more quickly at the source level when parsing STABS 863 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 864 if ( !N_BRAC_indexes.empty() ) 865 { 866 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back()); 867 symbol_ptr->SetByteSize(sym_idx + 1); 868 symbol_ptr->SetSizeIsSibling(true); 869 N_BRAC_indexes.pop_back(); 870 } 871 type = eSymbolTypeScopeEnd; 872 break; 873 874 case N_EXCL: // deleted include file: name,,NO_SECT,0,sum 875 type = eSymbolTypeHeaderFile; 876 break; 877 878 //---------------------------------------------------------------------- 879 // COMM scopes 880 //---------------------------------------------------------------------- 881 case N_BCOMM: // begin common: name,,NO_SECT,0,0 882 // We use the current number of symbols in the symbol table in lieu of 883 // using nlist_idx in case we ever start trimming entries out 884 type = eSymbolTypeScopeBegin; 885 N_COMM_indexes.push_back(sym_idx); 886 break; 887 888 case N_ECOML: // end common (local name): 0,,n_sect,0,address 889 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 890 // Fall through 891 892 case N_ECOMM: // end common: name,,n_sect,0,0 893 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML 894 // so that we can always skip the entire symbol if we need to navigate 895 // more quickly at the source level when parsing STABS 896 if ( !N_COMM_indexes.empty() ) 897 { 898 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back()); 899 symbol_ptr->SetByteSize(sym_idx + 1); 900 symbol_ptr->SetSizeIsSibling(true); 901 N_COMM_indexes.pop_back(); 902 } 903 type = eSymbolTypeScopeEnd; 904 break; 905 906 case N_LENG: // second stab entry with length information 907 type = eSymbolTypeAdditional; 908 break; 909 910 default: break; 911 } 912 } 913 else 914 { 915 //uint8_t n_pext = N_PEXT & nlist.n_type; 916 uint8_t n_type = N_TYPE & nlist.n_type; 917 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0); 918 919 if (symbol_name && ::strstr (symbol_name, ".objc") == symbol_name) 920 { 921 type = eSymbolTypeRuntime; 922 } 923 else 924 { 925 switch (n_type) 926 { 927 case N_INDR: // Fall through 928 case N_PBUD: // Fall through 929 case N_UNDF: 930 type = eSymbolTypeExtern; 931 break; 932 933 case N_ABS: 934 type = eSymbolTypeAbsolute; 935 break; 936 937 case N_SECT: 938 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 939 940 assert(symbol_section != NULL); 941 if (TEXT_eh_frame_sectID == nlist.n_sect) 942 { 943 type = eSymbolTypeException; 944 } 945 else 946 { 947 uint32_t section_type = symbol_section->GetAllFlagBits() & SECTION_TYPE; 948 949 switch (section_type) 950 { 951 case S_REGULAR: break; // regular section 952 //case S_ZEROFILL: type = eSymbolTypeData; break; // zero fill on demand section 953 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings 954 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals 955 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals 956 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals 957 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers 958 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers 959 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field 960 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization 961 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination 962 //case S_COALESCED: type = eSymbolType; break; // section contains symbols that are to be coalesced 963 //case S_GB_ZEROFILL: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes) 964 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing 965 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals 966 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break; 967 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; 968 default: break; 969 } 970 971 if (type == eSymbolTypeInvalid) 972 { 973 const char *symbol_sect_name = symbol_section->GetName().AsCString(); 974 if (symbol_section->IsDescendant (text_section_sp.get())) 975 { 976 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE | S_ATTR_SOME_INSTRUCTIONS)) 977 type = eSymbolTypeData; 978 else 979 type = eSymbolTypeCode; 980 } 981 else 982 if (symbol_section->IsDescendant(data_section_sp.get())) 983 { 984 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name) 985 { 986 type = eSymbolTypeRuntime; 987 } 988 else 989 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name) 990 { 991 type = eSymbolTypeException; 992 } 993 else 994 { 995 type = eSymbolTypeData; 996 } 997 } 998 else 999 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name) 1000 { 1001 type = eSymbolTypeTrampoline; 1002 } 1003 else 1004 if (symbol_section->IsDescendant(objc_section_sp.get())) 1005 { 1006 type = eSymbolTypeRuntime; 1007 } 1008 } 1009 } 1010 break; 1011 } 1012 } 1013 } 1014 1015 if (add_nlist) 1016 { 1017 bool symbol_name_is_mangled = false; 1018 if (symbol_name && symbol_name[0] == '_') 1019 { 1020 symbol_name_is_mangled = symbol_name[1] == '_'; 1021 symbol_name++; // Skip the leading underscore 1022 } 1023 uint64_t symbol_value = nlist.n_value; 1024 if (symbol_section != NULL) 1025 symbol_value -= symbol_section->GetFileAddress(); 1026 1027 sym[sym_idx].SetID (nlist_idx); 1028 sym[sym_idx].SetType (type); 1029 if (symbol_name) 1030 sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled); 1031 sym[sym_idx].GetAddressRangeRef().GetBaseAddress().SetSection (symbol_section); 1032 sym[sym_idx].GetAddressRangeRef().GetBaseAddress().SetOffset (symbol_value); 1033 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc); 1034 1035 ++sym_idx; 1036 } 1037 else 1038 { 1039 sym[sym_idx].Clear(); 1040 } 1041 1042 } 1043 1044 1045 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value 1046 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all 1047 // such entries by figuring out what the address for the global is by looking up this non-STAB 1048 // entry and copying the value into the debug symbol's value to save us the hassle in the 1049 // debug symbol parser. 1050 1051 Symbol *global_symbol = NULL; 1052 for (nlist_idx = 0; 1053 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType(eSymbolTypeGlobal, nlist_idx)) != NULL; 1054 nlist_idx++) 1055 { 1056 if (global_symbol->GetValue().GetFileAddress() == 0) 1057 { 1058 std::vector<uint32_t> indexes; 1059 if (symtab->AppendSymbolIndexesWithName(global_symbol->GetMangled().GetName(), indexes) > 0) 1060 { 1061 std::vector<uint32_t>::const_iterator pos; 1062 std::vector<uint32_t>::const_iterator end = indexes.end(); 1063 for (pos = indexes.begin(); pos != end; ++pos) 1064 { 1065 symbol_ptr = symtab->SymbolAtIndex(*pos); 1066 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false) 1067 { 1068 global_symbol->SetValue(symbol_ptr->GetValue()); 1069 break; 1070 } 1071 } 1072 } 1073 } 1074 } 1075 // Now synthesize indirect symbols 1076 if (m_dysymtab.nindirectsyms != 0) 1077 { 1078 DataBufferSP indirect_symbol_indexes_sp(m_file.ReadFileContents(m_offset + m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4)); 1079 1080 if (indirect_symbol_indexes_sp && indirect_symbol_indexes_sp->GetByteSize()) 1081 { 1082 DataExtractor indirect_symbol_index_data (indirect_symbol_indexes_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize()); 1083 1084 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx) 1085 { 1086 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS) 1087 { 1088 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2; 1089 if (symbol_stub_byte_size == 0) 1090 continue; 1091 1092 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size; 1093 1094 if (num_symbol_stubs == 0) 1095 continue; 1096 1097 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1; 1098 uint32_t stub_sym_id = symtab_load_command.nsyms; 1099 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) 1100 { 1101 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx; 1102 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size); 1103 uint32_t symbol_stub_offset = symbol_stub_index * 4; 1104 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4)) 1105 { 1106 const uint32_t symbol_index = indirect_symbol_index_data.GetU32 (&symbol_stub_offset); 1107 1108 Symbol *stub_symbol = symtab->SymbolAtIndex(symbol_index); 1109 if (stub_symbol) 1110 { 1111 Address so_addr(symbol_stub_addr, section_list); 1112 1113 if (stub_symbol->GetType() == eSymbolTypeExtern) 1114 { 1115 // Change the external symbol into a trampoline that makes sense 1116 // These symbols were N_UNDF N_EXT, and are useless to us, so we 1117 // can re-use them so we don't have to make up a synthetic symbol 1118 // for no good reason. 1119 stub_symbol->SetType (eSymbolTypeTrampoline); 1120 stub_symbol->SetExternal (false); 1121 stub_symbol->GetAddressRangeRef().GetBaseAddress() = so_addr; 1122 stub_symbol->GetAddressRangeRef().SetByteSize (symbol_stub_byte_size); 1123 } 1124 else 1125 { 1126 // Make a synthetic symbol to describe the trampoline stub 1127 if (sym_idx >= num_syms) 1128 { 1129 sym = symtab->Resize (num_syms + 16); 1130 num_syms = symtab->GetNumSymbols(); 1131 } 1132 sym[sym_idx].SetID (stub_sym_id++); 1133 sym[sym_idx].GetMangled() = stub_symbol->GetMangled(); 1134 sym[sym_idx].SetType (eSymbolTypeTrampoline); 1135 sym[sym_idx].SetIsSynthetic (true); 1136 sym[sym_idx].GetAddressRangeRef().GetBaseAddress() = so_addr; 1137 sym[sym_idx].GetAddressRangeRef().SetByteSize (symbol_stub_byte_size); 1138 ++sym_idx; 1139 } 1140 } 1141 } 1142 } 1143 } 1144 } 1145 } 1146 } 1147 1148 if (sym_idx != symtab->GetNumSymbols()) 1149 symtab->Resize (sym_idx); 1150 1151 return symtab->GetNumSymbols(); 1152 } 1153 } 1154 offset = cmd_offset + symtab_load_command.cmdsize; 1155 } 1156 return 0; 1157 } 1158 1159 1160 void 1161 ObjectFileMachO::Dump (Stream *s) 1162 { 1163 lldb_private::Mutex::Locker locker(m_mutex); 1164 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 1165 s->Indent(); 1166 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64) 1167 s->PutCString("ObjectFileMachO64"); 1168 else 1169 s->PutCString("ObjectFileMachO32"); 1170 1171 ArchSpec header_arch(m_header.cputype, m_header.cpusubtype); 1172 1173 *s << ", file = '" << m_file << "', arch = " << header_arch.AsCString() << "\n"; 1174 1175 if (m_sections_ap.get()) 1176 m_sections_ap->Dump(s, NULL, true); 1177 1178 if (m_symtab_ap.get()) 1179 m_symtab_ap->Dump(s, NULL); 1180 } 1181 1182 1183 bool 1184 ObjectFileMachO::GetUUID (UUID* uuid) 1185 { 1186 lldb_private::Mutex::Locker locker(m_mutex); 1187 struct uuid_command load_cmd; 1188 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); 1189 uint32_t i; 1190 for (i=0; i<m_header.ncmds; ++i) 1191 { 1192 const uint32_t cmd_offset = offset; 1193 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) 1194 break; 1195 1196 if (load_cmd.cmd == LC_UUID) 1197 { 1198 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16); 1199 if (uuid_bytes) 1200 { 1201 uuid->SetBytes (uuid_bytes); 1202 return true; 1203 } 1204 return false; 1205 } 1206 offset = cmd_offset + load_cmd.cmdsize; 1207 } 1208 return false; 1209 } 1210 1211 1212 uint32_t 1213 ObjectFileMachO::GetDependentModules (FileSpecList& files) 1214 { 1215 lldb_private::Mutex::Locker locker(m_mutex); 1216 struct load_command load_cmd; 1217 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); 1218 uint32_t count = 0; 1219 uint32_t i; 1220 for (i=0; i<m_header.ncmds; ++i) 1221 { 1222 const uint32_t cmd_offset = offset; 1223 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) 1224 break; 1225 1226 switch (load_cmd.cmd) 1227 { 1228 case LC_LOAD_DYLIB: 1229 case LC_LOAD_WEAK_DYLIB: 1230 case LC_REEXPORT_DYLIB: 1231 case LC_LOAD_DYLINKER: 1232 case LC_LOADFVMLIB: 1233 { 1234 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); 1235 const char *path = m_data.PeekCStr(name_offset); 1236 // Skip any path that starts with '@' since these are usually: 1237 // @executable_path/.../file 1238 // @rpath/.../file 1239 if (path && path[0] != '@') 1240 { 1241 FileSpec file_spec(path); 1242 if (files.AppendIfUnique(file_spec)) 1243 count++; 1244 } 1245 } 1246 break; 1247 1248 default: 1249 break; 1250 } 1251 offset = cmd_offset + load_cmd.cmdsize; 1252 } 1253 return count; 1254 } 1255 1256 bool 1257 ObjectFileMachO::GetTargetTriple (ConstString &target_triple) 1258 { 1259 lldb_private::Mutex::Locker locker(m_mutex); 1260 std::string triple(GetModule()->GetArchitecture().AsCString()); 1261 triple += "-apple-darwin"; 1262 target_triple.SetCString(triple.c_str()); 1263 if (target_triple) 1264 return true; 1265 return false; 1266 } 1267 1268 1269 //------------------------------------------------------------------ 1270 // PluginInterface protocol 1271 //------------------------------------------------------------------ 1272 const char * 1273 ObjectFileMachO::GetPluginName() 1274 { 1275 return "ObjectFileMachO"; 1276 } 1277 1278 const char * 1279 ObjectFileMachO::GetShortPluginName() 1280 { 1281 return GetPluginNameStatic(); 1282 } 1283 1284 uint32_t 1285 ObjectFileMachO::GetPluginVersion() 1286 { 1287 return 1; 1288 } 1289 1290 void 1291 ObjectFileMachO::GetPluginCommandHelp (const char *command, Stream *strm) 1292 { 1293 } 1294 1295 Error 1296 ObjectFileMachO::ExecutePluginCommand (Args &command, Stream *strm) 1297 { 1298 Error error; 1299 error.SetErrorString("No plug-in command are currently supported."); 1300 return error; 1301 } 1302 1303 Log * 1304 ObjectFileMachO::EnablePluginLogging (Stream *strm, Args &command) 1305 { 1306 return NULL; 1307 } 1308 1309 1310 1311 1312