R600: Add ISA documents to the CompilerWriterInfo page
[oota-llvm.git] / tools / llvm-readobj / COFFDumper.cpp
index be4e76cc634f0d6c2c8d7c30376e8dd5e2579d48..1ceb8fcd316dcc2f6111c12d84674a5d530bd9d4 100644 (file)
@@ -201,8 +201,7 @@ static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
       return EC;
 
     if (Ofs == Offset) {
-      if (error_code EC = RelI->getSymbol(Sym))
-        return EC;
+      Sym = *RelI->getSymbol();
       return readobj_error::success;
     }
   }
@@ -263,6 +262,31 @@ static const EnumEntry<COFF::Characteristics> ImageFileCharacteristics[] = {
   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_HI      )
 };
 
+static const EnumEntry<COFF::WindowsSubsystem> PEWindowsSubsystem[] = {
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_UNKNOWN                ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_NATIVE                 ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_GUI            ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CUI            ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_POSIX_CUI              ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI         ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_APPLICATION        ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER     ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_ROM                ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_XBOX                   ),
+};
+
+static const EnumEntry<COFF::DLLCharacteristics> PEDLLCharacteristics[] = {
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE         ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY      ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT            ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION         ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_SEH               ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_BIND              ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER           ),
+  LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE),
+};
+
 static const EnumEntry<COFF::SectionCharacteristics>
 ImageSectionCharacteristics[] = {
   LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD           ),
@@ -455,15 +479,15 @@ static std::string formatSymbol(const std::vector<RelocationRef> &Rels,
 
   StringRef Sym;
   if (resolveSymbolName(Rels, Offset, Sym)) {
-    Str << format(" (0x%X)", Offset);
+    Str << format(" (0x%" PRIX64 ")", Offset);
     return Str.str();
   }
 
   Str << Sym;
   if (Disp > 0) {
-    Str << format(" +0x%X (0x%X)", Disp, Offset);
+    Str << format(" +0x%X (0x%" PRIX64 ")", Disp, Offset);
   } else {
-    Str << format(" (0x%X)", Offset);
+    Str << format(" (0x%" PRIX64 ")", Offset);
   }
 
   return Str.str();
@@ -537,26 +561,67 @@ void COFFDumper::cacheRelocations() {
 }
 
 void COFFDumper::printFileHeaders() {
-  const coff_file_header *Header = 0;
-  if (error(Obj->getHeader(Header)))
+  // Print COFF header
+  const coff_file_header *COFFHeader = 0;
+  if (error(Obj->getCOFFHeader(COFFHeader)))
     return;
 
-  time_t TDS = Header->TimeDateStamp;
+  time_t TDS = COFFHeader->TimeDateStamp;
   char FormattedTime[20] = { };
   strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
 
   {
     DictScope D(W, "ImageFileHeader");
-    W.printEnum  ("Machine", Header->Machine,
+    W.printEnum  ("Machine", COFFHeader->Machine,
                     makeArrayRef(ImageFileMachineType));
-    W.printNumber("SectionCount", Header->NumberOfSections);
-    W.printHex   ("TimeDateStamp", FormattedTime, Header->TimeDateStamp);
-    W.printHex   ("PointerToSymbolTable", Header->PointerToSymbolTable);
-    W.printNumber("SymbolCount", Header->NumberOfSymbols);
-    W.printNumber("OptionalHeaderSize", Header->SizeOfOptionalHeader);
-    W.printFlags ("Characteristics", Header->Characteristics,
+    W.printNumber("SectionCount", COFFHeader->NumberOfSections);
+    W.printHex   ("TimeDateStamp", FormattedTime, COFFHeader->TimeDateStamp);
+    W.printHex   ("PointerToSymbolTable", COFFHeader->PointerToSymbolTable);
+    W.printNumber("SymbolCount", COFFHeader->NumberOfSymbols);
+    W.printNumber("OptionalHeaderSize", COFFHeader->SizeOfOptionalHeader);
+    W.printFlags ("Characteristics", COFFHeader->Characteristics,
                     makeArrayRef(ImageFileCharacteristics));
   }
+
+  // Print PE header. This header does not exist if this is an object file and
+  // not an executable.
+  const pe32_header *PEHeader = 0;
+  if (error(Obj->getPE32Header(PEHeader)))
+    return;
+
+  if (PEHeader) {
+    DictScope D(W, "ImageOptionalHeader");
+    W.printNumber("MajorLinkerVersion", PEHeader->MajorLinkerVersion);
+    W.printNumber("MinorLinkerVersion", PEHeader->MinorLinkerVersion);
+    W.printNumber("SizeOfCode", PEHeader->SizeOfCode);
+    W.printNumber("SizeOfInitializedData", PEHeader->SizeOfInitializedData);
+    W.printNumber("SizeOfUninitializedData", PEHeader->SizeOfUninitializedData);
+    W.printHex   ("AddressOfEntryPoint", PEHeader->AddressOfEntryPoint);
+    W.printHex   ("BaseOfCode", PEHeader->BaseOfCode);
+    W.printHex   ("BaseOfData", PEHeader->BaseOfData);
+    W.printHex   ("ImageBase", PEHeader->ImageBase);
+    W.printNumber("SectionAlignment", PEHeader->SectionAlignment);
+    W.printNumber("FileAlignment", PEHeader->FileAlignment);
+    W.printNumber("MajorOperatingSystemVersion",
+                  PEHeader->MajorOperatingSystemVersion);
+    W.printNumber("MinorOperatingSystemVersion",
+                  PEHeader->MinorOperatingSystemVersion);
+    W.printNumber("MajorImageVersion", PEHeader->MajorImageVersion);
+    W.printNumber("MinorImageVersion", PEHeader->MinorImageVersion);
+    W.printNumber("MajorSubsystemVersion", PEHeader->MajorSubsystemVersion);
+    W.printNumber("MinorSubsystemVersion", PEHeader->MinorSubsystemVersion);
+    W.printNumber("SizeOfImage", PEHeader->SizeOfImage);
+    W.printNumber("SizeOfHeaders", PEHeader->SizeOfHeaders);
+    W.printEnum  ("Subsystem", PEHeader->Subsystem,
+                    makeArrayRef(PEWindowsSubsystem));
+    W.printFlags ("Subsystem", PEHeader->DLLCharacteristics,
+                    makeArrayRef(PEDLLCharacteristics));
+    W.printNumber("SizeOfStackReserve", PEHeader->SizeOfStackReserve);
+    W.printNumber("SizeOfStackCommit", PEHeader->SizeOfStackCommit);
+    W.printNumber("SizeOfHeapReserve", PEHeader->SizeOfHeapReserve);
+    W.printNumber("SizeOfHeapCommit", PEHeader->SizeOfHeapCommit);
+    W.printNumber("NumberOfRvaAndSize", PEHeader->NumberOfRvaAndSize);
+  }
 }
 
 void COFFDumper::printSections() {
@@ -670,21 +735,27 @@ void COFFDumper::printRelocation(section_iterator SecI,
   uint64_t Offset;
   uint64_t RelocType;
   SmallString<32> RelocName;
-  SymbolRef Symbol;
   StringRef SymbolName;
   StringRef Contents;
   if (error(RelI->getOffset(Offset))) return;
   if (error(RelI->getType(RelocType))) return;
   if (error(RelI->getTypeName(RelocName))) return;
-  if (error(RelI->getSymbol(Symbol))) return;
-  if (error(Symbol.getName(SymbolName))) return;
+  symbol_iterator Symbol = RelI->getSymbol();
+  if (error(Symbol->getName(SymbolName))) return;
   if (error(SecI->getContents(Contents))) return;
 
-  raw_ostream& OS = W.startLine();
-  OS << W.hex(Offset)
-     << " " << RelocName
-     << " " << (SymbolName.size() > 0 ? SymbolName : "-")
-     << "\n";
+  if (opts::ExpandRelocs) {
+    DictScope Group(W, "Relocation");
+    W.printHex("Offset", Offset);
+    W.printNumber("Type", RelocName, RelocType);
+    W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
+  } else {
+    raw_ostream& OS = W.startLine();
+    OS << W.hex(Offset)
+       << " " << RelocName
+       << " " << (SymbolName.size() > 0 ? SymbolName : "-")
+       << "\n";
+  }
 }
 
 void COFFDumper::printSymbols() {
@@ -719,9 +790,9 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
   if (Obj->getSymbolName(Symbol, SymbolName))
     SymbolName = "";
 
-  StringRef SectionName;
-  if (Section && Obj->getSectionName(Section, SectionName))
-    SectionName = "";
+  StringRef SectionName = "";
+  if (Section)
+    Obj->getSectionName(Section, SectionName);
 
   W.printString("Name", SymbolName);
   W.printNumber("Value", Symbol->Value);
@@ -778,7 +849,12 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
       if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
         break;
 
-    } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC) {
+      DictScope AS(W, "AuxFileRecord");
+      W.printString("FileName", StringRef(Aux->FileName));
+
+    } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC ||
+               (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+                Symbol->SectionNumber != COFF::IMAGE_SYM_UNDEFINED)) {
       const coff_aux_section_definition *Aux;
       if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
         break;
@@ -792,7 +868,7 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
       W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect));
       W.printBinary("Unused", makeArrayRef(Aux->Unused));
 
-      if (Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
+      if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
           && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
         const coff_section *Assoc;
         StringRef AssocName;
@@ -824,7 +900,7 @@ void COFFDumper::printSymbol(symbol_iterator SymI) {
 
 void COFFDumper::printUnwindInfo() {
   const coff_file_header *Header;
-  if (error(Obj->getHeader(Header)))
+  if (error(Obj->getCOFFHeader(Header)))
     return;
 
   ListScope D(W, "UnwindInformation");