Move all of the GoogleTest files back to the same locations they occupy
[oota-llvm.git] / tools / llvm-readobj / COFFDumper.cpp
index 14f8b72ac79c3a64b66d7f23a8f5c7dbaa217394..2f309e30ec22b7dd8f50a656afb92b029353935a 100644 (file)
@@ -60,6 +60,8 @@ private:
 
   void printRelocation(section_iterator SecI, relocation_iterator RelI);
 
+  void printDataDirectory(uint32_t Index, const std::string &FieldName);
+
   void printX64UnwindInfo();
 
   void printRuntimeFunction(
@@ -201,8 +203,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 +264,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 +481,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();
@@ -536,27 +562,90 @@ void COFFDumper::cacheRelocations() {
   }
 }
 
+void COFFDumper::printDataDirectory(uint32_t Index, const std::string &FieldName) {
+  const data_directory *Data;
+  if (Obj->getDataDirectory(Index, Data))
+    return;
+  W.printHex(FieldName + "RVA", Data->RelativeVirtualAddress);
+  W.printHex(FieldName + "Size", Data->Size);
+}
+
 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);
+
+    if (PEHeader->NumberOfRvaAndSize > 0) {
+      DictScope D(W, "DataDirectory");
+      static const char * const directory[] = {
+        "ExportTable", "ImportTable", "ResourceTable", "ExceptionTable",
+        "CertificateTable", "BaseRelocationTable", "Debug", "Architecture",
+        "GlobalPtr", "TLSTable", "LoadConfigTable", "BoundImport", "IAT",
+        "DelayImportDescriptor", "CLRRuntimeHeader", "Reserved"
+      };
+
+      for (uint32_t i = 0; i < PEHeader->NumberOfRvaAndSize; ++i) {
+        printDataDirectory(i, directory[i]);
+      }
+    }
+  }
 }
 
 void COFFDumper::printSections() {
@@ -670,14 +759,13 @@ 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;
 
   if (opts::ExpandRelocs) {
@@ -785,7 +873,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;
@@ -831,7 +924,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");