diff options
Diffstat (limited to 'contrib/llvm/lib/Object/WindowsResource.cpp')
| -rw-r--r-- | contrib/llvm/lib/Object/WindowsResource.cpp | 65 | 
1 files changed, 35 insertions, 30 deletions
diff --git a/contrib/llvm/lib/Object/WindowsResource.cpp b/contrib/llvm/lib/Object/WindowsResource.cpp index 246eee5ddb31..271224ec6312 100644 --- a/contrib/llvm/lib/Object/WindowsResource.cpp +++ b/contrib/llvm/lib/Object/WindowsResource.cpp @@ -14,10 +14,10 @@  #include "llvm/Object/WindowsResource.h"  #include "llvm/Object/COFF.h"  #include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/FormatVariadic.h"  #include "llvm/Support/MathExtras.h"  #include <ctime>  #include <queue> -#include <sstream>  #include <system_error>  using namespace llvm; @@ -57,19 +57,22 @@ WindowsResource::createWindowsResource(MemoryBufferRef Source) {  }  Expected<ResourceEntryRef> WindowsResource::getHeadEntry() { -  Error Err = Error::success(); -  auto Ref = ResourceEntryRef(BinaryStreamRef(BBS), this, Err); -  if (Err) -    return std::move(Err); -  return Ref; +  if (BBS.getLength() < sizeof(WinResHeaderPrefix) + sizeof(WinResHeaderSuffix)) +    return make_error<EmptyResError>(".res contains no entries", +                                     object_error::unexpected_eof); +  return ResourceEntryRef::create(BinaryStreamRef(BBS), this);  }  ResourceEntryRef::ResourceEntryRef(BinaryStreamRef Ref, -                                   const WindowsResource *Owner, Error &Err) -    : Reader(Ref), OwningRes(Owner) { -  if (loadNext()) -    Err = make_error<GenericBinaryError>("Could not read first entry.\n", -                                         object_error::unexpected_eof); +                                   const WindowsResource *Owner) +    : Reader(Ref) {} + +Expected<ResourceEntryRef> +ResourceEntryRef::create(BinaryStreamRef BSR, const WindowsResource *Owner) { +  auto Ref = ResourceEntryRef(BSR, Owner); +  if (auto E = Ref.loadNext()) +    return std::move(E); +  return Ref;  }  Error ResourceEntryRef::moveNext(bool &End) { @@ -127,8 +130,20 @@ WindowsResourceParser::WindowsResourceParser() : Root(false) {}  Error WindowsResourceParser::parse(WindowsResource *WR) {    auto EntryOrErr = WR->getHeadEntry(); -  if (!EntryOrErr) -    return EntryOrErr.takeError(); +  if (!EntryOrErr) { +    auto E = EntryOrErr.takeError(); +    if (E.isA<EmptyResError>()) { +      // Check if the .res file contains no entries.  In this case we don't have +      // to throw an error but can rather just return without parsing anything. +      // This applies for files which have a valid PE header magic and the +      // mandatory empty null resource entry.  Files which do not fit this +      // criteria would have already been filtered out by +      // WindowsResource::createWindowsResource(). +      consumeError(std::move(E)); +      return Error::success(); +    } +    return E; +  }    ResourceEntryRef Entry = EntryOrErr.get();    bool End = false; @@ -426,19 +441,7 @@ std::unique_ptr<MemoryBuffer> WindowsResourceCOFFWriter::write() {  void WindowsResourceCOFFWriter::writeCOFFHeader() {    // Write the COFF header.    auto *Header = reinterpret_cast<coff_file_header *>(BufferStart); -  switch (MachineType) { -  case COFF::IMAGE_FILE_MACHINE_ARMNT: -    Header->Machine = COFF::IMAGE_FILE_MACHINE_ARMNT; -    break; -  case COFF::IMAGE_FILE_MACHINE_AMD64: -    Header->Machine = COFF::IMAGE_FILE_MACHINE_AMD64; -    break; -  case COFF::IMAGE_FILE_MACHINE_I386: -    Header->Machine = COFF::IMAGE_FILE_MACHINE_I386; -    break; -  default: -    Header->Machine = COFF::IMAGE_FILE_MACHINE_UNKNOWN; -  } +  Header->Machine = MachineType;    Header->NumberOfSections = 2;    Header->TimeDateStamp = getTime();    Header->PointerToSymbolTable = SymbolTableOffset; @@ -558,10 +561,9 @@ void WindowsResourceCOFFWriter::writeSymbolTable() {    // Now write a symbol for each relocation.    for (unsigned i = 0; i < Data.size(); i++) { -    char RelocationName[9]; -    sprintf(RelocationName, "$R%06X", DataOffsets[i]); +    auto RelocationName = formatv("$R{0:X-6}", i & 0xffffff).sstr<COFF::NameSize>();      Symbol = reinterpret_cast<coff_symbol16 *>(BufferStart + CurrentOffset); -    strncpy(Symbol->Name.ShortName, RelocationName, (size_t)COFF::NameSize); +    memcpy(Symbol->Name.ShortName, RelocationName.data(), (size_t) COFF::NameSize);      Symbol->Value = DataOffsets[i];      Symbol->SectionNumber = 2;      Symbol->Type = COFF::IMAGE_SYM_DTYPE_NULL; @@ -699,8 +701,11 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {      case COFF::IMAGE_FILE_MACHINE_I386:        Reloc->Type = COFF::IMAGE_REL_I386_DIR32NB;        break; +    case COFF::IMAGE_FILE_MACHINE_ARM64: +      Reloc->Type = COFF::IMAGE_REL_ARM64_ADDR32NB; +      break;      default: -      Reloc->Type = 0; +      llvm_unreachable("unknown machine type");      }      CurrentOffset += sizeof(coff_relocation);    }  | 
