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(eArchTypeMachO, 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 // Grow the section size as needed. 346 if (sect64.offset) 347 { 348 const lldb::addr_t segment_min_file_offset = segment->GetFileOffset(); 349 const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize(); 350 351 const lldb::addr_t section_min_file_offset = sect64.offset; 352 const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size; 353 const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset); 354 const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset; 355 segment->SetFileOffset (new_file_offset); 356 segment->SetFileSize (new_file_size); 357 } 358 } 359 else 360 { 361 // Create a fake section for the section's named segment 362 segment_sp.reset(new Section(segment_sp.get(), // Parent section 363 GetModule(), // Module to which this section belongs 364 ++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 365 segment_name, // Name of this section 366 eSectionTypeContainer, // This section is a container of other sections. 367 sect64.addr, // File VM address == addresses as they are found in the object file 368 sect64.size, // VM size in bytes of this section 369 sect64.offset, // Offset to the data for this section in the file 370 sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file 371 load_cmd.flags)); // Flags for this section 372 segment_sp->SetIsFake(true); 373 m_sections_ap->AddSection(segment_sp); 374 } 375 } 376 assert (segment_sp.get()); 377 378 uint32_t mach_sect_type = sect64.flags & SECTION_TYPE; 379 static ConstString g_sect_name_objc_data ("__objc_data"); 380 static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs"); 381 static ConstString g_sect_name_objc_selrefs ("__objc_selrefs"); 382 static ConstString g_sect_name_objc_classrefs ("__objc_classrefs"); 383 static ConstString g_sect_name_objc_superrefs ("__objc_superrefs"); 384 static ConstString g_sect_name_objc_const ("__objc_const"); 385 static ConstString g_sect_name_objc_classlist ("__objc_classlist"); 386 static ConstString g_sect_name_cfstring ("__cfstring"); 387 SectionType sect_type = eSectionTypeOther; 388 389 if (section_name == g_sect_name_objc_selrefs) 390 { 391 sect_type = eSectionTypeDataCStringPointers; 392 } 393 else if (section_name == g_sect_name_objc_msgrefs) 394 { 395 sect_type = eSectionTypeDataObjCMessageRefs; 396 } 397 else if (section_name == g_sect_name_objc_data || 398 section_name == g_sect_name_objc_classrefs || 399 section_name == g_sect_name_objc_superrefs || 400 section_name == g_sect_name_objc_const || 401 section_name == g_sect_name_objc_classlist) 402 { 403 sect_type = eSectionTypeDataPointers; 404 } 405 else if (section_name == g_sect_name_cfstring) 406 { 407 sect_type = eSectionTypeDataObjCCFStrings; 408 } 409 410 if (sect_type == eSectionTypeOther) 411 { 412 switch (mach_sect_type) 413 { 414 // TODO: categorize sections by other flags for regular sections 415 case S_REGULAR: 416 417 sect_type = eSectionTypeOther; 418 break; 419 case S_ZEROFILL: sect_type = eSectionTypeZeroFill; break; 420 case S_CSTRING_LITERALS: sect_type = eSectionTypeDataCString; break; // section with only literal C strings 421 case S_4BYTE_LITERALS: sect_type = eSectionTypeData4; break; // section with only 4 byte literals 422 case S_8BYTE_LITERALS: sect_type = eSectionTypeData8; break; // section with only 8 byte literals 423 case S_LITERAL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals 424 case S_NON_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers 425 case S_LAZY_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers 426 case S_SYMBOL_STUBS: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field 427 case S_MOD_INIT_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization 428 case S_MOD_TERM_FUNC_POINTERS: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination 429 case S_COALESCED: sect_type = eSectionTypeOther; break; 430 case S_GB_ZEROFILL: sect_type = eSectionTypeZeroFill; break; 431 case S_INTERPOSING: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing 432 case S_16BYTE_LITERALS: sect_type = eSectionTypeData16; break; // section with only 16 byte literals 433 case S_DTRACE_DOF: sect_type = eSectionTypeDebug; break; 434 case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers; break; 435 default: break; 436 } 437 } 438 439 SectionSP section_sp(new Section(segment_sp.get(), 440 GetModule(), 441 ++sectID, 442 section_name, 443 sect_type, 444 sect64.addr - segment_sp->GetFileAddress(), 445 sect64.size, 446 sect64.offset, 447 sect64.offset == 0 ? 0 : sect64.size, 448 sect64.flags)); 449 segment_sp->GetChildren().AddSection(section_sp); 450 451 if (segment_sp->IsFake()) 452 { 453 segment_sp.reset(); 454 segment_name.Clear(); 455 } 456 } 457 if (m_header.filetype == MH_DSYM) 458 { 459 if (first_segment_sectID <= sectID) 460 { 461 lldb::user_id_t sect_uid; 462 for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid) 463 { 464 SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid)); 465 SectionSP next_section_sp; 466 if (sect_uid + 1 <= sectID) 467 next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1); 468 469 if (curr_section_sp.get()) 470 { 471 if (curr_section_sp->GetByteSize() == 0) 472 { 473 if (next_section_sp.get() != NULL) 474 curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() ); 475 else 476 curr_section_sp->SetByteSize ( load_cmd.vmsize ); 477 } 478 } 479 } 480 } 481 } 482 } 483 } 484 } 485 else if (load_cmd.cmd == LC_DYSYMTAB) 486 { 487 m_dysymtab.cmd = load_cmd.cmd; 488 m_dysymtab.cmdsize = load_cmd.cmdsize; 489 m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2); 490 } 491 492 offset = load_cmd_offset + load_cmd.cmdsize; 493 } 494 // if (dump_sections) 495 // { 496 // StreamFile s(stdout); 497 // m_sections_ap->Dump(&s, true); 498 // } 499 return sectID; // Return the number of sections we registered with the module 500 } 501 502 class MachSymtabSectionInfo 503 { 504 public: 505 506 MachSymtabSectionInfo (SectionList *section_list) : 507 m_section_list (section_list), 508 m_section_infos() 509 { 510 // Get the number of sections down to a depth of 1 to include 511 // all segments and their sections, but no other sections that 512 // may be added for debug map or 513 m_section_infos.resize(section_list->GetNumSections(1)); 514 } 515 516 517 Section * 518 GetSection (uint8_t n_sect, addr_t file_addr) 519 { 520 if (n_sect == 0) 521 return NULL; 522 if (n_sect < m_section_infos.size()) 523 { 524 if (m_section_infos[n_sect].section == NULL) 525 { 526 Section *section = m_section_list->FindSectionByID (n_sect).get(); 527 m_section_infos[n_sect].section = section; 528 assert (section != NULL); 529 m_section_infos[n_sect].vm_range.SetBaseAddress (section->GetFileAddress()); 530 m_section_infos[n_sect].vm_range.SetByteSize (section->GetByteSize()); 531 } 532 if (m_section_infos[n_sect].vm_range.Contains(file_addr)) 533 return m_section_infos[n_sect].section; 534 } 535 return m_section_list->FindSectionContainingFileAddress(file_addr).get(); 536 } 537 538 protected: 539 struct SectionInfo 540 { 541 SectionInfo () : 542 vm_range(), 543 section (NULL) 544 { 545 } 546 547 VMRange vm_range; 548 Section *section; 549 }; 550 SectionList *m_section_list; 551 std::vector<SectionInfo> m_section_infos; 552 }; 553 554 555 556 size_t 557 ObjectFileMachO::ParseSymtab (bool minimize) 558 { 559 Timer scoped_timer(__PRETTY_FUNCTION__, 560 "ObjectFileMachO::ParseSymtab () module = %s", 561 m_file.GetFilename().AsCString("")); 562 struct symtab_command symtab_load_command; 563 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); 564 uint32_t i; 565 for (i=0; i<m_header.ncmds; ++i) 566 { 567 const uint32_t cmd_offset = offset; 568 // Read in the load command and load command size 569 if (m_data.GetU32(&offset, &symtab_load_command, 2) == NULL) 570 break; 571 // Watch for the symbol table load command 572 if (symtab_load_command.cmd == LC_SYMTAB) 573 { 574 // Read in the rest of the symtab load command 575 if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4)) 576 { 577 Symtab *symtab = m_symtab_ap.get(); 578 SectionList *section_list = GetSectionList(); 579 assert(section_list); 580 const size_t addr_size = m_data.GetAddressByteSize(); 581 const ByteOrder endian = m_data.GetByteOrder(); 582 bool bit_width_32 = addr_size == 4; 583 const size_t nlist_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64); 584 585 DataBufferSP symtab_data_sp(m_file.ReadFileContents(m_offset + symtab_load_command.symoff, symtab_load_command.nsyms * nlist_size)); 586 DataBufferSP strtab_data_sp(m_file.ReadFileContents(m_offset + symtab_load_command.stroff, symtab_load_command.strsize)); 587 588 const char *strtab_data = (const char *)strtab_data_sp->GetBytes(); 589 // DataExtractor symtab_data(symtab_data_sp, endian, addr_size); 590 // DataExtractor strtab_data(strtab_data_sp, endian, addr_size); 591 592 static ConstString g_segment_name_TEXT ("__TEXT"); 593 static ConstString g_segment_name_DATA ("__DATA"); 594 static ConstString g_segment_name_OBJC ("__OBJC"); 595 static ConstString g_section_name_eh_frame ("__eh_frame"); 596 SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT)); 597 SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA)); 598 SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC)); 599 SectionSP eh_frame_section_sp; 600 if (text_section_sp.get()) 601 eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame); 602 else 603 eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame); 604 605 uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NO_SECT; 606 //uint32_t symtab_offset = 0; 607 const uint8_t* nlist_data = symtab_data_sp->GetBytes(); 608 assert (symtab_data_sp->GetByteSize()/nlist_size >= symtab_load_command.nsyms); 609 610 611 if (endian != eByteOrderHost) 612 { 613 // ... 614 assert (!"UNIMPLEMENTED: Swap all nlist entries"); 615 } 616 uint32_t N_SO_index = UINT_MAX; 617 618 MachSymtabSectionInfo section_info (section_list); 619 std::vector<uint32_t> N_FUN_indexes; 620 std::vector<uint32_t> N_NSYM_indexes; 621 std::vector<uint32_t> N_INCL_indexes; 622 std::vector<uint32_t> N_BRAC_indexes; 623 std::vector<uint32_t> N_COMM_indexes; 624 uint32_t nlist_idx = 0; 625 Symbol *symbol_ptr = NULL; 626 627 uint32_t sym_idx = 0; 628 Symbol *sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms); 629 uint32_t num_syms = symtab->GetNumSymbols(); 630 631 //symtab->Reserve (symtab_load_command.nsyms + m_dysymtab.nindirectsyms); 632 for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) 633 { 634 struct nlist_64 nlist; 635 if (bit_width_32) 636 { 637 struct nlist* nlist32_ptr = (struct nlist*)(nlist_data + (nlist_idx * nlist_size)); 638 nlist.n_un.n_strx = nlist32_ptr->n_un.n_strx; 639 nlist.n_type = nlist32_ptr->n_type; 640 nlist.n_sect = nlist32_ptr->n_sect; 641 nlist.n_desc = nlist32_ptr->n_desc; 642 nlist.n_value = nlist32_ptr->n_value; 643 } 644 else 645 { 646 nlist = *((struct nlist_64*)(nlist_data + (nlist_idx * nlist_size))); 647 } 648 649 SymbolType type = eSymbolTypeInvalid; 650 const char* symbol_name = &strtab_data[nlist.n_un.n_strx]; 651 if (symbol_name[0] == '\0') 652 symbol_name = NULL; 653 Section* symbol_section = NULL; 654 bool add_nlist = true; 655 bool is_debug = ((nlist.n_type & N_STAB) != 0); 656 657 assert (sym_idx < num_syms); 658 659 sym[sym_idx].SetDebug (is_debug); 660 661 if (is_debug) 662 { 663 switch (nlist.n_type) 664 { 665 case N_GSYM: // global symbol: name,,NO_SECT,type,0 666 // Sometimes the N_GSYM value contains the address. 667 if (nlist.n_value != 0) 668 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 669 type = eSymbolTypeGlobal; 670 break; 671 672 case N_FNAME: // procedure name (f77 kludge): name,,NO_SECT,0,0 673 type = eSymbolTypeFunction; 674 break; 675 676 case N_FUN: // procedure: name,,n_sect,linenumber,address 677 if (symbol_name) 678 { 679 type = eSymbolTypeFunction; 680 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 681 // We use the current number of symbols in the symbol table in lieu of 682 // using nlist_idx in case we ever start trimming entries out 683 N_FUN_indexes.push_back(sym_idx); 684 } 685 else 686 { 687 type = eSymbolTypeFunctionEnd; 688 689 if ( !N_FUN_indexes.empty() ) 690 { 691 // Copy the size of the function into the original STAB entry so we don't have 692 // to hunt for it later 693 symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value); 694 N_FUN_indexes.pop_back(); 695 // We dont' really need the end function STAB as it contains the size which 696 // we already placed with the original symbol, so don't add it if we want a 697 // minimal symbol table 698 if (minimize) 699 add_nlist = false; 700 } 701 } 702 break; 703 704 case N_STSYM: // static symbol: name,,n_sect,type,address 705 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 706 type = eSymbolTypeStatic; 707 break; 708 709 case N_LCSYM: // .lcomm symbol: name,,n_sect,type,address 710 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 711 type = eSymbolTypeCommonBlock; 712 break; 713 714 case N_BNSYM: 715 // We use the current number of symbols in the symbol table in lieu of 716 // using nlist_idx in case we ever start trimming entries out 717 if (minimize) 718 { 719 // Skip these if we want minimal symbol tables 720 add_nlist = false; 721 } 722 else 723 { 724 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 725 N_NSYM_indexes.push_back(sym_idx); 726 type = eSymbolTypeScopeBegin; 727 } 728 break; 729 730 case N_ENSYM: 731 // Set the size of the N_BNSYM to the terminating index of this N_ENSYM 732 // so that we can always skip the entire symbol if we need to navigate 733 // more quickly at the source level when parsing STABS 734 if (minimize) 735 { 736 // Skip these if we want minimal symbol tables 737 add_nlist = false; 738 } 739 else 740 { 741 if ( !N_NSYM_indexes.empty() ) 742 { 743 symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back()); 744 symbol_ptr->SetByteSize(sym_idx + 1); 745 symbol_ptr->SetSizeIsSibling(true); 746 N_NSYM_indexes.pop_back(); 747 } 748 type = eSymbolTypeScopeEnd; 749 } 750 break; 751 752 753 case N_OPT: // emitted with gcc2_compiled and in gcc source 754 type = eSymbolTypeCompiler; 755 break; 756 757 case N_RSYM: // register sym: name,,NO_SECT,type,register 758 type = eSymbolTypeVariable; 759 break; 760 761 case N_SLINE: // src line: 0,,n_sect,linenumber,address 762 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 763 type = eSymbolTypeLineEntry; 764 break; 765 766 case N_SSYM: // structure elt: name,,NO_SECT,type,struct_offset 767 type = eSymbolTypeVariableType; 768 break; 769 770 case N_SO: 771 type = eSymbolTypeSourceFile; 772 if (symbol_name == NULL) 773 { 774 if (N_SO_index == UINT_MAX) 775 { 776 // Skip the extra blank N_SO entries that happen when the entire 777 // path is contained in the second consecutive N_SO STAB. 778 if (minimize) 779 add_nlist = false; 780 } 781 else 782 { 783 // Set the size of the N_SO to the terminating index of this N_SO 784 // so that we can always skip the entire N_SO if we need to navigate 785 // more quickly at the source level when parsing STABS 786 symbol_ptr = symtab->SymbolAtIndex(N_SO_index); 787 symbol_ptr->SetByteSize(sym_idx + 1); 788 symbol_ptr->SetSizeIsSibling(true); 789 } 790 N_NSYM_indexes.clear(); 791 N_INCL_indexes.clear(); 792 N_BRAC_indexes.clear(); 793 N_COMM_indexes.clear(); 794 N_FUN_indexes.clear(); 795 N_SO_index = UINT_MAX; 796 } 797 else if (symbol_name[0] == '/') 798 { 799 // We use the current number of symbols in the symbol table in lieu of 800 // using nlist_idx in case we ever start trimming entries out 801 N_SO_index = sym_idx; 802 } 803 break; 804 805 case N_OSO: // object file name: name,,0,0,st_mtime 806 type = eSymbolTypeObjectFile; 807 break; 808 809 case N_LSYM: // local sym: name,,NO_SECT,type,offset 810 type = eSymbolTypeLocal; 811 break; 812 813 //---------------------------------------------------------------------- 814 // INCL scopes 815 //---------------------------------------------------------------------- 816 case N_BINCL: // include file beginning: name,,NO_SECT,0,sum 817 // We use the current number of symbols in the symbol table in lieu of 818 // using nlist_idx in case we ever start trimming entries out 819 N_INCL_indexes.push_back(sym_idx); 820 type = eSymbolTypeScopeBegin; 821 break; 822 case N_EINCL: // include file end: name,,NO_SECT,0,0 823 824 // Set the size of the N_BINCL to the terminating index of this N_EINCL 825 // so that we can always skip the entire symbol if we need to navigate 826 // more quickly at the source level when parsing STABS 827 if ( !N_INCL_indexes.empty() ) 828 { 829 symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back()); 830 symbol_ptr->SetByteSize(sym_idx + 1); 831 symbol_ptr->SetSizeIsSibling(true); 832 N_INCL_indexes.pop_back(); 833 } 834 type = eSymbolTypeScopeEnd; 835 break; 836 837 case N_SOL: // #included file name: name,,n_sect,0,address 838 type = eSymbolTypeHeaderFile; 839 break; 840 841 case N_PARAMS: // compiler parameters: name,,NO_SECT,0,0 842 type = eSymbolTypeCompiler; 843 break; 844 845 case N_VERSION: // compiler version: name,,NO_SECT,0,0 846 type = eSymbolTypeCompiler; 847 break; 848 849 case N_OLEVEL: // compiler -O level: name,,NO_SECT,0,0 850 type = eSymbolTypeCompiler; 851 break; 852 853 case N_PSYM: // parameter: name,,NO_SECT,type,offset 854 type = eSymbolTypeVariable; 855 break; 856 857 case N_ENTRY: // alternate entry: name,,n_sect,linenumber,address 858 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 859 type = eSymbolTypeLineEntry; 860 break; 861 862 //---------------------------------------------------------------------- 863 // Left and Right Braces 864 //---------------------------------------------------------------------- 865 case N_LBRAC: // left bracket: 0,,NO_SECT,nesting level,address 866 // We use the current number of symbols in the symbol table in lieu of 867 // using nlist_idx in case we ever start trimming entries out 868 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 869 N_BRAC_indexes.push_back(sym_idx); 870 type = eSymbolTypeScopeBegin; 871 break; 872 873 case N_RBRAC: // right bracket: 0,,NO_SECT,nesting level,address 874 // Set the size of the N_LBRAC to the terminating index of this N_RBRAC 875 // so that we can always skip the entire symbol if we need to navigate 876 // more quickly at the source level when parsing STABS 877 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 878 if ( !N_BRAC_indexes.empty() ) 879 { 880 symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back()); 881 symbol_ptr->SetByteSize(sym_idx + 1); 882 symbol_ptr->SetSizeIsSibling(true); 883 N_BRAC_indexes.pop_back(); 884 } 885 type = eSymbolTypeScopeEnd; 886 break; 887 888 case N_EXCL: // deleted include file: name,,NO_SECT,0,sum 889 type = eSymbolTypeHeaderFile; 890 break; 891 892 //---------------------------------------------------------------------- 893 // COMM scopes 894 //---------------------------------------------------------------------- 895 case N_BCOMM: // begin common: name,,NO_SECT,0,0 896 // We use the current number of symbols in the symbol table in lieu of 897 // using nlist_idx in case we ever start trimming entries out 898 type = eSymbolTypeScopeBegin; 899 N_COMM_indexes.push_back(sym_idx); 900 break; 901 902 case N_ECOML: // end common (local name): 0,,n_sect,0,address 903 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 904 // Fall through 905 906 case N_ECOMM: // end common: name,,n_sect,0,0 907 // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML 908 // so that we can always skip the entire symbol if we need to navigate 909 // more quickly at the source level when parsing STABS 910 if ( !N_COMM_indexes.empty() ) 911 { 912 symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back()); 913 symbol_ptr->SetByteSize(sym_idx + 1); 914 symbol_ptr->SetSizeIsSibling(true); 915 N_COMM_indexes.pop_back(); 916 } 917 type = eSymbolTypeScopeEnd; 918 break; 919 920 case N_LENG: // second stab entry with length information 921 type = eSymbolTypeAdditional; 922 break; 923 924 default: break; 925 } 926 } 927 else 928 { 929 //uint8_t n_pext = N_PEXT & nlist.n_type; 930 uint8_t n_type = N_TYPE & nlist.n_type; 931 sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0); 932 933 if (symbol_name && ::strstr (symbol_name, ".objc") == symbol_name) 934 { 935 type = eSymbolTypeRuntime; 936 } 937 else 938 { 939 switch (n_type) 940 { 941 case N_INDR: // Fall through 942 case N_PBUD: // Fall through 943 case N_UNDF: 944 type = eSymbolTypeExtern; 945 break; 946 947 case N_ABS: 948 type = eSymbolTypeAbsolute; 949 break; 950 951 case N_SECT: 952 symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); 953 954 assert(symbol_section != NULL); 955 if (TEXT_eh_frame_sectID == nlist.n_sect) 956 { 957 type = eSymbolTypeException; 958 } 959 else 960 { 961 uint32_t section_type = symbol_section->GetAllFlagBits() & SECTION_TYPE; 962 963 switch (section_type) 964 { 965 case S_REGULAR: break; // regular section 966 //case S_ZEROFILL: type = eSymbolTypeData; break; // zero fill on demand section 967 case S_CSTRING_LITERALS: type = eSymbolTypeData; break; // section with only literal C strings 968 case S_4BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 4 byte literals 969 case S_8BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 8 byte literals 970 case S_LITERAL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only pointers to literals 971 case S_NON_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers 972 case S_LAZY_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers 973 case S_SYMBOL_STUBS: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field 974 case S_MOD_INIT_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for initialization 975 case S_MOD_TERM_FUNC_POINTERS: type = eSymbolTypeCode; break; // section with only function pointers for termination 976 //case S_COALESCED: type = eSymbolType; break; // section contains symbols that are to be coalesced 977 //case S_GB_ZEROFILL: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes) 978 case S_INTERPOSING: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing 979 case S_16BYTE_LITERALS: type = eSymbolTypeData; break; // section with only 16 byte literals 980 case S_DTRACE_DOF: type = eSymbolTypeInstrumentation; break; 981 case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; 982 default: break; 983 } 984 985 if (type == eSymbolTypeInvalid) 986 { 987 const char *symbol_sect_name = symbol_section->GetName().AsCString(); 988 if (symbol_section->IsDescendant (text_section_sp.get())) 989 { 990 if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE | S_ATTR_SOME_INSTRUCTIONS)) 991 type = eSymbolTypeData; 992 else 993 type = eSymbolTypeCode; 994 } 995 else 996 if (symbol_section->IsDescendant(data_section_sp.get())) 997 { 998 if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name) 999 { 1000 type = eSymbolTypeRuntime; 1001 } 1002 else 1003 if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name) 1004 { 1005 type = eSymbolTypeException; 1006 } 1007 else 1008 { 1009 type = eSymbolTypeData; 1010 } 1011 } 1012 else 1013 if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name) 1014 { 1015 type = eSymbolTypeTrampoline; 1016 } 1017 else 1018 if (symbol_section->IsDescendant(objc_section_sp.get())) 1019 { 1020 type = eSymbolTypeRuntime; 1021 } 1022 } 1023 } 1024 break; 1025 } 1026 } 1027 } 1028 1029 if (add_nlist) 1030 { 1031 bool symbol_name_is_mangled = false; 1032 if (symbol_name && symbol_name[0] == '_') 1033 { 1034 symbol_name_is_mangled = symbol_name[1] == '_'; 1035 symbol_name++; // Skip the leading underscore 1036 } 1037 uint64_t symbol_value = nlist.n_value; 1038 if (symbol_section != NULL) 1039 symbol_value -= symbol_section->GetFileAddress(); 1040 1041 sym[sym_idx].SetID (nlist_idx); 1042 sym[sym_idx].SetType (type); 1043 if (symbol_name) 1044 sym[sym_idx].GetMangled().SetValue(symbol_name, symbol_name_is_mangled); 1045 sym[sym_idx].GetAddressRangeRef().GetBaseAddress().SetSection (symbol_section); 1046 sym[sym_idx].GetAddressRangeRef().GetBaseAddress().SetOffset (symbol_value); 1047 sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc); 1048 1049 ++sym_idx; 1050 } 1051 else 1052 { 1053 sym[sym_idx].Clear(); 1054 } 1055 1056 } 1057 1058 1059 // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value 1060 // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all 1061 // such entries by figuring out what the address for the global is by looking up this non-STAB 1062 // entry and copying the value into the debug symbol's value to save us the hassle in the 1063 // debug symbol parser. 1064 1065 Symbol *global_symbol = NULL; 1066 for (nlist_idx = 0; 1067 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType(eSymbolTypeGlobal, nlist_idx)) != NULL; 1068 nlist_idx++) 1069 { 1070 if (global_symbol->GetValue().GetFileAddress() == 0) 1071 { 1072 std::vector<uint32_t> indexes; 1073 if (symtab->AppendSymbolIndexesWithName(global_symbol->GetMangled().GetName(), indexes) > 0) 1074 { 1075 std::vector<uint32_t>::const_iterator pos; 1076 std::vector<uint32_t>::const_iterator end = indexes.end(); 1077 for (pos = indexes.begin(); pos != end; ++pos) 1078 { 1079 symbol_ptr = symtab->SymbolAtIndex(*pos); 1080 if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false) 1081 { 1082 global_symbol->SetValue(symbol_ptr->GetValue()); 1083 break; 1084 } 1085 } 1086 } 1087 } 1088 } 1089 // Now synthesize indirect symbols 1090 if (m_dysymtab.nindirectsyms != 0) 1091 { 1092 DataBufferSP indirect_symbol_indexes_sp(m_file.ReadFileContents(m_offset + m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4)); 1093 1094 if (indirect_symbol_indexes_sp && indirect_symbol_indexes_sp->GetByteSize()) 1095 { 1096 DataExtractor indirect_symbol_index_data (indirect_symbol_indexes_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize()); 1097 1098 for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx) 1099 { 1100 if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS) 1101 { 1102 uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2; 1103 if (symbol_stub_byte_size == 0) 1104 continue; 1105 1106 const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size; 1107 1108 if (num_symbol_stubs == 0) 1109 continue; 1110 1111 const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1; 1112 uint32_t stub_sym_id = symtab_load_command.nsyms; 1113 for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) 1114 { 1115 const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx; 1116 const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size); 1117 uint32_t symbol_stub_offset = symbol_stub_index * 4; 1118 if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4)) 1119 { 1120 const uint32_t symbol_index = indirect_symbol_index_data.GetU32 (&symbol_stub_offset); 1121 1122 Symbol *stub_symbol = symtab->SymbolAtIndex(symbol_index); 1123 if (stub_symbol) 1124 { 1125 Address so_addr(symbol_stub_addr, section_list); 1126 1127 if (stub_symbol->GetType() == eSymbolTypeExtern) 1128 { 1129 // Change the external symbol into a trampoline that makes sense 1130 // These symbols were N_UNDF N_EXT, and are useless to us, so we 1131 // can re-use them so we don't have to make up a synthetic symbol 1132 // for no good reason. 1133 stub_symbol->SetType (eSymbolTypeTrampoline); 1134 stub_symbol->SetExternal (false); 1135 stub_symbol->GetAddressRangeRef().GetBaseAddress() = so_addr; 1136 stub_symbol->GetAddressRangeRef().SetByteSize (symbol_stub_byte_size); 1137 } 1138 else 1139 { 1140 // Make a synthetic symbol to describe the trampoline stub 1141 if (sym_idx >= num_syms) 1142 { 1143 sym = symtab->Resize (num_syms + 16); 1144 num_syms = symtab->GetNumSymbols(); 1145 } 1146 sym[sym_idx].SetID (stub_sym_id++); 1147 sym[sym_idx].GetMangled() = stub_symbol->GetMangled(); 1148 sym[sym_idx].SetType (eSymbolTypeTrampoline); 1149 sym[sym_idx].SetIsSynthetic (true); 1150 sym[sym_idx].GetAddressRangeRef().GetBaseAddress() = so_addr; 1151 sym[sym_idx].GetAddressRangeRef().SetByteSize (symbol_stub_byte_size); 1152 ++sym_idx; 1153 } 1154 } 1155 } 1156 } 1157 } 1158 } 1159 } 1160 } 1161 1162 if (sym_idx != symtab->GetNumSymbols()) 1163 symtab->Resize (sym_idx); 1164 1165 return symtab->GetNumSymbols(); 1166 } 1167 } 1168 offset = cmd_offset + symtab_load_command.cmdsize; 1169 } 1170 return 0; 1171 } 1172 1173 1174 void 1175 ObjectFileMachO::Dump (Stream *s) 1176 { 1177 lldb_private::Mutex::Locker locker(m_mutex); 1178 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 1179 s->Indent(); 1180 if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64) 1181 s->PutCString("ObjectFileMachO64"); 1182 else 1183 s->PutCString("ObjectFileMachO32"); 1184 1185 ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); 1186 1187 *s << ", file = '" << m_file << "', arch = " << header_arch.AsCString() << "\n"; 1188 1189 if (m_sections_ap.get()) 1190 m_sections_ap->Dump(s, NULL, true); 1191 1192 if (m_symtab_ap.get()) 1193 m_symtab_ap->Dump(s, NULL); 1194 } 1195 1196 1197 bool 1198 ObjectFileMachO::GetUUID (UUID* uuid) 1199 { 1200 lldb_private::Mutex::Locker locker(m_mutex); 1201 struct uuid_command load_cmd; 1202 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); 1203 uint32_t i; 1204 for (i=0; i<m_header.ncmds; ++i) 1205 { 1206 const uint32_t cmd_offset = offset; 1207 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) 1208 break; 1209 1210 if (load_cmd.cmd == LC_UUID) 1211 { 1212 const uint8_t *uuid_bytes = m_data.PeekData(offset, 16); 1213 if (uuid_bytes) 1214 { 1215 uuid->SetBytes (uuid_bytes); 1216 return true; 1217 } 1218 return false; 1219 } 1220 offset = cmd_offset + load_cmd.cmdsize; 1221 } 1222 return false; 1223 } 1224 1225 1226 uint32_t 1227 ObjectFileMachO::GetDependentModules (FileSpecList& files) 1228 { 1229 lldb_private::Mutex::Locker locker(m_mutex); 1230 struct load_command load_cmd; 1231 uint32_t offset = MachHeaderSizeFromMagic(m_header.magic); 1232 uint32_t count = 0; 1233 uint32_t i; 1234 for (i=0; i<m_header.ncmds; ++i) 1235 { 1236 const uint32_t cmd_offset = offset; 1237 if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) 1238 break; 1239 1240 switch (load_cmd.cmd) 1241 { 1242 case LC_LOAD_DYLIB: 1243 case LC_LOAD_WEAK_DYLIB: 1244 case LC_REEXPORT_DYLIB: 1245 case LC_LOAD_DYLINKER: 1246 case LC_LOADFVMLIB: 1247 { 1248 uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); 1249 const char *path = m_data.PeekCStr(name_offset); 1250 // Skip any path that starts with '@' since these are usually: 1251 // @executable_path/.../file 1252 // @rpath/.../file 1253 if (path && path[0] != '@') 1254 { 1255 FileSpec file_spec(path); 1256 if (files.AppendIfUnique(file_spec)) 1257 count++; 1258 } 1259 } 1260 break; 1261 1262 default: 1263 break; 1264 } 1265 offset = cmd_offset + load_cmd.cmdsize; 1266 } 1267 return count; 1268 } 1269 1270 bool 1271 ObjectFileMachO::GetTargetTriple (ConstString &target_triple) 1272 { 1273 lldb_private::Mutex::Locker locker(m_mutex); 1274 std::string triple(GetModule()->GetArchitecture().AsCString()); 1275 triple += "-apple-darwin"; 1276 target_triple.SetCString(triple.c_str()); 1277 if (target_triple) 1278 return true; 1279 return false; 1280 } 1281 1282 1283 //------------------------------------------------------------------ 1284 // PluginInterface protocol 1285 //------------------------------------------------------------------ 1286 const char * 1287 ObjectFileMachO::GetPluginName() 1288 { 1289 return "ObjectFileMachO"; 1290 } 1291 1292 const char * 1293 ObjectFileMachO::GetShortPluginName() 1294 { 1295 return GetPluginNameStatic(); 1296 } 1297 1298 uint32_t 1299 ObjectFileMachO::GetPluginVersion() 1300 { 1301 return 1; 1302 } 1303 1304 void 1305 ObjectFileMachO::GetPluginCommandHelp (const char *command, Stream *strm) 1306 { 1307 } 1308 1309 Error 1310 ObjectFileMachO::ExecutePluginCommand (Args &command, Stream *strm) 1311 { 1312 Error error; 1313 error.SetErrorString("No plug-in command are currently supported."); 1314 return error; 1315 } 1316 1317 Log * 1318 ObjectFileMachO::EnablePluginLogging (Stream *strm, Args &command) 1319 { 1320 return NULL; 1321 } 1322 1323 1324 1325 1326