diff --git a/src/binaryToObject/elf.cpp b/src/binaryToObject/elf.cpp index 51c7d7c587..5235c8f0a7 100644 --- a/src/binaryToObject/elf.cpp +++ b/src/binaryToObject/elf.cpp @@ -166,7 +166,7 @@ public: ElfObjectWriter(PlatformInfo::Architecture arch): arch(arch) {} - void writeObject(const uint8_t* data, unsigned size, FILE* out, + void writeObject(const uint8_t* data, unsigned size, OutputStream* out, const char* startName, const char* endName, const char* sectionName, unsigned sectionFlags, unsigned alignment, int machine, int encoding) @@ -311,31 +311,30 @@ public: endSymbol.st_other = V1(STV_DEFAULT); endSymbol.st_shndx = V2(bodySectionNumber); - fwrite(&fileHeader, 1, sizeof(fileHeader), out); - fwrite(&nullSection, 1, sizeof(nullSection), out); - fwrite(&bodySection, 1, sizeof(bodySection), out); - fwrite(§ionStringTableSection, 1, sizeof(sectionStringTableSection), - out); - fwrite(&stringTableSection, 1, sizeof(stringTableSection), out); - fwrite(&symbolTableSection, 1, sizeof(symbolTableSection), out); + out->writeChunk(&fileHeader, sizeof(fileHeader)); + out->writeChunk(&nullSection, sizeof(nullSection)); + out->writeChunk(&bodySection, sizeof(bodySection)); + out->writeChunk(§ionStringTableSection, sizeof(sectionStringTableSection)); + out->writeChunk(&stringTableSection, sizeof(stringTableSection)); + out->writeChunk(&symbolTableSection, sizeof(symbolTableSection)); - fwrite(data, 1, size, out); + out->writeChunk(data, size); - fputc(0, out); - fwrite(sectionStringTableName, 1, sectionStringTableNameLength, out); - fwrite(stringTableName, 1, stringTableNameLength, out); - fwrite(symbolTableName, 1, symbolTableNameLength, out); - fwrite(sectionName, 1, sectionNameLength, out); + out->write(0); + out->writeChunk(sectionStringTableName, sectionStringTableNameLength); + out->writeChunk(stringTableName, stringTableNameLength); + out->writeChunk(symbolTableName, symbolTableNameLength); + out->writeChunk(sectionName, sectionNameLength); - fputc(0, out); - fwrite(startName, 1, startNameLength, out); - fwrite(endName, 1, endNameLength, out); + out->write(0); + out->writeChunk(startName, startNameLength); + out->writeChunk(endName, endNameLength); - fwrite(&startSymbol, 1, sizeof(startSymbol), out); - fwrite(&endSymbol, 1, sizeof(endSymbol), out); + out->writeChunk(&startSymbol, sizeof(startSymbol)); + out->writeChunk(&endSymbol, sizeof(endSymbol)); } - virtual bool write(uint8_t* data, size_t size, FILE* out, + virtual bool write(uint8_t* data, size_t size, OutputStream* out, const char* startName, const char* endName, unsigned alignment, unsigned accessFlags) { diff --git a/src/binaryToObject/mach-o.cpp b/src/binaryToObject/mach-o.cpp index 6aab90a0b1..e040569212 100644 --- a/src/binaryToObject/mach-o.cpp +++ b/src/binaryToObject/mach-o.cpp @@ -148,7 +148,7 @@ public: MachOObjectWriter(PlatformInfo::Architecture arch): arch(arch) {} - void writeObject(const uint8_t* data, unsigned size, FILE* out, + void writeObject(const uint8_t* data, unsigned size, OutputStream* out, const char* startName, const char* endName, const char* segmentName, const char* sectionName, unsigned alignment, cpu_type_t cpuType, cpu_subtype_t cpuSubType) @@ -242,22 +242,23 @@ public: } }; - fwrite(&header, 1, sizeof(header), out); - fwrite(&segment, 1, sizeof(segment), out); - fwrite(§, 1, sizeof(sect), out); - fwrite(&symbolTable, 1, sizeof(symbolTable), out); + out->writeChunk(&header, sizeof(header)); + out->writeChunk(&segment, sizeof(segment)); + out->writeChunk(§, sizeof(sect)); + out->writeChunk(&symbolTable, sizeof(symbolTable)); - fwrite(data, 1, size, out); - for (unsigned i = 0; i < pad(size) - size; ++i) fputc(0, out); + out->writeChunk(data, size); + out->writeRepeat(0, pad(size) - size); - fwrite(&symbolList, 1, sizeof(symbolList), out); + out->writeChunk(&symbolList, sizeof(symbolList)); - fputc(0, out); - fwrite(startName, 1, startNameLength, out); - fwrite(endName, 1, endNameLength, out); + out->write(0); + + out->writeChunk(startName, startNameLength); + out->writeChunk(endName, endNameLength); } - virtual bool write(uint8_t* data, size_t size, FILE* out, + virtual bool write(uint8_t* data, size_t size, OutputStream* out, const char* startName, const char* endName, unsigned alignment, unsigned accessFlags) { diff --git a/src/binaryToObject/main.cpp b/src/binaryToObject/main.cpp index 6dcdf9734d..197bcbf0f6 100644 --- a/src/binaryToObject/main.cpp +++ b/src/binaryToObject/main.cpp @@ -44,7 +44,7 @@ namespace { using namespace avian::tools; bool -writeObject(uint8_t* data, unsigned size, FILE* out, const char* startName, +writeObject(uint8_t* data, unsigned size, OutputStream* out, const char* startName, const char* endName, const char* os, const char* architecture, unsigned alignment, bool writable, bool executable) @@ -142,13 +142,11 @@ main(int argc, const char** argv) bool success = false; if (data) { - FILE* out = fopen(argv[2], "wb"); - if (out) { + FileOutputStream out(argv[2]); + if (out.isValid()) { success = writeObject - (data, size, out, argv[3], argv[4], argv[5], argv[6], alignment, + (data, size, &out, argv[3], argv[4], argv[5], argv[6], alignment, writable, executable); - - fclose(out); } else { fprintf(stderr, "unable to open %s\n", argv[2]); } diff --git a/src/binaryToObject/pe.cpp b/src/binaryToObject/pe.cpp index 67fe684153..9fcdbe8949 100644 --- a/src/binaryToObject/pe.cpp +++ b/src/binaryToObject/pe.cpp @@ -79,8 +79,10 @@ pad(unsigned n) return (n + (4 - 1)) & ~(4 - 1); } +using namespace avian::tools; + void -writeObject(const uint8_t* data, unsigned size, FILE* out, +writeObject(const uint8_t* data, unsigned size, OutputStream* out, const char* startName, const char* endName, const char* sectionName, int machine, int machineMask, int sectionMask) @@ -147,24 +149,22 @@ writeObject(const uint8_t* data, unsigned size, FILE* out, }; endSymbol.N.Name.Long = endNameOffset; - fwrite(&fileHeader, 1, sizeof(fileHeader), out); - fwrite(§ionHeader, 1, sizeof(sectionHeader), out); + out->writeChunk(&fileHeader, sizeof(fileHeader)); + out->writeChunk(§ionHeader, sizeof(sectionHeader)); - fwrite(data, 1, size, out); - for (unsigned i = 0; i < pad(size) - size; ++i) fputc(0, out); + out->writeChunk(data, size); + out->writeRepeat(0, pad(size) - size); - fwrite(&startSymbol, 1, sizeof(startSymbol), out); - fwrite(&endSymbol, 1, sizeof(endSymbol), out); + out->writeChunk(&startSymbol, sizeof(startSymbol)); + out->writeChunk(&endSymbol, sizeof(endSymbol)); uint32_t symbolTableSize = endNameOffset + endNameLength; - fwrite(&symbolTableSize, 1, 4, out); + out->writeChunk(&symbolTableSize, 4); - fwrite(startName, 1, startNameLength, out); - fwrite(endName, 1, endNameLength, out); + out->writeChunk(startName, startNameLength); + out->writeChunk(endName, endNameLength); } -using namespace avian::tools; - template class WindowsPlatform : public Platform { public: @@ -172,7 +172,7 @@ public: class PEObjectWriter : public ObjectWriter { public: - virtual bool write(uint8_t* data, size_t size, FILE* out, + virtual bool write(uint8_t* data, size_t size, OutputStream* out, const char* startName, const char* endName, unsigned alignment, unsigned accessFlags) { diff --git a/src/binaryToObject/tools.cpp b/src/binaryToObject/tools.cpp index 531fd2f246..0768e8a24b 100644 --- a/src/binaryToObject/tools.cpp +++ b/src/binaryToObject/tools.cpp @@ -19,6 +19,37 @@ namespace avian { namespace tools { +void OutputStream::write(uint8_t byte) { + writeChunk(&byte, 1); +} + +void OutputStream::writeRepeat(uint8_t byte, size_t size) { + for(size_t i = 0; i < size; i++) { + write(byte); + } +} + +FileOutputStream::FileOutputStream(const char* name): + file(fopen(name, "wb")) {} + +FileOutputStream::~FileOutputStream() { + if(file) { + fclose(file); + } +} + +bool FileOutputStream::isValid() { + return file; +} + +void FileOutputStream::writeChunk(const void* data, size_t size) { + fwrite(data, size, 1, file); +} + +void FileOutputStream::write(uint8_t byte) { + fputc(byte, file); +} + Platform* Platform::first = 0; diff --git a/src/binaryToObject/tools.h b/src/binaryToObject/tools.h index 1d1b2d2a34..359068fe4d 100644 --- a/src/binaryToObject/tools.h +++ b/src/binaryToObject/tools.h @@ -15,6 +15,26 @@ namespace avian { namespace tools { +class OutputStream { +public: + virtual void writeChunk(const void* data, size_t size) = 0; + virtual void write(uint8_t byte); + virtual void writeRepeat(uint8_t byte, size_t size); +}; + +class FileOutputStream : public OutputStream { +private: + FILE* file; +public: + FileOutputStream(const char* name); + ~FileOutputStream(); + + bool isValid(); + + virtual void writeChunk(const void* data, size_t size); + virtual void write(uint8_t byte); +}; + class ObjectWriter { public: @@ -24,7 +44,7 @@ public: Executable = 1 << 2 }; - virtual bool write(uint8_t* data, size_t size, FILE* out, + virtual bool write(uint8_t* data, size_t size, OutputStream* out, const char* startName, const char* endName, unsigned alignment, unsigned accessFlags) = 0;