int main(int Argc, const char **Argv) { InitLLVM X(Argc, Argv); CvtResOptTable T; unsigned MAI, MAC; ArrayRef<const char *> ArgsArr = makeArrayRef(Argv + 1, Argc - 1); opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MAI, MAC); if (InputArgs.hasArg(OPT_HELP)) { T.PrintHelp(outs(), "llvm-cvtres [options] file...", "Resource Converter"); return 0; } bool Verbose = InputArgs.hasArg(OPT_VERBOSE); COFF::MachineTypes MachineType; if (InputArgs.hasArg(OPT_MACHINE)) { std::string MachineString = InputArgs.getLastArgValue(OPT_MACHINE).upper(); MachineType = StringSwitch<COFF::MachineTypes>(MachineString) .Case("ARM", COFF::IMAGE_FILE_MACHINE_ARMNT) .Case("ARM64", COFF::IMAGE_FILE_MACHINE_ARM64) .Case("X64", COFF::IMAGE_FILE_MACHINE_AMD64) .Case("X86", COFF::IMAGE_FILE_MACHINE_I386) .Default(COFF::IMAGE_FILE_MACHINE_UNKNOWN); if (MachineType == COFF::IMAGE_FILE_MACHINE_UNKNOWN) reportError("Unsupported machine architecture"); } else { if (Verbose) outs() << "Machine architecture not specified; assumed X64.\n"; MachineType = COFF::IMAGE_FILE_MACHINE_AMD64; } std::vector<std::string> InputFiles = InputArgs.getAllArgValues(OPT_INPUT); if (InputFiles.size() == 0) { reportError("No input file specified.\n"); } SmallString<128> OutputFile; if (InputArgs.hasArg(OPT_OUT)) { OutputFile = InputArgs.getLastArgValue(OPT_OUT); } else { OutputFile = sys::path::filename(StringRef(InputFiles[0])); sys::path::replace_extension(OutputFile, ".obj"); } if (Verbose) { outs() << "Machine: "; switch (MachineType) { case COFF::IMAGE_FILE_MACHINE_ARM64: outs() << "ARM64\n"; break; case COFF::IMAGE_FILE_MACHINE_ARMNT: outs() << "ARM\n"; break; case COFF::IMAGE_FILE_MACHINE_I386: outs() << "X86\n"; break; default: outs() << "X64\n"; } } WindowsResourceParser Parser; for (const auto &File : InputFiles) { Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File); if (!BinaryOrErr) reportError(File, errorToErrorCode(BinaryOrErr.takeError())); Binary &Binary = *BinaryOrErr.get().getBinary(); WindowsResource *RF = dyn_cast<WindowsResource>(&Binary); if (!RF) reportError(File + ": unrecognized file format.\n"); if (Verbose) { int EntryNumber = 0; ResourceEntryRef Entry = error(RF->getHeadEntry()); bool End = false; while (!End) { error(Entry.moveNext(End)); EntryNumber++; } outs() << "Number of resources: " << EntryNumber << "\n"; } error(Parser.parse(RF)); } if (Verbose) { Parser.printTree(outs()); } std::unique_ptr<MemoryBuffer> OutputBuffer = error(llvm::object::writeWindowsResourceCOFF(MachineType, Parser)); auto FileOrErr = FileOutputBuffer::create(OutputFile, OutputBuffer->getBufferSize()); if (!FileOrErr) reportError(OutputFile, errorToErrorCode(FileOrErr.takeError())); std::unique_ptr<FileOutputBuffer> FileBuffer = std::move(*FileOrErr); std::copy(OutputBuffer->getBufferStart(), OutputBuffer->getBufferEnd(), FileBuffer->getBufferStart()); error(FileBuffer->commit()); if (Verbose) { Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(OutputFile); if (!BinaryOrErr) reportError(OutputFile, errorToErrorCode(BinaryOrErr.takeError())); Binary &Binary = *BinaryOrErr.get().getBinary(); ScopedPrinter W(errs()); W.printBinaryBlock("Output File Raw Data", Binary.getData()); } return 0; }
void Dumper::printEntry(const ResourceEntryRef &Ref) { if (Ref.checkTypeString()) { auto NarrowStr = stripUTF16(Ref.getTypeString()); SW.printString("Resource type (string)", NarrowStr); } else SW.printNumber("Resource type (int)", Ref.getTypeID()); if (Ref.checkNameString()) { auto NarrowStr = stripUTF16(Ref.getNameString()); SW.printString("Resource name (string)", NarrowStr); } else SW.printNumber("Resource name (int)", Ref.getNameID()); SW.printNumber("Data version", Ref.getDataVersion()); SW.printHex("Memory flags", Ref.getMemoryFlags()); SW.printNumber("Language ID", Ref.getLanguage()); SW.printNumber("Version (major)", Ref.getMajorVersion()); SW.printNumber("Version (minor)", Ref.getMinorVersion()); SW.printNumber("Characteristics", Ref.getCharacteristics()); SW.printNumber("Data size", (uint64_t)Ref.getData().size()); SW.printBinary("Data:", Ref.getData()); SW.startLine() << "\n"; }
int main(int argc_, const char *argv_[]) { sys::PrintStackTraceOnErrorSignal(argv_[0]); PrettyStackTraceProgram X(argc_, argv_); ExitOnErr.setBanner("llvm-cvtres: "); SmallVector<const char *, 256> argv; SpecificBumpPtrAllocator<char> ArgAllocator; ExitOnErr(errorCodeToError(sys::Process::GetArgumentVector( argv, makeArrayRef(argv_, argc_), ArgAllocator))); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. CvtResOptTable T; unsigned MAI, MAC; ArrayRef<const char *> ArgsArr = makeArrayRef(argv_ + 1, argc_); opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MAI, MAC); if (InputArgs.hasArg(OPT_HELP)) { T.PrintHelp(outs(), "cvtres", "Resource Converter", false); return 0; } bool Verbose = InputArgs.hasArg(OPT_VERBOSE); Machine MachineType; if (InputArgs.hasArg(OPT_MACHINE)) { std::string MachineString = InputArgs.getLastArgValue(OPT_MACHINE).upper(); MachineType = StringSwitch<Machine>(MachineString) .Case("ARM", Machine::ARM) .Case("X64", Machine::X64) .Case("X86", Machine::X86) .Default(Machine::UNKNOWN); if (MachineType == Machine::UNKNOWN) reportError("Unsupported machine architecture"); } else { if (Verbose) outs() << "Machine architecture not specified; assumed X64.\n"; MachineType = Machine::X64; } std::vector<std::string> InputFiles = InputArgs.getAllArgValues(OPT_INPUT); if (InputFiles.size() == 0) { reportError("No input file specified.\n"); } SmallString<128> OutputFile; if (InputArgs.hasArg(OPT_OUT)) { OutputFile = InputArgs.getLastArgValue(OPT_OUT); } else { OutputFile = llvm::sys::path::filename(StringRef(InputFiles[0])); llvm::sys::path::replace_extension(OutputFile, ".obj"); } if (Verbose) { outs() << "Machine: "; switch (MachineType) { case Machine::ARM: outs() << "ARM\n"; break; case Machine::X86: outs() << "X86\n"; break; default: outs() << "X64\n"; } } WindowsResourceParser Parser; for (const auto &File : InputFiles) { Expected<object::OwningBinary<object::Binary>> BinaryOrErr = object::createBinary(File); if (!BinaryOrErr) reportError(File, errorToErrorCode(BinaryOrErr.takeError())); Binary &Binary = *BinaryOrErr.get().getBinary(); WindowsResource *RF = dyn_cast<WindowsResource>(&Binary); if (!RF) reportError(File + ": unrecognized file format.\n"); if (Verbose) { int EntryNumber = 0; Expected<ResourceEntryRef> EntryOrErr = RF->getHeadEntry(); if (!EntryOrErr) error(EntryOrErr.takeError()); ResourceEntryRef Entry = EntryOrErr.get(); bool End = false; while (!End) { error(Entry.moveNext(End)); EntryNumber++; } outs() << "Number of resources: " << EntryNumber << "\n"; } error(Parser.parse(RF)); } if (Verbose) { Parser.printTree(outs()); Parser.printTree(errs()); } error( llvm::object::writeWindowsResourceCOFF(OutputFile, MachineType, Parser)); if (Verbose) { Expected<object::OwningBinary<object::Binary>> BinaryOrErr = object::createBinary(OutputFile); if (!BinaryOrErr) reportError(OutputFile, errorToErrorCode(BinaryOrErr.takeError())); Binary &Binary = *BinaryOrErr.get().getBinary(); ScopedPrinter W(errs()); W.printBinaryBlock("Output File Raw Data", Binary.getData()); } return 0; }