MachODumper.cpp revision 7ea2e4869496fb27876d35b93fe99397be29b978
1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//===-- MachODump.cpp - Object file dumping utility for llvm --------------===// 2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The LLVM Compiler Infrastructure 4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This file is distributed under the University of Illinois Open Source 6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// License. See LICENSE.TXT for details. 7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//===----------------------------------------------------------------------===// 9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This file implements the MachO-specific dumper for llvm-readobj. 11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//===----------------------------------------------------------------------===// 13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include "llvm-readobj.h" 15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include "Error.h" 16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include "ObjDumper.h" 17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include "StreamWriter.h" 18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include "llvm/ADT/SmallString.h" 20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include "llvm/Object/MachO.h" 21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include "llvm/Support/Casting.h" 22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing namespace llvm; 24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing namespace object; 25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace { 27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass MachODumper : public ObjDumper { 29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonpublic: 30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MachODumper(const llvm::object::MachOObjectFile *Obj, StreamWriter& Writer) 31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : ObjDumper(Writer) 32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson , Obj(Obj) { } 33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void printFileHeaders() LLVM_OVERRIDE; 35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void printSections() LLVM_OVERRIDE; 36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void printRelocations() LLVM_OVERRIDE; 37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void printSymbols() LLVM_OVERRIDE; 38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void printDynamicSymbols() LLVM_OVERRIDE; 39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void printUnwindInfo() LLVM_OVERRIDE; 40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonprivate: 42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void printSymbol(symbol_iterator SymI); 43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void printRelocation(section_iterator SecI, relocation_iterator RelI); 45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const llvm::object::MachOObjectFile *Obj; 47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace 50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 52dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkinnamespace llvm { 53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonerror_code createMachODumper(const object::ObjectFile *Obj, 55dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin StreamWriter& Writer, 56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson OwningPtr<ObjDumper> &Result) { 57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(Obj); 58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!MachOObj) 59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return readobj_error::unsupported_obj_file_format; 60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Result.reset(new MachODumper(MachOObj, Writer)); 62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return readobj_error::success; 63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace llvm 66dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin 67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const EnumEntry<unsigned> MachOSectionTypes[] = { 69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "Regular" , 0x00 }, 70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ZeroFill" , 0x01 }, 71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "CStringLiterals" , 0x02 }, 72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "4ByteLiterals" , 0x03 }, 73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "8ByteLiterals" , 0x04 }, 74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "LiteralPointers" , 0x05 }, 75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "NonLazySymbolPointers" , 0x06 }, 76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "LazySymbolPointers" , 0x07 }, 77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "SymbolStubs" , 0x08 }, 78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ModInitFuncs" , 0x09 }, 79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ModTermFuncs" , 0x0A }, 80dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin { "Coalesced" , 0x0B }, 81dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin { "GBZeroFill" , 0x0C }, 82dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin { "Interposing" , 0x0D }, 83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "16ByteLiterals" , 0x0E }, 84dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin { "DTraceDOF" , 0x0F }, 85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "LazyDylibSymbolPoints" , 0x10 }, 86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ThreadLocalRegular" , 0x11 }, 87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ThreadLocalZerofill" , 0x12 }, 88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ThreadLocalVariables" , 0x13 }, 89dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin { "ThreadLocalVariablePointers" , 0x14 }, 90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ThreadLocalInitFunctionPointers", 0x15 } 91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const EnumEntry<unsigned> MachOSectionAttributes[] = { 94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "LocReloc" , 1 << 0 /*S_ATTR_LOC_RELOC */ }, 95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ExtReloc" , 1 << 1 /*S_ATTR_EXT_RELOC */ }, 96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "SomeInstructions" , 1 << 2 /*S_ATTR_SOME_INSTRUCTIONS */ }, 97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "Debug" , 1 << 17 /*S_ATTR_DEBUG */ }, 98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "SelfModifyingCode", 1 << 18 /*S_ATTR_SELF_MODIFYING_CODE*/ }, 99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "LiveSupport" , 1 << 19 /*S_ATTR_LIVE_SUPPORT */ }, 100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "NoDeadStrip" , 1 << 20 /*S_ATTR_NO_DEAD_STRIP */ }, 101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "StripStaticSyms" , 1 << 21 /*S_ATTR_STRIP_STATIC_SYMS */ }, 102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "NoTOC" , 1 << 22 /*S_ATTR_NO_TOC */ }, 103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "PureInstructions" , 1 << 23 /*S_ATTR_PURE_INSTRUCTIONS */ }, 104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstatic const EnumEntry<unsigned> MachOSymbolRefTypes[] = { 107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "UndefinedNonLazy", 0 }, 108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ReferenceFlagUndefinedLazy", 1 }, 109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ReferenceFlagDefined", 2 }, 110dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin { "ReferenceFlagPrivateDefined", 3 }, 111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ReferenceFlagPrivateUndefinedNonLazy", 4 }, 112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson { "ReferenceFlagPrivateUndefinedLazy", 5 } 113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 114 115static const EnumEntry<unsigned> MachOSymbolFlags[] = { 116 { "ReferencedDynamically", 0x10 }, 117 { "NoDeadStrip", 0x20 }, 118 { "WeakRef", 0x40 }, 119 { "WeakDef", 0x80 } 120}; 121 122static const EnumEntry<unsigned> MachOSymbolTypes[] = { 123 { "Undef", 0x0 }, 124 { "External", 0x1 }, 125 { "Abs", 0x2 }, 126 { "Indirect", 0xA }, 127 { "PreboundUndef", 0xC }, 128 { "Section", 0xE }, 129 { "PrivateExternal", 0x10 } 130}; 131 132namespace { 133 enum { 134 N_STAB = 0xE0 135 }; 136 137 struct MachOSection { 138 ArrayRef<char> Name; 139 ArrayRef<char> SegmentName; 140 uint64_t Address; 141 uint64_t Size; 142 uint32_t Offset; 143 uint32_t Alignment; 144 uint32_t RelocationTableOffset; 145 uint32_t NumRelocationTableEntries; 146 uint32_t Flags; 147 uint32_t Reserved1; 148 uint32_t Reserved2; 149 }; 150 151 struct MachOSymbol { 152 uint32_t StringIndex; 153 uint8_t Type; 154 uint8_t SectionIndex; 155 uint16_t Flags; 156 uint64_t Value; 157 }; 158} 159 160static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { 161 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); 162 if (LCI.Command.Type == macho::LCT_Segment64) 163 return true; 164 assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); 165 return false; 166} 167 168static void getSection(const MachOObjectFile *Obj, 169 DataRefImpl DRI, 170 MachOSection &Section) { 171 const MachOObject *MachOObj = Obj->getObject(); 172 173 if (is64BitLoadCommand(MachOObj, DRI)) { 174 const MachOFormat::Section64 *Sect = Obj->getSection64(DRI); 175 176 Section.Address = Sect->Address; 177 Section.Size = Sect->Size; 178 Section.Offset = Sect->Offset; 179 Section.Alignment = Sect->Align; 180 Section.RelocationTableOffset = Sect->RelocationTableOffset; 181 Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries; 182 Section.Flags = Sect->Flags; 183 Section.Reserved1 = Sect->Reserved1; 184 Section.Reserved2 = Sect->Reserved2; 185 } else { 186 const MachOFormat::Section *Sect = Obj->getSection(DRI); 187 188 Section.Address = Sect->Address; 189 Section.Size = Sect->Size; 190 Section.Offset = Sect->Offset; 191 Section.Alignment = Sect->Align; 192 Section.RelocationTableOffset = Sect->RelocationTableOffset; 193 Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries; 194 Section.Flags = Sect->Flags; 195 Section.Reserved1 = Sect->Reserved1; 196 Section.Reserved2 = Sect->Reserved2; 197 } 198} 199 200static void getSymbolTableEntry(const MachOObject *MachO, 201 DataRefImpl DRI, 202 InMemoryStruct<macho::SymbolTableEntry> &Res) { 203 InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd; 204 LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a); 205 MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); 206 MachO->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res); 207} 208 209static void getSymbol64TableEntry(const MachOObject *MachO, 210 DataRefImpl DRI, 211 InMemoryStruct<macho::Symbol64TableEntry> &Res) { 212 InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd; 213 LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a); 214 MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); 215 MachO->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res); 216} 217 218static void getSymbol(const MachOObject *MachOObj, 219 DataRefImpl DRI, 220 MachOSymbol &Symbol) { 221 if (MachOObj->is64Bit()) { 222 InMemoryStruct<macho::Symbol64TableEntry> Entry; 223 getSymbol64TableEntry(MachOObj, DRI, Entry); 224 Symbol.StringIndex = Entry->StringIndex; 225 Symbol.Type = Entry->Type; 226 Symbol.SectionIndex = Entry->SectionIndex; 227 Symbol.Flags = Entry->Flags; 228 Symbol.Value = Entry->Value; 229 } else { 230 InMemoryStruct<macho::SymbolTableEntry> Entry; 231 getSymbolTableEntry(MachOObj, DRI, Entry); 232 Symbol.StringIndex = Entry->StringIndex; 233 Symbol.Type = Entry->Type; 234 Symbol.SectionIndex = Entry->SectionIndex; 235 Symbol.Flags = Entry->Flags; 236 Symbol.Value = Entry->Value; 237 } 238} 239 240void MachODumper::printFileHeaders() { 241 W.startLine() << "FileHeaders not implemented.\n"; 242} 243 244void MachODumper::printSections() { 245 ListScope Group(W, "Sections"); 246 247 int SectionIndex = -1; 248 error_code EC; 249 for (section_iterator SecI = Obj->begin_sections(), 250 SecE = Obj->end_sections(); 251 SecI != SecE; SecI.increment(EC)) { 252 if (error(EC)) break; 253 254 ++SectionIndex; 255 256 MachOSection Section; 257 getSection(Obj, SecI->getRawDataRefImpl(), Section); 258 DataRefImpl DR = SecI->getRawDataRefImpl(); 259 260 StringRef Name; 261 if (error(SecI->getName(Name))) 262 Name = ""; 263 264 ArrayRef<char> RawName = Obj->getSectionRawName(DR); 265 StringRef SegmentName = Obj->getSectionFinalSegmentName(DR); 266 ArrayRef<char> RawSegmentName = Obj->getSectionRawFinalSegmentName(DR); 267 268 DictScope SectionD(W, "Section"); 269 W.printNumber("Index", SectionIndex); 270 W.printBinary("Name", Name, RawName); 271 W.printBinary("Segment", SegmentName, RawSegmentName); 272 W.printHex ("Address", Section.Address); 273 W.printHex ("Size", Section.Size); 274 W.printNumber("Offset", Section.Offset); 275 W.printNumber("Alignment", Section.Alignment); 276 W.printHex ("RelocationOffset", Section.RelocationTableOffset); 277 W.printNumber("RelocationCount", Section.NumRelocationTableEntries); 278 W.printEnum ("Type", Section.Flags & 0xFF, 279 makeArrayRef(MachOSectionAttributes)); 280 W.printFlags ("Attributes", Section.Flags >> 8, 281 makeArrayRef(MachOSectionAttributes)); 282 W.printHex ("Reserved1", Section.Reserved1); 283 W.printHex ("Reserved2", Section.Reserved2); 284 285 if (opts::SectionRelocations) { 286 ListScope D(W, "Relocations"); 287 for (relocation_iterator RelI = SecI->begin_relocations(), 288 RelE = SecI->end_relocations(); 289 RelI != RelE; RelI.increment(EC)) { 290 if (error(EC)) break; 291 292 printRelocation(SecI, RelI); 293 } 294 } 295 296 if (opts::SectionSymbols) { 297 ListScope D(W, "Symbols"); 298 for (symbol_iterator SymI = Obj->begin_symbols(), 299 SymE = Obj->end_symbols(); 300 SymI != SymE; SymI.increment(EC)) { 301 if (error(EC)) break; 302 303 bool Contained = false; 304 if (SecI->containsSymbol(*SymI, Contained) || !Contained) 305 continue; 306 307 printSymbol(SymI); 308 } 309 } 310 311 if (opts::SectionData) { 312 StringRef Data; 313 if (error(SecI->getContents(Data))) break; 314 315 W.printBinaryBlock("SectionData", Data); 316 } 317 } 318} 319 320void MachODumper::printRelocations() { 321 ListScope D(W, "Relocations"); 322 323 error_code EC; 324 for (section_iterator SecI = Obj->begin_sections(), 325 SecE = Obj->end_sections(); 326 SecI != SecE; SecI.increment(EC)) { 327 if (error(EC)) break; 328 329 StringRef Name; 330 if (error(SecI->getName(Name))) 331 continue; 332 333 bool PrintedGroup = false; 334 for (relocation_iterator RelI = SecI->begin_relocations(), 335 RelE = SecI->end_relocations(); 336 RelI != RelE; RelI.increment(EC)) { 337 if (error(EC)) break; 338 339 if (!PrintedGroup) { 340 W.startLine() << "Section " << Name << " {\n"; 341 W.indent(); 342 PrintedGroup = true; 343 } 344 345 printRelocation(SecI, RelI); 346 } 347 348 if (PrintedGroup) { 349 W.unindent(); 350 W.startLine() << "}\n"; 351 } 352 } 353} 354 355void MachODumper::printRelocation(section_iterator SecI, 356 relocation_iterator RelI) { 357 uint64_t Offset; 358 SmallString<32> RelocName; 359 int64_t Info; 360 StringRef SymbolName; 361 SymbolRef Symbol; 362 if (error(RelI->getOffset(Offset))) return; 363 if (error(RelI->getTypeName(RelocName))) return; 364 if (error(RelI->getAdditionalInfo(Info))) return; 365 if (error(RelI->getSymbol(Symbol))) return; 366 if (error(Symbol.getName(SymbolName))) return; 367 368 raw_ostream& OS = W.startLine(); 369 OS << W.hex(Offset) 370 << " " << RelocName 371 << " " << (SymbolName.size() > 0 ? SymbolName : "-") 372 << " " << W.hex(Info) 373 << "\n"; 374} 375 376void MachODumper::printSymbols() { 377 ListScope Group(W, "Symbols"); 378 379 error_code EC; 380 for (symbol_iterator SymI = Obj->begin_symbols(), 381 SymE = Obj->end_symbols(); 382 SymI != SymE; SymI.increment(EC)) { 383 if (error(EC)) break; 384 385 printSymbol(SymI); 386 } 387} 388 389void MachODumper::printDynamicSymbols() { 390 ListScope Group(W, "DynamicSymbols"); 391} 392 393void MachODumper::printSymbol(symbol_iterator SymI) { 394 error_code EC; 395 396 StringRef SymbolName; 397 if (SymI->getName(SymbolName)) 398 SymbolName = ""; 399 400 const MachOObject *MachO = const_cast<MachOObjectFile*>(Obj)->getObject(); 401 402 MachOSymbol Symbol; 403 getSymbol(MachO, SymI->getRawDataRefImpl(), Symbol); 404 405 StringRef SectionName; 406 section_iterator SecI(Obj->end_sections()); 407 if (error(SymI->getSection(SecI)) || 408 error(SecI->getName(SectionName))) 409 SectionName = ""; 410 411 DictScope D(W, "Symbol"); 412 W.printNumber("Name", SymbolName, Symbol.StringIndex); 413 if (Symbol.Type & N_STAB) { 414 W.printHex ("Type", "SymDebugTable", Symbol.Type); 415 } else { 416 W.printEnum("Type", Symbol.Type, makeArrayRef(MachOSymbolTypes)); 417 } 418 W.printHex ("Section", SectionName, Symbol.SectionIndex); 419 W.printEnum ("RefType", static_cast<uint16_t>(Symbol.Flags & 0xF), 420 makeArrayRef(MachOSymbolRefTypes)); 421 W.printFlags ("Flags", static_cast<uint16_t>(Symbol.Flags & ~0xF), 422 makeArrayRef(MachOSymbolFlags)); 423 W.printHex ("Value", Symbol.Value); 424} 425 426void MachODumper::printUnwindInfo() { 427 W.startLine() << "UnwindInfo not implemented.\n"; 428} 429