diff options
| -rw-r--r-- | llvm/include/llvm/Object/WindowsResource.h | 10 | ||||
| -rw-r--r-- | llvm/lib/Object/WindowsResource.cpp | 149 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/Inputs/combined.obj.coff | bin | 0 -> 4040 bytes | |||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/Inputs/languages.rc | 36 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/Inputs/languages.res | bin | 0 -> 452 bytes | |||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/Inputs/test_resource.obj.coff.arm | bin | 0 -> 3472 bytes | |||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/Inputs/test_resource.obj.coff.x64 | bin | 0 -> 3472 bytes | |||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/basic.test | 4 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/combined.test | 313 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/help.test | 13 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/machine.test | 59 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/object.test | 225 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-cvtres/parse.test | 2 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-readobj/resources.test | 230 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 45 | 
15 files changed, 815 insertions, 271 deletions
diff --git a/llvm/include/llvm/Object/WindowsResource.h b/llvm/include/llvm/Object/WindowsResource.h index c5189329d3e..33f396cc6f2 100644 --- a/llvm/include/llvm/Object/WindowsResource.h +++ b/llvm/include/llvm/Object/WindowsResource.h @@ -159,14 +159,16 @@ public:      TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,               uint32_t Characteristics); -    void addEntry(const ResourceEntryRef &Entry); -    TreeNode &addTypeNode(const ResourceEntryRef &Entry); -    TreeNode &addNameNode(const ResourceEntryRef &Entry); +    void addEntry(const ResourceEntryRef &Entry, bool &IsNewTypeString, +                  bool &IsNewNameString); +    TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString); +    TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString);      TreeNode &addLanguageNode(const ResourceEntryRef &Entry);      TreeNode &addChild(uint32_t ID, bool IsDataNode = false,                         uint16_t MajorVersion = 0, uint16_t MinorVersion = 0,                         uint32_t Characteristics = 0); -    TreeNode &addChild(ArrayRef<UTF16> NameRef); +    TreeNode &addChild(ArrayRef<UTF16> NameRef, bool &IsNewString); +      bool IsDataNode = false;      uint32_t StringIndex;      uint32_t DataIndex; diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp index 3a1ed9a907a..3d689fe1e9a 100644 --- a/llvm/lib/Object/WindowsResource.cpp +++ b/llvm/lib/Object/WindowsResource.cpp @@ -30,6 +30,10 @@ namespace object {  const uint32_t MIN_HEADER_SIZE = 7 * sizeof(uint32_t) + 2 * sizeof(uint16_t); +// COFF files seem to be inconsistent with alignment between sections, just use +// 8-byte because it makes everyone happy. +const uint32_t SECTION_ALIGNMENT = sizeof(uint64_t); +  static const size_t ResourceMagicSize = 16;  static const size_t NullEntrySize = 16; @@ -133,17 +137,19 @@ Error WindowsResourceParser::parse(WindowsResource *WR) {    ResourceEntryRef Entry = EntryOrErr.get();    bool End = false;    while (!End) { -      Data.push_back(Entry.getData()); -    if (Entry.checkTypeString()) +    bool IsNewTypeString = false; +    bool IsNewNameString = false; + +    Root.addEntry(Entry, IsNewTypeString, IsNewNameString); + +    if (IsNewTypeString)        StringTable.push_back(Entry.getTypeString()); -    if (Entry.checkNameString()) +    if (IsNewNameString)        StringTable.push_back(Entry.getNameString()); -    Root.addEntry(Entry); -      RETURN_IF_ERROR(Entry.moveNext(End));    } @@ -155,9 +161,11 @@ void WindowsResourceParser::printTree() const {    Root.print(Writer, "Resource Tree");  } -void WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry) { -  TreeNode &TypeNode = addTypeNode(Entry); -  TreeNode &NameNode = TypeNode.addNameNode(Entry); +void WindowsResourceParser::TreeNode::addEntry(const ResourceEntryRef &Entry, +                                               bool &IsNewTypeString, +                                               bool &IsNewNameString) { +  TreeNode &TypeNode = addTypeNode(Entry, IsNewTypeString); +  TreeNode &NameNode = TypeNode.addNameNode(Entry, IsNewNameString);    NameNode.addLanguageNode(Entry);  } @@ -171,7 +179,6 @@ WindowsResourceParser::TreeNode::TreeNode(uint16_t MajorVersion,                                            uint32_t Characteristics)      : IsDataNode(true), MajorVersion(MajorVersion), MinorVersion(MinorVersion),        Characteristics(Characteristics) { -  if (IsDataNode)      DataIndex = DataCount++;  } @@ -194,17 +201,19 @@ WindowsResourceParser::TreeNode::createDataNode(uint16_t MajorVersion,  }  WindowsResourceParser::TreeNode & -WindowsResourceParser::TreeNode::addTypeNode(const ResourceEntryRef &Entry) { +WindowsResourceParser::TreeNode::addTypeNode(const ResourceEntryRef &Entry, +                                             bool &IsNewTypeString) {    if (Entry.checkTypeString()) -    return addChild(Entry.getTypeString()); +    return addChild(Entry.getTypeString(), IsNewTypeString);    else      return addChild(Entry.getTypeID());  }  WindowsResourceParser::TreeNode & -WindowsResourceParser::TreeNode::addNameNode(const ResourceEntryRef &Entry) { +WindowsResourceParser::TreeNode::addNameNode(const ResourceEntryRef &Entry, +                                             bool &IsNewNameString) {    if (Entry.checkNameString()) -    return addChild(Entry.getNameString()); +    return addChild(Entry.getNameString(), IsNewNameString);    else      return addChild(Entry.getNameID());  } @@ -232,7 +241,8 @@ WindowsResourceParser::TreeNode &WindowsResourceParser::TreeNode::addChild(  }  WindowsResourceParser::TreeNode & -WindowsResourceParser::TreeNode::addChild(ArrayRef<UTF16> NameRef) { +WindowsResourceParser::TreeNode::addChild(ArrayRef<UTF16> NameRef, +                                          bool &IsNewString) {    std::string NameString;    ArrayRef<UTF16> CorrectedName;    std::vector<UTF16> EndianCorrectedName; @@ -248,6 +258,7 @@ WindowsResourceParser::TreeNode::addChild(ArrayRef<UTF16> NameRef) {    auto Child = StringChildren.find(NameString);    if (Child == StringChildren.end()) {      auto NewChild = createStringNode(); +    IsNewString = true;      WindowsResourceParser::TreeNode &Node = *NewChild;      StringChildren.emplace(NameString, std::move(NewChild));      return Node; @@ -296,7 +307,6 @@ class WindowsResourceCOFFWriter {  public:    WindowsResourceCOFFWriter(StringRef OutputFile, Machine MachineType,                              const WindowsResourceParser &Parser, Error &E); -    Error write();  private: @@ -314,7 +324,8 @@ private:    void writeDirectoryStringTable();    void writeFirstSectionRelocations();    std::unique_ptr<FileOutputBuffer> Buffer; -  uint8_t *Current; +  uint8_t *BufferStart; +  uint64_t CurrentOffset = 0;    Machine MachineType;    const WindowsResourceParser::TreeNode &Resources;    const ArrayRef<std::vector<uint8_t>> Data; @@ -386,6 +397,7 @@ void WindowsResourceCOFFWriter::performSectionOneLayout() {    FileSize += SectionOneSize;    FileSize += Data.size() *                llvm::COFF::RelocationSize; // one relocation for each resource. +  FileSize = alignTo(FileSize, SECTION_ALIGNMENT);  }  void WindowsResourceCOFFWriter::performSectionTwoLayout() { @@ -398,6 +410,7 @@ void WindowsResourceCOFFWriter::performSectionTwoLayout() {      SectionTwoSize += llvm::alignTo(Entry.size(), sizeof(uint64_t));    }    FileSize += SectionTwoSize; +  FileSize = alignTo(FileSize, SECTION_ALIGNMENT);  }  static std::time_t getTime() { @@ -408,7 +421,7 @@ static std::time_t getTime() {  }  Error WindowsResourceCOFFWriter::write() { -  Current = Buffer->getBufferStart(); +  BufferStart = Buffer->getBufferStart();    writeCOFFHeader();    writeFirstSectionHeader(); @@ -427,7 +440,8 @@ Error WindowsResourceCOFFWriter::write() {  void WindowsResourceCOFFWriter::writeCOFFHeader() {    // Write the COFF header. -  auto *Header = reinterpret_cast<llvm::object::coff_file_header *>(Current); +  auto *Header = +      reinterpret_cast<llvm::object::coff_file_header *>(BufferStart);    switch (MachineType) {    case Machine::ARM:      Header->Machine = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT; @@ -452,9 +466,9 @@ void WindowsResourceCOFFWriter::writeCOFFHeader() {  void WindowsResourceCOFFWriter::writeFirstSectionHeader() {    // Write the first section header. -  Current += sizeof(llvm::object::coff_file_header); -  auto *SectionOneHeader = -      reinterpret_cast<llvm::object::coff_section *>(Current); +  CurrentOffset += sizeof(llvm::object::coff_file_header); +  auto *SectionOneHeader = reinterpret_cast<llvm::object::coff_section *>( +      BufferStart + CurrentOffset);    strncpy(SectionOneHeader->Name, ".rsrc$01", (size_t)llvm::COFF::NameSize);    SectionOneHeader->VirtualSize = 0;    SectionOneHeader->VirtualAddress = 0; @@ -473,9 +487,9 @@ void WindowsResourceCOFFWriter::writeFirstSectionHeader() {  void WindowsResourceCOFFWriter::writeSecondSectionHeader() {    // Write the second section header. -  Current += sizeof(llvm::object::coff_section); -  auto *SectionTwoHeader = -      reinterpret_cast<llvm::object::coff_section *>(Current); +  CurrentOffset += sizeof(llvm::object::coff_section); +  auto *SectionTwoHeader = reinterpret_cast<llvm::object::coff_section *>( +      BufferStart + CurrentOffset);    strncpy(SectionTwoHeader->Name, ".rsrc$02", (size_t)llvm::COFF::NameSize);    SectionTwoHeader->VirtualSize = 0;    SectionTwoHeader->VirtualAddress = 0; @@ -492,75 +506,85 @@ void WindowsResourceCOFFWriter::writeSecondSectionHeader() {  void WindowsResourceCOFFWriter::writeFirstSection() {    // Write section one. -  Current += sizeof(llvm::object::coff_section); +  CurrentOffset += sizeof(llvm::object::coff_section);    writeDirectoryTree();    writeDirectoryStringTable();    writeFirstSectionRelocations(); + +  CurrentOffset = alignTo(CurrentOffset, SECTION_ALIGNMENT);  }  void WindowsResourceCOFFWriter::writeSecondSection() {    // Now write the .rsrc$02 section.    for (auto const &RawDataEntry : Data) { -    std::copy(RawDataEntry.begin(), RawDataEntry.end(), Current); -    Current += alignTo(RawDataEntry.size(), sizeof(uint64_t)); +    std::copy(RawDataEntry.begin(), RawDataEntry.end(), +              BufferStart + CurrentOffset); +    CurrentOffset += alignTo(RawDataEntry.size(), sizeof(uint64_t));    } + +  CurrentOffset = alignTo(CurrentOffset, SECTION_ALIGNMENT);  }  void WindowsResourceCOFFWriter::writeSymbolTable() {    // Now write the symbol table.    // First, the feat symbol. -  auto *Symbol = reinterpret_cast<llvm::object::coff_symbol16 *>(Current); +  auto *Symbol = reinterpret_cast<llvm::object::coff_symbol16 *>(BufferStart + +                                                                 CurrentOffset);    strncpy(Symbol->Name.ShortName, "@feat.00", (size_t)llvm::COFF::NameSize);    Symbol->Value = 0x11;    Symbol->SectionNumber = 0xffff;    Symbol->Type = llvm::COFF::IMAGE_SYM_DTYPE_NULL;    Symbol->StorageClass = llvm::COFF::IMAGE_SYM_CLASS_STATIC;    Symbol->NumberOfAuxSymbols = 0; -  Current += sizeof(llvm::object::coff_symbol16); +  CurrentOffset += sizeof(llvm::object::coff_symbol16);    // Now write the .rsrc1 symbol + aux. -  Symbol = reinterpret_cast<llvm::object::coff_symbol16 *>(Current); +  Symbol = reinterpret_cast<llvm::object::coff_symbol16 *>(BufferStart + +                                                           CurrentOffset);    strncpy(Symbol->Name.ShortName, ".rsrc$01", (size_t)llvm::COFF::NameSize);    Symbol->Value = 0;    Symbol->SectionNumber = 1;    Symbol->Type = llvm::COFF::IMAGE_SYM_DTYPE_NULL;    Symbol->StorageClass = llvm::COFF::IMAGE_SYM_CLASS_STATIC;    Symbol->NumberOfAuxSymbols = 1; -  Current += sizeof(llvm::object::coff_symbol16); -  auto *Aux = -      reinterpret_cast<llvm::object::coff_aux_section_definition *>(Current); +  CurrentOffset += sizeof(llvm::object::coff_symbol16); +  auto *Aux = reinterpret_cast<llvm::object::coff_aux_section_definition *>( +      BufferStart + CurrentOffset);    Aux->Length = SectionOneSize;    Aux->NumberOfRelocations = Data.size();    Aux->NumberOfLinenumbers = 0;    Aux->CheckSum = 0;    Aux->NumberLowPart = 0;    Aux->Selection = 0; -  Current += sizeof(llvm::object::coff_aux_section_definition); +  CurrentOffset += sizeof(llvm::object::coff_aux_section_definition);    // Now write the .rsrc2 symbol + aux. -  Symbol = reinterpret_cast<llvm::object::coff_symbol16 *>(Current); +  Symbol = reinterpret_cast<llvm::object::coff_symbol16 *>(BufferStart + +                                                           CurrentOffset);    strncpy(Symbol->Name.ShortName, ".rsrc$02", (size_t)llvm::COFF::NameSize);    Symbol->Value = 0;    Symbol->SectionNumber = 2;    Symbol->Type = llvm::COFF::IMAGE_SYM_DTYPE_NULL;    Symbol->StorageClass = llvm::COFF::IMAGE_SYM_CLASS_STATIC;    Symbol->NumberOfAuxSymbols = 1; -  Current += sizeof(llvm::object::coff_symbol16); -  Aux = reinterpret_cast<llvm::object::coff_aux_section_definition *>(Current); +  CurrentOffset += sizeof(llvm::object::coff_symbol16); +  Aux = reinterpret_cast<llvm::object::coff_aux_section_definition *>( +      BufferStart + CurrentOffset);    Aux->Length = SectionTwoSize;    Aux->NumberOfRelocations = 0;    Aux->NumberOfLinenumbers = 0;    Aux->CheckSum = 0;    Aux->NumberLowPart = 0;    Aux->Selection = 0; -  Current += sizeof(llvm::object::coff_aux_section_definition); +  CurrentOffset += sizeof(llvm::object::coff_aux_section_definition);    // Now write a symbol for each relocation.    for (unsigned i = 0; i < Data.size(); i++) {      char RelocationName[9];      sprintf(RelocationName, "$R%06X", DataOffsets[i]); -    Symbol = reinterpret_cast<llvm::object::coff_symbol16 *>(Current); +    Symbol = reinterpret_cast<llvm::object::coff_symbol16 *>(BufferStart + +                                                             CurrentOffset);      strncpy(Symbol->Name.ShortName, RelocationName,              (size_t)llvm::COFF::NameSize);      Symbol->Value = DataOffsets[i]; @@ -568,14 +592,15 @@ void WindowsResourceCOFFWriter::writeSymbolTable() {      Symbol->Type = llvm::COFF::IMAGE_SYM_DTYPE_NULL;      Symbol->StorageClass = llvm::COFF::IMAGE_SYM_CLASS_STATIC;      Symbol->NumberOfAuxSymbols = 0; -    Current += sizeof(llvm::object::coff_symbol16); +    CurrentOffset += sizeof(llvm::object::coff_symbol16);    }  }  void WindowsResourceCOFFWriter::writeStringTable() {    // Just 4 null bytes for the string table. -  auto COFFStringTable = reinterpret_cast<void *>(Current); -  memset(COFFStringTable, 0, 4); +  auto COFFStringTable = +      reinterpret_cast<uint32_t *>(BufferStart + CurrentOffset); +  *COFFStringTable = 0;  }  void WindowsResourceCOFFWriter::writeDirectoryTree() { @@ -593,8 +618,8 @@ void WindowsResourceCOFFWriter::writeDirectoryTree() {    while (!Queue.empty()) {      auto CurrentNode = Queue.front();      Queue.pop(); -    auto *Table = -        reinterpret_cast<llvm::object::coff_resource_dir_table *>(Current); +    auto *Table = reinterpret_cast<llvm::object::coff_resource_dir_table *>( +        BufferStart + CurrentOffset);      Table->Characteristics = CurrentNode->getCharacteristics();      Table->TimeDateStamp = 0;      Table->MajorVersion = CurrentNode->getMajorVersion(); @@ -603,13 +628,13 @@ void WindowsResourceCOFFWriter::writeDirectoryTree() {      auto &StringChildren = CurrentNode->getStringChildren();      Table->NumberOfNameEntries = StringChildren.size();      Table->NumberOfIDEntries = IDChildren.size(); -    Current += sizeof(llvm::object::coff_resource_dir_table); +    CurrentOffset += sizeof(llvm::object::coff_resource_dir_table);      CurrentRelativeOffset += sizeof(llvm::object::coff_resource_dir_table);      // Write the directory entries immediately following each directory table.      for (auto const &Child : StringChildren) { -      auto *Entry = -          reinterpret_cast<llvm::object::coff_resource_dir_entry *>(Current); +      auto *Entry = reinterpret_cast<llvm::object::coff_resource_dir_entry *>( +          BufferStart + CurrentOffset);        Entry->Identifier.NameOffset =            StringTableOffsets[Child.second->getStringIndex()];        if (Child.second->checkIsDataNode()) { @@ -624,12 +649,12 @@ void WindowsResourceCOFFWriter::writeDirectoryTree() {                                 sizeof(llvm::object::coff_resource_dir_entry);          Queue.push(Child.second.get());        } -      Current += sizeof(llvm::object::coff_resource_dir_entry); +      CurrentOffset += sizeof(llvm::object::coff_resource_dir_entry);        CurrentRelativeOffset += sizeof(llvm::object::coff_resource_dir_entry);      }      for (auto const &Child : IDChildren) { -      auto *Entry = -          reinterpret_cast<llvm::object::coff_resource_dir_entry *>(Current); +      auto *Entry = reinterpret_cast<llvm::object::coff_resource_dir_entry *>( +          BufferStart + CurrentOffset);        Entry->Identifier.ID = Child.first;        if (Child.second->checkIsDataNode()) {          Entry->Offset.DataEntryOffset = NextLevelOffset; @@ -643,7 +668,7 @@ void WindowsResourceCOFFWriter::writeDirectoryTree() {                                 sizeof(llvm::object::coff_resource_dir_entry);          Queue.push(Child.second.get());        } -      Current += sizeof(llvm::object::coff_resource_dir_entry); +      CurrentOffset += sizeof(llvm::object::coff_resource_dir_entry);        CurrentRelativeOffset += sizeof(llvm::object::coff_resource_dir_entry);      }    } @@ -651,14 +676,14 @@ void WindowsResourceCOFFWriter::writeDirectoryTree() {    RelocationAddresses.resize(Data.size());    // Now write all the resource data entries.    for (auto DataNodes : DataEntriesTreeOrder) { -    auto *Entry = -        reinterpret_cast<llvm::object::coff_resource_data_entry *>(Current); +    auto *Entry = reinterpret_cast<llvm::object::coff_resource_data_entry *>( +        BufferStart + CurrentOffset);      RelocationAddresses[DataNodes->getDataIndex()] = CurrentRelativeOffset;      Entry->DataRVA = 0; // Set to zero because it is a relocation.      Entry->DataSize = Data[DataNodes->getDataIndex()].size();      Entry->Codepage = 0;      Entry->Reserved = 0; -    Current += sizeof(llvm::object::coff_resource_data_entry); +    CurrentOffset += sizeof(llvm::object::coff_resource_data_entry);      CurrentRelativeOffset += sizeof(llvm::object::coff_resource_data_entry);    }  } @@ -667,16 +692,17 @@ void WindowsResourceCOFFWriter::writeDirectoryStringTable() {    // Now write the directory string table for .rsrc$01    uint32_t TotalStringTableSize = 0;    for (auto String : StringTable) { -    auto *LengthField = reinterpret_cast<uint16_t *>(Current); +    auto *LengthField = +        reinterpret_cast<uint16_t *>(BufferStart + CurrentOffset);      uint16_t Length = String.size();      *LengthField = Length; -    Current += sizeof(uint16_t); -    auto *Start = reinterpret_cast<UTF16 *>(Current); +    CurrentOffset += sizeof(uint16_t); +    auto *Start = reinterpret_cast<UTF16 *>(BufferStart + CurrentOffset);      std::copy(String.begin(), String.end(), Start); -    Current += Length * sizeof(UTF16); +    CurrentOffset += Length * sizeof(UTF16);      TotalStringTableSize += Length * sizeof(UTF16) + sizeof(uint16_t);    } -  Current += +  CurrentOffset +=        alignTo(TotalStringTableSize, sizeof(uint32_t)) - TotalStringTableSize;  } @@ -687,7 +713,8 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {    // .rsrc section.    uint32_t NextSymbolIndex = 5;    for (unsigned i = 0; i < Data.size(); i++) { -    auto *Reloc = reinterpret_cast<llvm::object::coff_relocation *>(Current); +    auto *Reloc = reinterpret_cast<llvm::object::coff_relocation *>( +        BufferStart + CurrentOffset);      Reloc->VirtualAddress = RelocationAddresses[i];      Reloc->SymbolTableIndex = NextSymbolIndex++;      switch (MachineType) { @@ -703,7 +730,7 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {      default:        Reloc->Type = 0;      } -    Current += sizeof(llvm::object::coff_relocation); +    CurrentOffset += sizeof(llvm::object::coff_relocation);    }  } diff --git a/llvm/test/tools/llvm-cvtres/Inputs/combined.obj.coff b/llvm/test/tools/llvm-cvtres/Inputs/combined.obj.coff Binary files differnew file mode 100644 index 00000000000..bbb670b258e --- /dev/null +++ b/llvm/test/tools/llvm-cvtres/Inputs/combined.obj.coff diff --git a/llvm/test/tools/llvm-cvtres/Inputs/languages.rc b/llvm/test/tools/llvm-cvtres/Inputs/languages.rc new file mode 100644 index 00000000000..081b3a77beb --- /dev/null +++ b/llvm/test/tools/llvm-cvtres/Inputs/languages.rc @@ -0,0 +1,36 @@ +#include "windows.h"
 +
 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 +randomdat RCDATA
 +{
 +	"this is a random bit of data that means nothing\0",
 +	0x23a9,
 +	0x140e,
 +	194292,
 +}
 +
 +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 +randomdat RCDATA
 +{
 +	"zhe4 shi4 yi1ge4 sui2ji1 de shu4ju4, zhe4 yi4wei4zhe shen2me\0",
 +	0x23a9,
 +	0x140e,
 +	194292,
 +}
 +
 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_LUXEMBOURG
 +randomdat RCDATA
 +{
 +	"Dies ist ein zufälliges Bit von Daten, die nichts bedeutet\0",
 +	0x23a9,
 +	0x140e,
 +	194292,
 +}
 +
 +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 +myaccelerators ACCELERATORS
 +{
 +	"^C", 999, VIRTKEY, ALT
 +	"D", 1100, VIRTKEY, CONTROL, SHIFT
 +	"^R", 444, ASCII, NOINVERT
 +}
 diff --git a/llvm/test/tools/llvm-cvtres/Inputs/languages.res b/llvm/test/tools/llvm-cvtres/Inputs/languages.res Binary files differnew file mode 100644 index 00000000000..31da6166d7f --- /dev/null +++ b/llvm/test/tools/llvm-cvtres/Inputs/languages.res diff --git a/llvm/test/tools/llvm-cvtres/Inputs/test_resource.obj.coff.arm b/llvm/test/tools/llvm-cvtres/Inputs/test_resource.obj.coff.arm Binary files differnew file mode 100644 index 00000000000..ca2f9a4fd04 --- /dev/null +++ b/llvm/test/tools/llvm-cvtres/Inputs/test_resource.obj.coff.arm diff --git a/llvm/test/tools/llvm-cvtres/Inputs/test_resource.obj.coff.x64 b/llvm/test/tools/llvm-cvtres/Inputs/test_resource.obj.coff.x64 Binary files differnew file mode 100644 index 00000000000..4620f97f0af --- /dev/null +++ b/llvm/test/tools/llvm-cvtres/Inputs/test_resource.obj.coff.x64 diff --git a/llvm/test/tools/llvm-cvtres/basic.test b/llvm/test/tools/llvm-cvtres/basic.test deleted file mode 100644 index fcebef22f65..00000000000 --- a/llvm/test/tools/llvm-cvtres/basic.test +++ /dev/null @@ -1,4 +0,0 @@ -; RUN: llvm-cvtres /h > %t -; RUN: FileCheck -input-file=%t %s -check-prefix=HELP_TEST - -; HELP_TEST: OVERVIEW: Resource Converter diff --git a/llvm/test/tools/llvm-cvtres/combined.test b/llvm/test/tools/llvm-cvtres/combined.test new file mode 100644 index 00000000000..bb3b4dbc736 --- /dev/null +++ b/llvm/test/tools/llvm-cvtres/combined.test @@ -0,0 +1,313 @@ +// Check that cvtres properly handles merging multiple .res files. +// The inputs were generated with the following commands, using the original Windows +// rc.exe: +// > rc /fo test_resource.res /nologo test_resource.rc +// > rc /fo languages.res /nologo languages.rc +// The object file we are comparing against was generated with this command using +// the original Windows cvtres.exe. +// > cvtres /machine:X86 /readonly /nologo /out:combined.obj.coff \ +//   languages.res test_resource.res + +RUN: llvm-cvtres /out:%t %p/Inputs/languages.res %p/Inputs/test_resource.res +RUN: llvm-readobj -coff-resources -section-data %t | FileCheck %s + +CHECK:     Resources [ +CHECK-NEXT:  Total Number of Resources: 12 +CHECK-DAG:   Number of String Entries: 1 +CHECK-NEXT:  Number of ID Entries: 5 +CHECK-NEXT:  Type: STRINGARRAY [ +CHECK-NEXT:    Table Offset: 0x40 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 0 +CHECK-NEXT:    Name: MYRESOURCE [ +CHECK-NEXT:      Table Offset: 0xE8 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x1D8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_BITMAP (ID 2) [ +CHECK-NEXT:    Table Offset: 0x58 +CHECK-NEXT:    Number of String Entries: 2 +CHECK-NEXT:    Number of ID Entries: 0 +CHECK-NEXT:    Name: CURSOR [ +CHECK-NEXT:      Table Offset: 0x100 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x1E8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:    Name: OKAY [ +CHECK-NEXT:      Table Offset: 0x118 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x1F8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_MENU (ID 4) [ +CHECK-NEXT:    Table Offset: 0x78 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 1 +CHECK-NEXT:    Name: "EAT" [ +CHECK-NEXT:      Table Offset: 0x130 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 3081) [ +CHECK-NEXT:        Entry Offset: 0x208 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:    Name: (ID 14432) [ +CHECK-NEXT:      Table Offset: 0x148 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 2052) [ +CHECK-NEXT:        Entry Offset: 0x218 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_DIALOG (ID 5) [ +CHECK-NEXT:    Table Offset: 0x98 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 0 +CHECK-NEXT:    Name: TESTDIALOG [ +CHECK-NEXT:      Table Offset: 0x160 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x228 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_ACCELERATOR (ID 9) [ +CHECK-NEXT:    Table Offset: 0xB0 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 1 +CHECK-NEXT:    Name: MYACCELERATORS [ +CHECK-NEXT:      Table Offset: 0x178 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 2 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x238 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:      Language: (ID 2052) [ +CHECK-NEXT:        Entry Offset: 0x248 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:    Name: (ID 12) [ +CHECK-NEXT:      Table Offset: 0x198 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x258 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_RCDATA (ID 10) [ +CHECK-NEXT:    Table Offset: 0xD0 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 0 +CHECK-NEXT:    Name: RANDOMDAT [ +CHECK-NEXT:      Table Offset: 0x1B0 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 3 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x268 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:      Language: (ID 2052) [ +CHECK-NEXT:        Entry Offset: 0x278 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:      Language: (ID 4103) [ +CHECK-NEXT:        Entry Offset: 0x288 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-DAG:    .rsrc$02 Data ( +CHECK-NEXT:     0000: 74686973 20697320 61207261 6E646F6D  |this is a random| +CHECK-NEXT:     0010: 20626974 206F6620 64617461 20746861  | bit of data tha| +CHECK-NEXT:     0020: 74206D65 616E7320 6E6F7468 696E6700  |t means nothing.| +CHECK-NEXT:     0030: A9230E14 F4F60000 7A686534 20736869  |.#......zhe4 shi| +CHECK-NEXT:     0040: 34207969 31676534 20737569 326A6931  |4 yi1ge4 sui2ji1| +CHECK-NEXT:     0050: 20646520 73687534 6A75342C 207A6865  | de shu4ju4, zhe| +CHECK-NEXT:     0060: 34207969 34776569 347A6865 20736865  |4 yi4wei4zhe she| +CHECK-NEXT:     0070: 6E326D65 00A9230E 14F4F600 00000000  |n2me..#.........| +CHECK-NEXT:     0080: 44696573 20697374 2065696E 207A7566  |Dies ist ein zuf| +CHECK-NEXT:     0090: C3A46C6C 69676573 20426974 20766F6E  |..lliges Bit von| +CHECK-NEXT:     00A0: 20446174 656E2C20 64696520 6E696368  | Daten, die nich| +CHECK-NEXT:     00B0: 74732062 65646575 74657400 A9230E14  |ts bedeutet..#..| +CHECK-NEXT:     00C0: F4F60000 00000000 11000300 E7030000  |................| +CHECK-NEXT:     00D0: 0D004400 4C040000 82001200 BC010000  |..D.L...........| +CHECK-NEXT:     00E0: 11000300 E7030000 0D004400 4C040000  |..........D.L...| +CHECK-NEXT:     00F0: 82001200 BC010000 28000000 10000000  |........(.......| +CHECK-NEXT:     0100: 10000000 01001800 00000000 00030000  |................| +CHECK-NEXT:     0110: C40E0000 C40E0000 00000000 00000000  |................| +CHECK-NEXT:     0120: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0130: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0140: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0150: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0160: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0170: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0180: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0190: FFFFFFFF FF7F7F7F 7C7C7C78 78787575  |........|||xxxuu| +CHECK-NEXT:     01A0: 75FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |u...............| +CHECK-NEXT:     01B0: FFFFFFFF FFFFFFFF FFFFFFFF 979797FF  |................| +CHECK-NEXT:     01C0: FFFFFFFF FF838383 AAAAAADB DBDB7979  |..............yy| +CHECK-NEXT:     01D0: 79757575 FFFFFFFF FFFFFFFF FFFFFFFF  |yuuu............| +CHECK-NEXT:     01E0: FFFFFFFF FFFFFFFF FFFFFFFF 9C9C9C98  |................| +CHECK-NEXT:     01F0: 9898FFFF FF888888 DBDBDBB7 B7B77D7D  |..............}}| +CHECK-NEXT:     0200: 7DFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |}...............| +CHECK-NEXT:     0210: FFFFFFFF FFFFFFFF FFFFFFFF A0A0A09C  |................| +CHECK-NEXT:     0220: 9C9C9393 93ADADAD F2F2F284 84848181  |................| +CHECK-NEXT:     0230: 81FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0240: FFFFFFFF FFFFFFFF FFFFFFFF A4A4A4D7  |................| +CHECK-NEXT:     0250: D7D79D9D 9DD0D0D0 EEEEEE91 91918D8D  |................| +CHECK-NEXT:     0260: 8DFFFFFF FFFFFF81 81817E7E 7EFFFFFF  |..........~~~...| +CHECK-NEXT:     0270: FFFFFFFF FFFFFFFF FFFFFFFF A9A9A9F2  |................| +CHECK-NEXT:     0280: F2F2E5E5 E5E2E2E2 95959591 91918D8D  |................| +CHECK-NEXT:     0290: 8D898989 868686FF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     02A0: FFFFFFFF FFFFFFFF FFFFFFFF ADADADF2  |................| +CHECK-NEXT:     02B0: F2F2E1E1 E1DFDFDF E7E7E7E4 E4E4BBBB  |................| +CHECK-NEXT:     02C0: BB8E8E8E FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     02D0: FFFFFFFF FFFFFFFF FFFFFFFF B5B5B5F2  |................| +CHECK-NEXT:     02E0: F2F2E8E8 E8E7E7E7 EAEAEAC6 C6C69E9E  |................| +CHECK-NEXT:     02F0: 9EFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0300: FFFFFFFF FFFFFFFF FFFFFFFF B9B9B9F4  |................| +CHECK-NEXT:     0310: F4F4ECEC ECEDEDED CBCBCBA7 A7A7FFFF  |................| +CHECK-NEXT:     0320: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0330: FFFFFFFF FFFFFFFF FFFFFFFF BDBDBDF7  |................| +CHECK-NEXT:     0340: F7F7EFEF EFD0D0D0 AFAFAFFF FFFFFFFF  |................| +CHECK-NEXT:     0350: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0360: FFFFFFFF FFFFFFFF FFFFFFFF C1C1C1F7  |................| +CHECK-NEXT:     0370: F7F7D5D5 D5B6B6B6 FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0380: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0390: FFFFFFFF FFFFFFFF FFFFFFFF C4C4C4D9  |................| +CHECK-NEXT:     03A0: D9D9BEBE BEFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     03B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     03C0: FFFFFFFF FFFFFFFF FFFFFFFF C8C8C8C5  |................| +CHECK-NEXT:     03D0: C5C5FFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     03E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     03F0: FFFFFFFF FFFFFFFF FFFFFFFF CBCBCBFF  |................| +CHECK-NEXT:     0400: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0410: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0420: 28000000 10000000 10000000 01001800  |(...............| +CHECK-NEXT:     0430: 00000000 00030000 C40E0000 C40E0000  |................| +CHECK-NEXT:     0440: 00000000 00000000 FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0450: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0460: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0470: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0480: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0490: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     04A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     04B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     04C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     04D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     04E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     04F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0500: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0510: FFFFFFFF A0E3A901 B31801B3 1801B318  |................| +CHECK-NEXT:     0520: 01B31801 B31801B3 1861D06F FFFFFFFF  |.........a.o....| +CHECK-NEXT:     0530: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0540: FFFFFFFF 01B31800 D7331CDB 49DBF9E2  |.........3..I...| +CHECK-NEXT:     0550: 9BEFAF00 D73300D7 3301B318 FFFFFFFF  |.....3..3.......| +CHECK-NEXT:     0560: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0570: FFFFFFFF 01B31800 DE55F6FE F9DBFAE7  |.........U......| +CHECK-NEXT:     0580: FEFFFE86 EFAE00DE 5501B318 FFFFFFFF  |........U.......| +CHECK-NEXT:     0590: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     05A0: FFFFFFFF 01B31800 E676DBFB EC00E676  |.........v.....v| +CHECK-NEXT:     05B0: 57EFA5FB FFFD55EE A401B318 FFFFFFFF  |W.....U.........| +CHECK-NEXT:     05C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     05D0: FFFFFFFF 01B31800 ED9800ED 9800ED98  |................| +CHECK-NEXT:     05E0: 00ED9887 F7CFFEFF FF01B318 FFFFFFFF  |................| +CHECK-NEXT:     05F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0600: FFFFFFFF 01B31800 F4BA00F4 BA00F4BA  |................| +CHECK-NEXT:     0610: 00F4BA00 F4BA9CFB E401B318 FFFFFFFF  |................| +CHECK-NEXT:     0620: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0630: FFFFFFFF 01B31800 FBDB00FB DB00FBDB  |................| +CHECK-NEXT:     0640: 00FBDB00 FBDB00FB DB01B318 FFFFFFFF  |................| +CHECK-NEXT:     0650: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0660: FFFFFFFF 9FE2A801 B31801B3 1801B318  |................| +CHECK-NEXT:     0670: 01B31801 B31801B3 1861D06F FFFFFFFF  |.........a.o....| +CHECK-NEXT:     0680: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0690: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     06A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     06B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     06C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     06D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     06E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     06F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0700: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0710: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0720: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0730: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................| +CHECK-NEXT:     0740: FFFFFFFF FFFFFFFF 00000000 00006400  |..............d.| +CHECK-NEXT:     0750: 79007500 00000000 65007300 68006100  |y.u.....e.s.h.a.| +CHECK-NEXT:     0760: 6C006100 00008000 66006B00 61006F00  |l.a.....f.k.a.o.| +CHECK-NEXT:     0770: 79006100 00000000 0000C080 00000000  |y.a.............| +CHECK-NEXT:     0780: 02000A00 0A00C800 2C010000 00005400  |........,.....T.| +CHECK-NEXT:     0790: 65007300 74000000 01000250 00000000  |e.s.t......P....| +CHECK-NEXT:     07A0: 0A000A00 E6000E00 0100FFFF 82004300  |..............C.| +CHECK-NEXT:     07B0: 6F006E00 74006900 6E007500 65003A00  |o.n.t.i.n.u.e.:.| +CHECK-NEXT:     07C0: 00000000 00000150 00000000 42008600  |.......P....B...| +CHECK-NEXT:     07D0: A1000D00 0200FFFF 80002600 4F004B00  |..........&.O.K.| +CHECK-NEXT:     07E0: 00000000 00000000 11005800 A4000000  |..........X.....| +CHECK-NEXT:     07F0: 0D004800 2E160000 82001200 BC010000  |..H.............| +CHECK-NEXT:     0800: 00000000 00006400 66006900 73006800  |......d.f.i.s.h.| +CHECK-NEXT:     0810: 00000000 65007300 61006C00 61006400  |....e.s.a.l.a.d.| +CHECK-NEXT:     0820: 00008000 66006400 75006300 6B000000  |....f.d.u.c.k...| +CHECK-NEXT:     0830: 74686973 20697320 61207573 65722064  |this is a user d| +CHECK-NEXT:     0840: 6566696E 65642072 65736F75 72636500  |efined resource.| +CHECK-NEXT:     0850: 69742063 6F6E7461 696E7320 6D616E79  |it contains many| +CHECK-NEXT:     0860: 20737472 696E6773 00000000 00000000  | strings........| +CHECK-NEXT:   ) diff --git a/llvm/test/tools/llvm-cvtres/help.test b/llvm/test/tools/llvm-cvtres/help.test new file mode 100644 index 00000000000..ed76e1f126e --- /dev/null +++ b/llvm/test/tools/llvm-cvtres/help.test @@ -0,0 +1,13 @@ +; RUN: llvm-cvtres /h > %t +; RUN: FileCheck -input-file=%t %s -check-prefix=HELP_TEST + +; HELP_TEST: 	  OVERVIEW: Resource Converter +; HELP_TEST-DAG:  USAGE: cvtres [options] <inputs> +; HELP_TEST-DAG:  OPTIONS: +; HELP_TEST-NEXT:   /DEFINE:symbol  +; HELP_TEST-NEXT:   /FOLDDUPS:      +; HELP_TEST-NEXT:   /MACHINE:{ARM|EBC|IA64|X64|X86} +; HELP_TEST-DAG:    /NOLOGO         +; HELP_TEST-NEXT:   /OUT:filename   +; HELP_TEST-NEXT:   /READONLY       +; HELP_TEST-NEXT:   /VERBOSE diff --git a/llvm/test/tools/llvm-cvtres/machine.test b/llvm/test/tools/llvm-cvtres/machine.test new file mode 100644 index 00000000000..58096d1d8ed --- /dev/null +++ b/llvm/test/tools/llvm-cvtres/machine.test @@ -0,0 +1,59 @@ +// Check that cvtres properly generates COFF for different machine types. The +// only things that changes with machine type are the machine constant listed +// in the COFF header, and the relocation types in the relocation tables. +// The input was generated with the following command, using the original Windows +// rc.exe: +// > rc /fo test_resource.res /nologo test_resource.rc +// The object files we are comparing against were generated with these commands +// using the original Windows cvtres.exe. +// > cvtres /machine:X86 /readonly /nologo /out:test_resource.obj.coff \  +// 	 test_resource.res +// > cvtres /machine:X64 /readonly /nologo /out:test_resource.obj.coff.x64 \  +// 	 test_resource.res +// > cvtres /machine:ARM /readonly /nologo /out:test_resource.obj.coff.x64 \  +// 	 test_resource.res + +RUN: llvm-cvtres /machine:X86 /out:%t %p/Inputs/test_resource.res +RUN: llvm-readobj -h -relocations %t | FileCheck %s -check-prefix=X86 + +RUN: llvm-cvtres /machine:X64 /out:%t %p/Inputs/test_resource.res +RUN: llvm-readobj -h -relocations %t | FileCheck %s -check-prefix=X64 + +RUN: llvm-cvtres /machine:ARM /out:%t %p/Inputs/test_resource.res +RUN: llvm-readobj -h -relocations %t | FileCheck %s -check-prefix=ARM + +X86:         Machine: IMAGE_FILE_MACHINE_I386 (0x14C) +X86-DAG:   Relocations [ +X86-DAG:                 .rsrc$01 { +X86-NEXT:      0x1E8 IMAGE_REL_I386_DIR32NB $R000000 +X86-NEXT:      0x198 IMAGE_REL_I386_DIR32NB $R000018 +X86-NEXT:      0x1A8 IMAGE_REL_I386_DIR32NB $R000340 +X86-NEXT:      0x1C8 IMAGE_REL_I386_DIR32NB $R000668 +X86-NEXT:      0x1D8 IMAGE_REL_I386_DIR32NB $R000698 +X86-NEXT:      0x1F8 IMAGE_REL_I386_DIR32NB $R000708 +X86-NEXT:      0x1B8 IMAGE_REL_I386_DIR32NB $R000720 +X86-NEXT:      0x188 IMAGE_REL_I386_DIR32NB $R000750 + +X64:         Machine: IMAGE_FILE_MACHINE_AMD64 (0x8664) +X64-DAG:   Relocations [ +X64-DAG:                 .rsrc$01 { +X64-NEXT:      0x1E8 IMAGE_REL_AMD64_ADDR32NB $R000000 +X64-NEXT:      0x198 IMAGE_REL_AMD64_ADDR32NB $R000018 +X64-NEXT:      0x1A8 IMAGE_REL_AMD64_ADDR32NB $R000340 +X64-NEXT:      0x1C8 IMAGE_REL_AMD64_ADDR32NB $R000668 +X64-NEXT:      0x1D8 IMAGE_REL_AMD64_ADDR32NB $R000698 +X64-NEXT:      0x1F8 IMAGE_REL_AMD64_ADDR32NB $R000708 +X64-NEXT:      0x1B8 IMAGE_REL_AMD64_ADDR32NB $R000720 +X64-NEXT:      0x188 IMAGE_REL_AMD64_ADDR32NB $R000750 + +ARM:         Machine: IMAGE_FILE_MACHINE_ARMNT (0x1C4) +ARM-DAG:   Relocations [ +ARM-DAG:                 .rsrc$01 { +ARM-NEXT:      0x1E8 IMAGE_REL_ARM_ADDR32NB $R000000 +ARM-NEXT:      0x198 IMAGE_REL_ARM_ADDR32NB $R000018 +ARM-NEXT:      0x1A8 IMAGE_REL_ARM_ADDR32NB $R000340 +ARM-NEXT:      0x1C8 IMAGE_REL_ARM_ADDR32NB $R000668 +ARM-NEXT:      0x1D8 IMAGE_REL_ARM_ADDR32NB $R000698 +ARM-NEXT:      0x1F8 IMAGE_REL_ARM_ADDR32NB $R000708 +ARM-NEXT:      0x1B8 IMAGE_REL_ARM_ADDR32NB $R000720 +ARM-NEXT:      0x188 IMAGE_REL_ARM_ADDR32NB $R000750 diff --git a/llvm/test/tools/llvm-cvtres/object.test b/llvm/test/tools/llvm-cvtres/object.test index 8117ecc910c..12373e0ac7f 100644 --- a/llvm/test/tools/llvm-cvtres/object.test +++ b/llvm/test/tools/llvm-cvtres/object.test @@ -3,107 +3,138 @@  // rc.exe:  // > rc /fo test_resource.res /nologo test_resource.rc  // The object file we are comparing against was generated with this command using -// the original cvtres. -// > cvtres /machine:X86 /readonly /nologo /out:test_resource.o test_resource.res +// the original Windows cvtres.exe. +// > cvtres /machine:X86 /readonly /nologo /out:test_resource.obj.coff \ +//   test_resource.res  RUN: llvm-cvtres /out:%t %p/Inputs/test_resource.res  RUN: llvm-readobj -coff-resources -section-data %t | FileCheck %s -CHECK:      Resources [ -CHECK-NEXT:   String Name Entries: 1 -CHECK-NEXT:   ID Entries: 4 -CHECK-NEXT:   Type: STRINGARRAY [ -CHECK-NEXT:     String Name Entries: 1 -CHECK-NEXT:     ID Entries: 0 -CHECK-NEXT:     Name: MYRESOURCE [ -CHECK-NEXT:       String Name Entries: 0 -CHECK-NEXT:       ID Entries: 1 -CHECK-NEXT:       Language: (ID 1033) [ -CHECK-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -CHECK-NEXT:         Major Version: 0 -CHECK-NEXT:         Minor Version: 0 -CHECK-NEXT:       ] -CHECK-NEXT:     ] -CHECK-NEXT:   ] -CHECK-NEXT:   Type: kRT_BITMAP (ID 2) [ -CHECK-NEXT:     String Name Entries: 2 -CHECK-NEXT:     ID Entries: 0 -CHECK-NEXT:     Name: CURSOR [ -CHECK-NEXT:       String Name Entries: 0 -CHECK-NEXT:       ID Entries: 1 -CHECK-NEXT:       Language: (ID 1033) [ -CHECK-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -CHECK-NEXT:         Major Version: 0 -CHECK-NEXT:         Minor Version: 0 -CHECK-NEXT:       ] -CHECK-NEXT:     ] -CHECK-NEXT:     Name: OKAY [ -CHECK-NEXT:       String Name Entries: 0 -CHECK-NEXT:       ID Entries: 1 -CHECK-NEXT:       Language: (ID 1033) [ -CHECK-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -CHECK-NEXT:         Major Version: 0 -CHECK-NEXT:         Minor Version: 0 -CHECK-NEXT:       ] -CHECK-NEXT:     ] -CHECK-NEXT:   ] -CHECK-NEXT:   Type: kRT_MENU (ID 4) [ -CHECK-NEXT:     String Name Entries: 1 -CHECK-NEXT:     ID Entries: 1 -CHECK-NEXT:     Name: "EAT" [ -CHECK-NEXT:       String Name Entries: 0 -CHECK-NEXT:       ID Entries: 1 -CHECK-NEXT:       Language: (ID 3081) [ -CHECK-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -CHECK-NEXT:         Major Version: 0 -CHECK-NEXT:         Minor Version: 0 -CHECK-NEXT:       ] -CHECK-NEXT:     ] -CHECK-NEXT:     Name: (ID 14432) [ -CHECK-NEXT:       String Name Entries: 0 -CHECK-NEXT:       ID Entries: 1 -CHECK-NEXT:       Language: (ID 2052) [ -CHECK-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -CHECK-NEXT:         Major Version: 0 -CHECK-NEXT:         Minor Version: 0 -CHECK-NEXT:       ] -CHECK-NEXT:     ] -CHECK-NEXT:   ] -CHECK-NEXT:   Type: kRT_DIALOG (ID 5) [ -CHECK-NEXT:     String Name Entries: 1 -CHECK-NEXT:     ID Entries: 0 -CHECK-NEXT:     Name: TESTDIALOG [ -CHECK-NEXT:       String Name Entries: 0 -CHECK-NEXT:       ID Entries: 1 -CHECK-NEXT:       Language: (ID 1033) [ -CHECK-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -CHECK-NEXT:         Major Version: 0 -CHECK-NEXT:         Minor Version: 0 -CHECK-NEXT:       ] -CHECK-NEXT:     ] -CHECK-NEXT:   ] -CHECK-NEXT:   Type: kRT_ACCELERATOR (ID 9) [ -CHECK-NEXT:     String Name Entries: 1 -CHECK-NEXT:     ID Entries: 1 -CHECK-NEXT:     Name: MYACCELERATORS [ -CHECK-NEXT:       String Name Entries: 0 -CHECK-NEXT:       ID Entries: 1 -CHECK-NEXT:       Language: (ID 1033) [ -CHECK-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -CHECK-NEXT:         Major Version: 0 -CHECK-NEXT:         Minor Version: 0 -CHECK-NEXT:       ] -CHECK-NEXT:     ] -CHECK-NEXT:     Name: (ID 12) [ -CHECK-NEXT:       String Name Entries: 0 -CHECK-NEXT:       ID Entries: 1 -CHECK-NEXT:       Language: (ID 1033) [ -CHECK-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -CHECK-NEXT:         Major Version: 0 -CHECK-NEXT:         Minor Version: 0 -CHECK-NEXT:       ] -CHECK-NEXT:     ] -CHECK-NEXT:   ] +CHECK:     Resources [ +CHECK-NEXT:  Total Number of Resources: 8 +CHECK-DAG:   Number of String Entries: 1 +CHECK-NEXT:  Number of ID Entries: 4 +CHECK-NEXT:  Type: STRINGARRAY [ +CHECK-NEXT:    Table Offset: 0x38 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 0 +CHECK-NEXT:    Name: MYRESOURCE [ +CHECK-NEXT:      Table Offset: 0xC8 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x188 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_BITMAP (ID 2) [ +CHECK-NEXT:    Table Offset: 0x50 +CHECK-NEXT:    Number of String Entries: 2 +CHECK-NEXT:    Number of ID Entries: 0 +CHECK-NEXT:    Name: CURSOR [ +CHECK-NEXT:      Table Offset: 0xE0 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x198 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:    Name: OKAY [ +CHECK-NEXT:      Table Offset: 0xF8 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x1A8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_MENU (ID 4) [ +CHECK-NEXT:    Table Offset: 0x70 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 1 +CHECK-NEXT:    Name: "EAT" [ +CHECK-NEXT:      Table Offset: 0x110 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 3081) [ +CHECK-NEXT:        Entry Offset: 0x1B8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:    Name: (ID 14432) [ +CHECK-NEXT:      Table Offset: 0x128 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 2052) [ +CHECK-NEXT:        Entry Offset: 0x1C8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_DIALOG (ID 5) [ +CHECK-NEXT:    Table Offset: 0x90 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 0 +CHECK-NEXT:    Name: TESTDIALOG [ +CHECK-NEXT:      Table Offset: 0x140 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x1D8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ] +CHECK-NEXT:  Type: kRT_ACCELERATOR (ID 9) [ +CHECK-NEXT:    Table Offset: 0xA8 +CHECK-NEXT:    Number of String Entries: 1 +CHECK-NEXT:    Number of ID Entries: 1 +CHECK-NEXT:    Name: MYACCELERATORS [ +CHECK-NEXT:      Table Offset: 0x158 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x1E8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:    Name: (ID 12) [ +CHECK-NEXT:      Table Offset: 0x170 +CHECK-NEXT:      Number of String Entries: 0 +CHECK-NEXT:      Number of ID Entries: 1 +CHECK-NEXT:      Language: (ID 1033) [ +CHECK-NEXT:        Entry Offset: 0x1F8 +CHECK-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +CHECK-NEXT:        Major Version: 0 +CHECK-NEXT:        Minor Version: 0 +CHECK-NEXT:        Characteristics: 0 +CHECK-NEXT:      ] +CHECK-NEXT:    ] +CHECK-NEXT:  ]  CHECK-DAG:   .rsrc$02 Data (  CHECK-NEXT:    0000: 11000300 E7030000 0D004400 4C040000  |..........D.L...|  CHECK-NEXT:    0010: 82001200 BC010000 28000000 10000000  |........(.......| diff --git a/llvm/test/tools/llvm-cvtres/parse.test b/llvm/test/tools/llvm-cvtres/parse.test index 23911ada82e..58c47143e69 100644 --- a/llvm/test/tools/llvm-cvtres/parse.test +++ b/llvm/test/tools/llvm-cvtres/parse.test @@ -2,7 +2,7 @@  // rc.exe:  // > rc /fo test_resource.res /nologo test_resource.rc -RUN: llvm-cvtres /verbose /out:%t %p/Inputs/test_resource.res | FileCheck %s +RUN: llvm-cvtres /verbose %p/Inputs/test_resource.res | FileCheck %s  CHECK:      Number of resources: 8  CHECK-NEXT: Resource Tree [ diff --git a/llvm/test/tools/llvm-readobj/resources.test b/llvm/test/tools/llvm-readobj/resources.test index 855ce5393b8..589a9c968aa 100644 --- a/llvm/test/tools/llvm-readobj/resources.test +++ b/llvm/test/tools/llvm-readobj/resources.test @@ -9,103 +9,135 @@ RUN:   | FileCheck %s -check-prefix ZERO  RUN: llvm-readobj -coff-resources %p/Inputs/resources/test_resource.obj.coff \  RUN:   | FileCheck %s -check-prefix TEST_RES -ZERO:      Resources [ -ZERO-NEXT:   String Name Entries: 0 -ZERO-NEXT:   ID Entries: 1 -ZERO-NEXT:   Type: kRT_STRING (ID 6) [ -ZERO-NEXT:     String Name Entries: 0 -ZERO-NEXT:     ID Entries: 1 -ZERO-NEXT:     Name: (ID 1) [ -ZERO-NEXT:       String Name Entries: 0 -ZERO-NEXT:       ID Entries: 1 -ZERO-NEXT:       Language: (ID 1033) [ -ZERO-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -ZERO-NEXT:         Major Version: 0 -ZERO-NEXT:         Minor Version: 0 -ZERO-NEXT:       ] -ZERO-NEXT:     ] -ZERO-NEXT:   ] +ZERO:     Resources [ +ZERO-NEXT:  Total Number of Resources: 1 +ZERO-NEXT:  Base Table Address: 0x188 +ZERO-DAG:   Number of String Entries: 0 +ZERO-NEXT:  Number of ID Entries: 1 +ZERO-NEXT:  Type: kRT_STRING (ID 6) [ +ZERO-NEXT:    Table Offset: 0x18 +ZERO-NEXT:    Number of String Entries: 0 +ZERO-NEXT:    Number of ID Entries: 1 +ZERO-NEXT:    Name: (ID 1) [ +ZERO-NEXT:      Table Offset: 0x30 +ZERO-NEXT:      Number of String Entries: 0 +ZERO-NEXT:      Number of ID Entries: 1 +ZERO-NEXT:      Language: (ID 1033) [ +ZERO-NEXT:        Entry Offset: 0x48 +ZERO-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +ZERO-NEXT:        Major Version: 0 +ZERO-NEXT:        Minor Version: 0 +ZERO-NEXT:        Characteristics: 0 +ZERO-NEXT:      ] +ZERO-NEXT:    ] +ZERO-NEXT:  ] - -TEST_RES:	     Resources [ -TEST_RES-NEXT:   String Name Entries: 0 -TEST_RES-NEXT:   ID Entries: 4 -TEST_RES-NEXT:   Type: kRT_BITMAP (ID 2) [ -TEST_RES-NEXT:     String Name Entries: 2 -TEST_RES-NEXT:     ID Entries: 0 -TEST_RES-NEXT:     Name: CURSOR [ -TEST_RES-NEXT:       String Name Entries: 0 -TEST_RES-NEXT:       ID Entries: 1 -TEST_RES-NEXT:       Language: (ID 1033) [ -TEST_RES-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT:         Major Version: 0 -TEST_RES-NEXT:         Minor Version: 0 -TEST_RES-NEXT:       ] -TEST_RES-NEXT:     ] -TEST_RES-NEXT:     Name: OKAY [ -TEST_RES-NEXT:       String Name Entries: 0 -TEST_RES-NEXT:       ID Entries: 1 -TEST_RES-NEXT:       Language: (ID 1033) [ -TEST_RES-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT:         Major Version: 0 -TEST_RES-NEXT:         Minor Version: 0 -TEST_RES-NEXT:       ] -TEST_RES-NEXT:     ] -TEST_RES-NEXT:   ] -TEST_RES-NEXT:   Type: kRT_MENU (ID 4) [ -TEST_RES-NEXT:     String Name Entries: 1 -TEST_RES-NEXT:     ID Entries: 1 -TEST_RES-NEXT:     Name: "EAT" [ -TEST_RES-NEXT:       String Name Entries: 0 -TEST_RES-NEXT:       ID Entries: 1 -TEST_RES-NEXT:       Language: (ID 3081) [ -TEST_RES-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT:         Major Version: 0 -TEST_RES-NEXT:         Minor Version: 0 -TEST_RES-NEXT:       ] -TEST_RES-NEXT:     ] -TEST_RES-NEXT:     Name: (ID 14432) [ -TEST_RES-NEXT:       String Name Entries: 0 -TEST_RES-NEXT:       ID Entries: 1 -TEST_RES-NEXT:       Language: (ID 2052) [ -TEST_RES-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT:         Major Version: 0 -TEST_RES-NEXT:         Minor Version: 0 -TEST_RES-NEXT:       ] -TEST_RES-NEXT:     ] -TEST_RES-NEXT:   ] -TEST_RES-NEXT:   Type: kRT_DIALOG (ID 5) [ -TEST_RES-NEXT:     String Name Entries: 1 -TEST_RES-NEXT:     ID Entries: 0 -TEST_RES-NEXT:     Name: TESTDIALOG [ -TEST_RES-NEXT:       String Name Entries: 0 -TEST_RES-NEXT:       ID Entries: 1 -TEST_RES-NEXT:       Language: (ID 1033) [ -TEST_RES-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT:         Major Version: 0 -TEST_RES-NEXT:         Minor Version: 0 -TEST_RES-NEXT:       ] -TEST_RES-NEXT:     ] -TEST_RES-NEXT:   ] -TEST_RES-NEXT:   Type: kRT_ACCELERATOR (ID 9) [ -TEST_RES-NEXT:     String Name Entries: 1 -TEST_RES-NEXT:     ID Entries: 1 -TEST_RES-NEXT:     Name: MYACCELERATORS [ -TEST_RES-NEXT:       String Name Entries: 0 -TEST_RES-NEXT:       ID Entries: 1 -TEST_RES-NEXT:       Language: (ID 1033) [ -TEST_RES-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT:         Major Version: 0 -TEST_RES-NEXT:         Minor Version: 0 -TEST_RES-NEXT:       ] -TEST_RES-NEXT:     ] -TEST_RES-NEXT:     Name: (ID 12) [ -TEST_RES-NEXT:       String Name Entries: 0 -TEST_RES-NEXT:       ID Entries: 1 -TEST_RES-NEXT:       Language: (ID 1033) [ -TEST_RES-NEXT:         Time/Date Stamp: 1970-01-01 00:00:00 (0x0) -TEST_RES-NEXT:         Major Version: 0 -TEST_RES-NEXT:         Minor Version: 0 -TEST_RES-NEXT:       ] -TEST_RES-NEXT:     ] -TEST_RES-NEXT:   ] +TEST_RES:     Resources [ +TEST_RES-NEXT:  Total Number of Resources: 7 +TEST_RES-NEXT:  Base Table Address: 0x1C0   +TEST_RES-DAG:   Number of String Entries: 0 +TEST_RES-NEXT:  Number of ID Entries: 4 +TEST_RES-NEXT:  Type: kRT_BITMAP (ID 2) [ +TEST_RES-NEXT:    Table Offset: 0x30 +TEST_RES-NEXT:    Number of String Entries: 2 +TEST_RES-NEXT:    Number of ID Entries: 0 +TEST_RES-NEXT:    Name: CURSOR [ +TEST_RES-NEXT:      Table Offset: 0xA8 +TEST_RES-NEXT:      Number of String Entries: 0 +TEST_RES-NEXT:      Number of ID Entries: 1 +TEST_RES-NEXT:      Language: (ID 1033) [ +TEST_RES-NEXT:        Entry Offset: 0x150 +TEST_RES-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +TEST_RES-NEXT:        Major Version: 0 +TEST_RES-NEXT:        Minor Version: 0 +TEST_RES-NEXT:        Characteristics: 0 +TEST_RES-NEXT:      ] +TEST_RES-NEXT:    ] +TEST_RES-NEXT:    Name: OKAY [ +TEST_RES-NEXT:      Table Offset: 0xC0 +TEST_RES-NEXT:      Number of String Entries: 0 +TEST_RES-NEXT:      Number of ID Entries: 1 +TEST_RES-NEXT:      Language: (ID 1033) [ +TEST_RES-NEXT:        Entry Offset: 0x160 +TEST_RES-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +TEST_RES-NEXT:        Major Version: 0 +TEST_RES-NEXT:        Minor Version: 0 +TEST_RES-NEXT:        Characteristics: 0 +TEST_RES-NEXT:      ] +TEST_RES-NEXT:    ] +TEST_RES-NEXT:  ] +TEST_RES-NEXT:  Type: kRT_MENU (ID 4) [ +TEST_RES-NEXT:    Table Offset: 0x50 +TEST_RES-NEXT:    Number of String Entries: 1 +TEST_RES-NEXT:    Number of ID Entries: 1 +TEST_RES-NEXT:    Name: "EAT" [ +TEST_RES-NEXT:      Table Offset: 0xD8 +TEST_RES-NEXT:      Number of String Entries: 0 +TEST_RES-NEXT:      Number of ID Entries: 1 +TEST_RES-NEXT:      Language: (ID 3081) [ +TEST_RES-NEXT:        Entry Offset: 0x170 +TEST_RES-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +TEST_RES-NEXT:        Major Version: 0 +TEST_RES-NEXT:        Minor Version: 0 +TEST_RES-NEXT:        Characteristics: 0 +TEST_RES-NEXT:      ] +TEST_RES-NEXT:    ] +TEST_RES-NEXT:    Name: (ID 14432) [ +TEST_RES-NEXT:      Table Offset: 0xF0 +TEST_RES-NEXT:      Number of String Entries: 0 +TEST_RES-NEXT:      Number of ID Entries: 1 +TEST_RES-NEXT:      Language: (ID 2052) [ +TEST_RES-NEXT:        Entry Offset: 0x180 +TEST_RES-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +TEST_RES-NEXT:        Major Version: 0 +TEST_RES-NEXT:        Minor Version: 0 +TEST_RES-NEXT:        Characteristics: 0 +TEST_RES-NEXT:      ] +TEST_RES-NEXT:    ] +TEST_RES-NEXT:  ] +TEST_RES-NEXT:  Type: kRT_DIALOG (ID 5) [ +TEST_RES-NEXT:    Table Offset: 0x70 +TEST_RES-NEXT:    Number of String Entries: 1 +TEST_RES-NEXT:    Number of ID Entries: 0 +TEST_RES-NEXT:    Name: TESTDIALOG [ +TEST_RES-NEXT:      Table Offset: 0x108 +TEST_RES-NEXT:      Number of String Entries: 0 +TEST_RES-NEXT:      Number of ID Entries: 1 +TEST_RES-NEXT:      Language: (ID 1033) [ +TEST_RES-NEXT:        Entry Offset: 0x190 +TEST_RES-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +TEST_RES-NEXT:        Major Version: 0 +TEST_RES-NEXT:        Minor Version: 0 +TEST_RES-NEXT:        Characteristics: 0 +TEST_RES-NEXT:      ] +TEST_RES-NEXT:    ] +TEST_RES-NEXT:  ] +TEST_RES-NEXT:  Type: kRT_ACCELERATOR (ID 9) [ +TEST_RES-NEXT:    Table Offset: 0x88 +TEST_RES-NEXT:    Number of String Entries: 1 +TEST_RES-NEXT:    Number of ID Entries: 1 +TEST_RES-NEXT:    Name: MYACCELERATORS [ +TEST_RES-NEXT:      Table Offset: 0x120 +TEST_RES-NEXT:      Number of String Entries: 0 +TEST_RES-NEXT:      Number of ID Entries: 1 +TEST_RES-NEXT:      Language: (ID 1033) [ +TEST_RES-NEXT:        Entry Offset: 0x1A0 +TEST_RES-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +TEST_RES-NEXT:        Major Version: 0 +TEST_RES-NEXT:        Minor Version: 0 +TEST_RES-NEXT:        Characteristics: 0 +TEST_RES-NEXT:      ] +TEST_RES-NEXT:    ] +TEST_RES-NEXT:    Name: (ID 12) [ +TEST_RES-NEXT:      Table Offset: 0x138 +TEST_RES-NEXT:      Number of String Entries: 0 +TEST_RES-NEXT:      Number of ID Entries: 1 +TEST_RES-NEXT:      Language: (ID 1033) [ +TEST_RES-NEXT:        Entry Offset: 0x1B0 +TEST_RES-NEXT:        Time/Date Stamp: 1970-01-01 00:00:00 (0x0) +TEST_RES-NEXT:        Major Version: 0 +TEST_RES-NEXT:        Minor Version: 0 +TEST_RES-NEXT:        Characteristics: 0 +TEST_RES-NEXT:      ] +TEST_RES-NEXT:    ] +TEST_RES-NEXT:  ] diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 6223c09a4de..216c9adad9a 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -124,6 +124,10 @@ private:                             uint32_t RelocOffset, uint32_t Offset,                             StringRef *RelocSym = nullptr); +  uint32_t countTotalTableEntries(ResourceSectionRef RSF, +                                  const coff_resource_dir_table &Table, +                                  StringRef Level); +    void printResourceDirectoryTable(ResourceSectionRef RSF,                                     const coff_resource_dir_table &Table,                                     StringRef Level); @@ -1526,6 +1530,11 @@ void COFFDumper::printCOFFResources() {      if ((Name == ".rsrc") || (Name == ".rsrc$01")) {        ResourceSectionRef RSF(Ref);        auto &BaseTable = unwrapOrError(RSF.getBaseTable()); +      W.printNumber("Total Number of Resources", +                    countTotalTableEntries(RSF, BaseTable, "Type")); +      W.printHex("Base Table Address", +                 Obj->getCOFFSection(S)->PointerToRawData); +      W.startLine() << "\n";        printResourceDirectoryTable(RSF, BaseTable, "Type");      }      if (opts::SectionData) @@ -1533,15 +1542,35 @@ void COFFDumper::printCOFFResources() {    }  } +uint32_t +COFFDumper::countTotalTableEntries(ResourceSectionRef RSF, +                                   const coff_resource_dir_table &Table, +                                   StringRef Level) { +  uint32_t TotalEntries = 0; +  for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries; +       i++) { +    auto Entry = unwrapOrError(getResourceDirectoryTableEntry(Table, i)); +    if (Entry.Offset.isSubDir()) { +      StringRef NextLevel; +      if (Level == "Name") +        NextLevel = "Language"; +      else +        NextLevel = "Name"; +      auto &NextTable = unwrapOrError(RSF.getEntrySubDir(Entry)); +      TotalEntries += countTotalTableEntries(RSF, NextTable, NextLevel); +    } else { +      TotalEntries += 1; +    } +  } +  return TotalEntries; +} +  void COFFDumper::printResourceDirectoryTable(      ResourceSectionRef RSF, const coff_resource_dir_table &Table,      StringRef Level) { -  W.printNumber("String Name Entries", Table.NumberOfNameEntries); -  W.printNumber("ID Entries", Table.NumberOfIDEntries); -  char FormattedTime[20] = {}; -  time_t TDS = time_t(Table.TimeDateStamp); -  strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS)); +  W.printNumber("Number of String Entries", Table.NumberOfNameEntries); +  W.printNumber("Number of ID Entries", Table.NumberOfIDEntries);    // Iterate through level in resource directory tree.    for (int i = 0; i < Table.NumberOfNameEntries + Table.NumberOfIDEntries; @@ -1578,6 +1607,7 @@ void COFFDumper::printResourceDirectoryTable(      Name = StringRef(IDStr);      ListScope ResourceType(W, Level.str() + Name.str());      if (Entry.Offset.isSubDir()) { +      W.printHex("Table Offset", Entry.Offset.value());        StringRef NextLevel;        if (Level == "Name")          NextLevel = "Language"; @@ -1586,9 +1616,14 @@ void COFFDumper::printResourceDirectoryTable(        auto &NextTable = unwrapOrError(RSF.getEntrySubDir(Entry));        printResourceDirectoryTable(RSF, NextTable, NextLevel);      } else { +      W.printHex("Entry Offset", Entry.Offset.value()); +      char FormattedTime[20] = {}; +      time_t TDS = time_t(Table.TimeDateStamp); +      strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));        W.printHex("Time/Date Stamp", FormattedTime, Table.TimeDateStamp);        W.printNumber("Major Version", Table.MajorVersion);        W.printNumber("Minor Version", Table.MinorVersion); +      W.printNumber("Characteristics", Table.Characteristics);      }    }  }  | 

