Author: arty
Date: Sun Apr 29 08:05:11 2007
New Revision: 26574
URL:
http://svn.reactos.org/svn/reactos?rev=26574&view=rev
Log:
Start of a simple ELF PE augmenter.
Added:
branches/powerpc/reactos/tools/ppc-build/elfpe/
branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-dlltool.in (with props)
branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-gcc.in
branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-ld.in
branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-windres.in
branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr.cpp
branches/powerpc/reactos/tools/ppc-build/elfpe/fork_execvp.h (with props)
branches/powerpc/reactos/tools/ppc-build/elfpe/fork_unix.cpp (with props)
branches/powerpc/reactos/tools/ppc-build/elfpe/fork_win32.cpp (with props)
branches/powerpc/reactos/tools/ppc-build/elfpe/header.cpp
branches/powerpc/reactos/tools/ppc-build/elfpe/header.h
branches/powerpc/reactos/tools/ppc-build/elfpe/makefile
branches/powerpc/reactos/tools/ppc-build/elfpe/objectfile.cpp
branches/powerpc/reactos/tools/ppc-build/elfpe/objectfile.h
branches/powerpc/reactos/tools/ppc-build/elfpe/pedef.h
branches/powerpc/reactos/tools/ppc-build/elfpe/util.cpp
branches/powerpc/reactos/tools/ppc-build/elfpe/util.h
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-dlltool.in
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-dlltool.in (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-dlltool.in Sun Apr 29 08:05:11
2007
@@ -1,0 +1,7 @@
+#!/bin/sh
+
+DIR=@PREFIX@
+BPREFIX=@BPREFIX@
+TARGET=@TARGET@
+
+${BPREFIX}dlltool -S $DIR/bin/${TARGET}as -L $DIR/bin/${TARGET}ld $*
Propchange: branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-dlltool.in
------------------------------------------------------------------------------
svn:executable = *
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-gcc.in
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-gcc.in (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-gcc.in Sun Apr 29 08:05:11
2007
@@ -1,0 +1,58 @@
+#!/bin/sh
+
+DIR=@PREFIX@
+CPREFIX=@CPREFIX@
+TARGET=@TARGET@
+
+if [ "x$*" = "x-v" ] ; then
+ exec ${CPREFIX}gcc -v
+fi
+
+includes="-isystem $DIR/lib/mingw-crt-headers -isystem
$DIR/lib/gcc-core-headers"
+
+argstr=""
+for arg in $* ; do
+ if [ x"$arg" = x-mingw ] ; then
+ argstr="$argstr -isystem $DIR/lib/windows-headers"
+ else
+ argstr="$argstr $arg"
+ fi
+done
+
+TEMP=`mktemp -d`
+export TEMP
+if [ ! -d $TEMP ] ; then
+ echo "Could not make temp dir $TEMP"
+ exit 1
+fi
+TMP=$TEMP
+
+`dirname $0`/${TARGET}driver-gcc \
+ -nostdinc \
+ -D__cdecl__= \
+ -D__stdcall__= \
+ -D__fastcall__= \
+ -D__declspec\(x\)= \
+ -D__cdecl= \
+ -D__stdcall= \
+ -D__fastcall= \
+ -Dcdecl= \
+ -Dstdcall= \
+ -Dfastcall= \
+ -Ddllimport= \
+ -Ddllexport= \
+ -Du_short=unsigned\ short \
+ -Du_long=unsigned\ long \
+ -Du_int=unsigned\ int \
+ -Du_char=unsigned\ char \
+ -ldscript ${DIR}/lib/ldscript \
+ -gcc-name ${CPREFIX}gcc \
+ -link-stage-name ${DIR}/bin/${TARGET}ld \
+ -mingw-lib-dir $DIR/lib \
+ $includes \
+ $argstr </dev/null
+
+RES=$?
+
+rm -rf $TEMP
+exit $RES
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-ld.in
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-ld.in (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-ld.in Sun Apr 29 08:05:11 2007
@@ -1,0 +1,28 @@
+#!/bin/sh
+
+DIR=@PREFIX@
+BPREFIX=@BPREFIX@
+TARGET=@TARGET@
+
+if [ "x$*" = x-v ] ; then
+ exec ${BPREFIX}ld -v
+fi
+
+TEMP=`mktemp -d`
+export TEMP
+if [ ! -d $TEMP ] ; then
+ echo "Could not make temp dir $TEMP"
+ exit 1
+fi
+TMP=$TEMP
+
+`dirname $0`/${TARGET}driver-ld \
+ -ldscript ${DIR}/lib/ldscript \
+ -mingw-lib-dir ${DIR}/lib \
+ -link-stage-name ${BPREFIX}ld \
+ $*
+
+RES=$?
+
+rm -rf $TEMP
+exit $RES
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-windres.in
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-windres.in (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr-windres.in Sun Apr 29 08:05:11
2007
@@ -1,0 +1,7 @@
+#!/bin/sh
+
+DIR=@PREFIX@
+BPREFIX=@BPREFIX@
+TARGET=@TARGET@
+
+exec ${BPREFIX}windres -F elf32-powerpc $*
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr.cpp (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/compdvr.cpp Sun Apr 29 08:05:11 2007
@@ -1,0 +1,336 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <list>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <algorithm>
+#include "objectfile.h"
+#include "header.h"
+#include "fork_execvp.h"
+
+#define TYPE_PEHEADER (SHT_LOOS + 1)
+
+/* tool for transforming gcc -### output and using it to drive the compiler
+ * elements ourselves. Most importantly, we need to know what file gcc asks
+ * the linker to input and output, and add an intermediate stage with alink.
+ */
+
+typedef enum { empty, found_q, found_bs } break_t;
+
+template <class T>
+T break_arguments( const std::string &line ) {
+ break_t state = empty;
+ T args;
+ std::string arg;
+
+ for( size_t i = 0; i < line.size(); i++ ) {
+ switch( state ) {
+ case empty:
+ if( line[i] == '\"' ) {
+ state = found_q;
+ }
+ break;
+
+ case found_q:
+ if( line[i] == '\\' ) state = found_bs;
+ else if( line[i] == '\"' ) {
+ state = empty;
+ args.push_back(arg);
+ arg = "";
+ } else arg += line[i];
+ break;
+
+ case found_bs:
+ state = found_q;
+ arg += line[i];
+ break;
+ }
+ }
+
+ return args;
+}
+
+template <class T>
+std::vector<char *> get_arg_ptrs
+( const T &arg_strings ) {
+ std::vector<char *> arg_out;
+ for( size_t i = 0; i < arg_strings.size(); i++ )
+ arg_out.push_back( (char *)arg_strings[i].c_str() );
+ arg_out.push_back(0);
+ return arg_out;
+}
+
+int execute_command( bool verbose, const std::vector<std::string> &args ) {
+ std::string error;
+ std::vector<char *> args_ptrs;
+ const char *tag = "executable";
+
+ if( verbose ) {
+ fprintf( stderr, "<command>\n" );
+ for( size_t i = 0; i < args.size(); i++ ) {
+ fprintf( stderr, "<%s>%s</%s>\n", tag, args[i].c_str(), tag
);
+ tag = "argument";
+ }
+ }
+
+ Process p = fork_execvp( args );
+
+ while( p && p->ProcessStarted() && !p->EndOfStream() )
+ fprintf( stderr, "%s", p->ReadStdError().c_str() );
+
+ if( verbose ) {
+ fprintf( stderr, "<status>%d</status>\n", p->GetStatus() );
+ fprintf( stderr, "</command>\n" );
+ }
+
+ return p ? p->GetStatus() : -1;
+}
+
+std::string make_tmp_name() {
+ int fd;
+ std::string name;
+
+ while( true ) {
+ name = tmpnam(NULL);
+ name += ".obj";
+ if( (fd = creat( name.c_str(), 0644 )) != -1 ) {
+ close(fd);
+ return name;
+ }
+ }
+}
+
+void recognize_arg( std::vector<std::string> &args,
+ std::string &result,
+ size_t &i,
+ const std::string &argname,
+ const std::string &short_argname = "" ) {
+ if( (short_argname.size() && (args[i] == short_argname)) ||
+ (args[i] == argname) ) {
+ result = args[i+1];
+ args.erase(args.begin()+i);
+ args.erase(args.begin()+i--);
+ } else if( args[i].substr(0,argname.size()+1) == argname + "=" ) {
+ result = args[i].substr(argname.size()+1);
+ args.erase(args.begin()+i--);
+ }
+}
+
+int run_ld( bool verbose, bool nostdlib, bool nostartfiles, bool is_dll,
+ bool make_map,
+ const std::string &lib_dir,
+ const std::string &ldscript,
+ const std::vector<std::string> &arg_vect ) {
+ bool use_libgcc = false;
+ std::vector<std::string> args = arg_vect;
+ std::string real_output,
+ entry_point = "0x1000",
+ image_base = "0x400000", subsystem = "windows",
+ make_dll,
+ file_align = "0x1000",
+ section_align = "0x1000", base_file;
+ std::vector<std::string>::iterator i =
+ std::find(args.begin(),args.end(),"-lgcc");
+
+ if( i != args.end() ) {
+ args.erase( i );
+ use_libgcc = true;
+ }
+
+ if( !nostartfiles ) {
+ if( make_dll.size() )
+ args.push_back(lib_dir + "/dllcrt2.o");
+ else
+ args.push_back(lib_dir + "/crt2.o");
+ }
+
+ if( !nostdlib ) {
+ args.push_back(std::string("-L") + lib_dir);
+ args.push_back("-lkernel32");
+ args.push_back("-lmsvcrt");
+ args.push_back("-lcrtdll");
+ args.push_back("-lmingw32");
+ }
+ if( use_libgcc )
+ args.push_back(lib_dir + "/libgcc.a");
+
+ if( verbose )
+ args.insert(args.begin()+1,"-v");
+
+ args.insert(args.begin()+1,"-T");
+ args.insert(args.begin()+2,ldscript);
+ args.insert(args.begin()+1,"-r");
+ args.insert(args.begin()+1,"--start-group");
+ args.push_back("--end-group");
+
+ for( size_t i = 0; i < args.size(); i++ ) {
+ if( args[i] == "-o" && i < args.size()-1 ) {
+ real_output = args[++i];
+ } else if( args[i].substr(0,4) == "-mdll" ) {
+ args.erase(args.begin()+i--);
+ make_dll = "-dll";
+ }
+
+ recognize_arg( args, entry_point, i, "--entry", "-e" );
+ recognize_arg( args, image_base, i, "--image-base" );
+ recognize_arg( args, subsystem, i, "--subsystem" );
+ recognize_arg( args, file_align, i, "--file-alignment" );
+ recognize_arg( args, section_align, i, "--section-alignment" );
+ recognize_arg( args, base_file, i, "--base-file" );
+ }
+
+ if( execute_command( verbose, args ) )
+ return 1;
+
+ if( base_file.size() ) {
+ FILE *f = fopen(base_file.c_str(), "wb");
+ if( !f ) {
+ fprintf(stderr, "<error>\n");
+ perror(base_file.c_str());
+ fprintf(stderr, "</error>\n");
+ return 1;
+ }
+ fclose(f);
+ }
+
+ /* Ok fixup the elf object file */
+ ElfObjectFile eof(real_output);
+
+ if(!eof) return 1;
+
+ ElfPeHeader header
+ (strtoul(image_base.c_str(), 0, 0),
+ strtoul(section_align.c_str(), 0, 0),
+ strtoul(file_align.c_str(), 0, 0),
+ 0x10000,
+ 0x100000,
+ 0x10000,
+ 0x100000,
+ is_dll,
+ atoi(subsystem.c_str()),
+ &eof);
+
+ eof.addSection(".peheader", header.getData(), TYPE_PEHEADER);
+
+ return 0;
+}
+
+int main( int argc, char **argv ) {
+ bool verbose = false, ld_mode = false, nostdlib = false,
+ nostartfiles = false, is_dll = false, make_map = false;
+ int err_fd[2], read_len, child_pid_gcc, child_pid_command, status = 0;
+ std::string gcc_name, gcc_hash_output, gcc_line, linker_name = "ld",
+ mingw_lib_dir, ldscript;
+ std::vector<std::string> gcc_args_str,
+ subcmd_args;
+ std::vector<char *> arguments_for_gcc;
+ char buf[1024];
+
+ for( int i = 1; i < argc; i++ ) {
+ if( std::string("-gcc-name") == argv[i] && i < argc-1 ) {
+ gcc_name = argv[++i];
+ } else if( std::string("-ldscript") == argv[i] && i < argc-1 ) {
+ ldscript = argv[++i];
+ } else if( std::string("-link-stage-name") == argv[i] && i < argc-1
) {
+ linker_name = argv[++i];
+ } else if( std::string("-mingw-lib-dir") == argv[i] && i < argc-1 )
{
+ mingw_lib_dir = argv[++i];
+ } else if( std::string("-v") == argv[i] ) {
+ verbose = true;
+ } else if( std::string("-pipe") == argv[i] ) {
+ /* ignore */
+ } else if( std::string("-T") == argv[i] ) {
+ /* ignore */
+ i++;
+ } else if( std::string("-nostdlib") == argv[i] ) {
+ nostdlib = true;
+ } else if( std::string("-nostartfiles") == argv[i] ) {
+ nostartfiles = true;
+ } else if( std::string("-shared") == argv[i] ) {
+ is_dll = true;
+ } else if( std::string("-map") == argv[i] ) {
+ make_map = true;
+ } else {
+ gcc_args_str.push_back(argv[i]);
+ }
+ }
+
+ /* We never use the system start files or standard libs */
+ gcc_args_str.insert(gcc_args_str.begin()+1,"-nostdlib");
+ gcc_args_str.insert(gcc_args_str.begin()+1,"-nostartfiles");
+
+ if( std::string(argv[0]).find("ld") != std::string::npos ) {
+ gcc_args_str.insert
+ ( gcc_args_str.begin(), linker_name );
+ return run_ld
+ ( verbose, nostdlib, nostartfiles, is_dll, make_map, mingw_lib_dir,
+ ldscript, gcc_args_str );
+ }
+ if( verbose ) fprintf( stderr, "<compiler-driver>\n" );
+
+ // Stack on driver name and dump commands flag
+ gcc_args_str.insert(gcc_args_str.begin(),std::string("-###"));
+ gcc_args_str.insert(gcc_args_str.begin(),gcc_name);
+
+ /* Redirect stderr to our pipe */
+ if( verbose ) {
+ const char *tag = "executable";
+ fprintf( stderr, "<gcc>\n" );
+ for( size_t i = 0; i < gcc_args_str.size(); i++ ) {
+ fprintf( stderr, " <%s>%s</%s>\n",
+ tag, gcc_args_str[i].c_str(),
+ tag );
+ tag = "arg";
+ }
+ fprintf( stderr, "</gcc>\n" );
+ }
+
+ Process p = fork_execvp( gcc_args_str );
+
+ while( p && p->ProcessStarted() && !p->EndOfStream() )
+ gcc_hash_output += p->ReadStdError();
+
+ std::istringstream iss( gcc_hash_output );
+
+ if( p->GetStatus() ) goto final;
+
+ while( std::getline( iss, gcc_line, '\n' ) ) {
+ // command line
+ if( gcc_line.size() > 2 && gcc_line[0] == ' ' ) {
+ subcmd_args =
+ break_arguments<std::vector<std::string> >( gcc_line );
+
+ if( subcmd_args.size() < 1 ) continue;
+
+ if( subcmd_args[0].find("collect2") != std::string::npos ||
+ subcmd_args[0].find("ld") != std::string::npos ) {
+ if( run_ld( verbose, nostdlib, nostartfiles, is_dll, make_map,
+ mingw_lib_dir, ldscript, subcmd_args ) )
+ goto final;
+ else
+ continue;
+ }
+
+ if( verbose )
+ subcmd_args.insert(subcmd_args.begin()+1,"-v");
+
+ if( execute_command
+ ( verbose, subcmd_args ) )
+ goto final;
+ } else if( verbose )
+ fprintf( stderr, "<error>%s</error>\n", gcc_line.c_str() );
+ }
+ goto theend;
+
+ final:
+ status = 1;
+ theend:
+ if( verbose ) {
+ fprintf( stderr, "<status>%d</status>\n", status );
+ fprintf( stderr, "</compiler-driver>\n" );
+ }
+ return status;
+}
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/fork_execvp.h
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/fork_execvp.h (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/fork_execvp.h Sun Apr 29 08:05:11 2007
@@ -1,0 +1,28 @@
+#ifndef FORK_EXECVP_H
+#define FORK_EXECVP_H
+
+#include <string>
+#include <vector>
+
+class ProcessHolder {
+public:
+ virtual ~ProcessHolder() { }
+ virtual std::string ReadStdError() = 0;
+ virtual bool ProcessStarted() const = 0;
+ virtual bool EndOfStream() const = 0;
+ virtual int GetStatus() const = 0;
+};
+
+class Process {
+public:
+ Process( ProcessHolder *h ) : holder(h) { }
+ ~Process() { delete holder; }
+ ProcessHolder *operator -> () const { return holder; }
+ operator ProcessHolder *() const { return (holder &&
holder->ProcessStarted()) ? holder : NULL; }
+private:
+ ProcessHolder *holder;
+};
+
+ProcessHolder *fork_execvp( const std::vector<std::string> &args );
+
+#endif//FORK_EXECVP_H
Propchange: branches/powerpc/reactos/tools/ppc-build/elfpe/fork_execvp.h
------------------------------------------------------------------------------
svn:executable = *
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/fork_unix.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/fork_unix.cpp (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/fork_unix.cpp Sun Apr 29 08:05:11 2007
@@ -1,0 +1,66 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "fork_execvp.h"
+
+class UnixProcessHolder : public ProcessHolder {
+public:
+ UnixProcessHolder( const std::vector<std::string> &args )
+ : read_fd(-1), child_pid(-1), at_end(false), status(-1) {
+ std::vector<char *> argvect(args.size()+1);
+ for( size_t i = 0; i < args.size(); i++ )
+ argvect[i] = (char *)args[i].c_str();
+ argvect[args.size()] = 0;
+
+ int err_fd[2];
+
+ if( pipe( err_fd ) == -1 )
+ return;
+
+ fflush(stdout);
+
+ child_pid = fork();
+
+ if( !child_pid ) {
+ dup2( err_fd[1], 2 );
+ close( err_fd[0] );
+ close( err_fd[1] );
+
+ execvp(args[0].c_str(), &argvect[0] );
+ exit(1);
+ } else {
+ close( err_fd[1] );
+ read_fd = err_fd[0];
+ }
+ }
+
+ ~UnixProcessHolder() {
+ close( read_fd );
+ }
+
+ std::string ReadStdError() {
+ char buf[1024];
+ int rl = read( read_fd, buf, sizeof(buf) );
+ if( rl < 1 ) {
+ at_end = true;
+ waitpid( child_pid, &status, 0 );
+ return "";
+ }
+ return std::string(buf, rl);
+ }
+
+ bool ProcessStarted() const { return child_pid != -1; }
+ bool EndOfStream() const { return at_end; }
+ int GetStatus() const { return status; }
+
+private:
+ bool at_end;
+ int read_fd;
+ int child_pid;
+ int status;
+};
+
+ProcessHolder *fork_execvp( const std::vector<std::string> &args ) {
+ return new UnixProcessHolder( args );
+}
Propchange: branches/powerpc/reactos/tools/ppc-build/elfpe/fork_unix.cpp
------------------------------------------------------------------------------
svn:executable = *
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/fork_win32.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/fork_win32.cpp (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/fork_win32.cpp Sun Apr 29 08:05:11
2007
@@ -1,0 +1,109 @@
+#include <windows.h>
+#include "fork_execvp.h"
+
+class Win32ProcessHolder : public ProcessHolder {
+public:
+ Win32ProcessHolder( const std::string &args )
+ : ErrorRead(INVALID_HANDLE_VALUE),
+ ProcessHandle(INVALID_HANDLE_VALUE),
+ StreamEnded(false) {
+ HANDLE ErrorWrite = NULL, ErrorReadTemp = NULL;
+ PROCESS_INFORMATION pi = { };
+ SECURITY_ATTRIBUTES sa = { };
+ STARTUPINFO si = { };
+
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+
+ if(!CreatePipe(&ErrorReadTemp, &ErrorWrite, &sa, 0)) return;
+
+ if(!DuplicateHandle(GetCurrentProcess(), ErrorReadTemp,
+ GetCurrentProcess(), &ErrorRead,
+ 0, FALSE,
+ DUPLICATE_SAME_ACCESS)) return;
+
+ CloseHandle(ErrorReadTemp);
+
+ si.cb = sizeof(si);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ si.hStdError = ErrorWrite;
+
+ if(!CreateProcess(NULL, (char *)args.c_str(), NULL, NULL, TRUE,
+ 0, NULL, NULL, &si, &pi)) return;
+
+ ProcessHandle = pi.hProcess;
+
+ CloseHandle(ErrorWrite);
+ }
+
+ ~Win32ProcessHolder() {
+ CloseHandle( ErrorRead );
+ CloseHandle( ProcessHandle );
+ }
+
+ std::string ReadStdError() {
+ char Buf[1024];
+ DWORD ReadBytes;
+
+ if( StreamEnded ) return "";
+
+ StreamEnded =
+ !ReadFile(ErrorRead, Buf, sizeof(Buf), &ReadBytes, NULL) ||
+ !ReadBytes;
+
+ if( !StreamEnded ) return std::string(Buf, ReadBytes);
+ else return "";
+ }
+
+ bool EndOfStream() const {
+ return StreamEnded;
+ }
+
+ bool ProcessStarted() const {
+ return ProcessHandle != INVALID_HANDLE_VALUE;
+ }
+
+ int GetStatus() const {
+ DWORD Status = 1;
+ if( ProcessHandle != INVALID_HANDLE_VALUE ) {
+ WaitForSingleObject( ProcessHandle, INFINITE );
+ GetExitCodeProcess( ProcessHandle, &Status );
+ }
+ return Status;
+ }
+
+private:
+ bool StreamEnded;
+ HANDLE ErrorRead, ProcessHandle;
+};
+
+std::string quote_escape( const std::string &_str ) {
+ std::string str = _str;
+ size_t q;
+
+ q = str.find('\"');
+ while( q != std::string::npos ) {
+ str.replace(q, 1, "\\\"");
+ q = str.find('\"');
+ }
+
+ return std::string("\"") + str + "\"";
+}
+
+ProcessHolder *fork_execvp( const std::vector<std::string> &args ) {
+ std::string argstring;
+ ProcessHolder *holder;
+
+ for( std::vector<std::string>::const_iterator i = args.begin();
+ i != args.end();
+ i++ ) {
+ if( i != args.begin() )
+ argstring += " ";
+ argstring += quote_escape(*i);
+ }
+
+ return new Win32ProcessHolder( argstring );
+}
Propchange: branches/powerpc/reactos/tools/ppc-build/elfpe/fork_win32.cpp
------------------------------------------------------------------------------
svn:executable = *
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/header.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/header.cpp (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/header.cpp Sun Apr 29 08:05:11 2007
@@ -1,0 +1,176 @@
+#include <time.h>
+#include "util.h"
+#include "header.h"
+
+ElfPeHeader::ElfPeHeader
+ (uint32_t imagebase,
+ uint32_t filealign,
+ uint32_t sectionalign,
+ uint32_t stackreserve,
+ uint32_t stackcommit,
+ uint32_t heapreserve,
+ uint32_t heapcommit,
+ int subsysid,
+ bool dll,
+ ElfObjectFile *eof) :
+ imagebase(imagebase),
+ sectionalign(sectionalign),
+ stackreserve(stackreserve),
+ stackcommit(stackcommit),
+ heapreserve(heapreserve),
+ heapcommit(heapcommit),
+ subsysid(subsysid),
+ eof(eof)
+{
+ data.resize(computeSize());
+ createHeaderSection();
+}
+
+int ElfPeHeader::computeSize() const
+{
+ return sectionalign; /* We'll compute it for real later */
+}
+
+void ElfPeHeader::createHeaderSection()
+{
+ data[0] = 'M'; data[1] = 'Z';
+ uint8_t *dataptr = &data[0x3c];
+ uint32_t coffHeaderSize, optHeaderSizeMember;
+ le32write_postinc(dataptr, 0x80);
+ dataptr = &data[0x80];
+ le32write_postinc(dataptr, 0x4550);
+ le16write_postinc(dataptr, getPeArch());
+ le16write_postinc(dataptr, getNumSections());
+ le32write_postinc(dataptr, time(NULL));
+ le32write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, 0);
+ optHeaderSizeMember = dataptr - &data[0];
+ le16write_postinc(dataptr, 0); // Will fixup sizeof opt header
+ le16write_postinc(dataptr, getExeFlags());
+ coffHeaderSize = dataptr - &data[0];
+ le16write_postinc(dataptr, 0);
+ le16write_postinc(dataptr, 0x100);
+ le32write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, getEntryPoint());
+ le32write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, imagebase);
+ le32write_postinc(dataptr, sectionalign);
+ le32write_postinc(dataptr, filealign);
+ le16write_postinc(dataptr, 4);
+ le16write_postinc(dataptr, 0);
+ le16write_postinc(dataptr, 1);
+ le16write_postinc(dataptr, 0);
+ le16write_postinc(dataptr, 4);
+ le16write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, getImageSize());
+ le32write_postinc(dataptr, computeSize());
+ le32write_postinc(dataptr, 0); // No checksum yet
+ le16write_postinc(dataptr, subsysid);
+ le16write_postinc(dataptr, getDllFlags());
+ le32write_postinc(dataptr, stackreserve);
+ le32write_postinc(dataptr, stackcommit);
+ le32write_postinc(dataptr, heapreserve);
+ le32write_postinc(dataptr, heapcommit);
+ le32write_postinc(dataptr, 0);
+ le32write_postinc(dataptr, 10); // # Directories
+ // "Directories"
+ le32pwrite_postinc(dataptr, getExportInfo());
+ le32pwrite_postinc(dataptr, getImportInfo());
+ le32pwrite_postinc(dataptr, getResourceInfo());
+ le32pwrite_postinc(dataptr, getExceptionInfo());
+ le32pwrite_postinc(dataptr, getSecurityInfo());
+ le32pwrite_postinc(dataptr, getRelocInfo());
+ le32pwrite_postinc(dataptr, getDebugInfo());
+ le32pwrite_postinc(dataptr, getDescrInfo());
+ le32pwrite_postinc(dataptr, getMachInfo());
+ le32pwrite_postinc(dataptr, getTlsInfo());
+ // Fixup size of optional header
+ le16write
+ (&data[0] + optHeaderSizeMember,
+ (dataptr - &data[0]) - coffHeaderSize);
+}
+
+const std::vector<uint8_t> &ElfPeHeader::getData() const { return data; }
+
+uint32_t ElfPeHeader::getImageSize() const
+{
+ uint32_t start = 0;
+ uint32_t limit = 0;
+ for(int i = 0; i < eof->getNumSections(); i++) {
+ {
+ const ElfObjectFile::Section § = eof->getSection(i);
+ limit = roundup(start + sect.logicalSize(), sectionalign);
+ }
+ start = limit;
+ }
+
+ return limit;
+}
+
+uint16_t ElfPeHeader::getPeArch() const
+{
+ return IMAGE_FILE_MACHINE_POWERPCBE; /* for now */
+}
+
+u32pair_t getNamedSectionInfo(ElfObjectFile *eof, const std::string &name)
+{
+ const ElfObjectFile::Section *sect = eof->getNamedSection(name);
+ if(sect)
+ return std::make_pair(sect->getStartRva(), sect->logicalSize());
+ else
+ return std::make_pair(0,0);
+}
+
+u32pair_t ElfPeHeader::getExportInfo() const
+{
+ return getNamedSectionInfo(eof, ".edata");
+}
+
+u32pair_t ElfPeHeader::getImportInfo() const
+{
+ return getNamedSectionInfo(eof, ".idata");
+}
+
+u32pair_t ElfPeHeader::getResourceInfo() const
+{
+ return getNamedSectionInfo(eof, ".rsrc");
+}
+
+u32pair_t ElfPeHeader::getExceptionInfo() const
+{
+ return std::make_pair(0,0);
+}
+
+u32pair_t ElfPeHeader::getSecurityInfo() const
+{
+ return std::make_pair(0,0);
+}
+
+u32pair_t ElfPeHeader::getRelocInfo() const
+{
+ return std::make_pair(0,0);
+}
+
+u32pair_t ElfPeHeader::getDebugInfo() const
+{
+ return std::make_pair(0,0);
+}
+
+u32pair_t ElfPeHeader::getDescrInfo() const
+{
+ return std::make_pair(0,0);
+}
+
+u32pair_t ElfPeHeader::getTlsInfo() const
+{
+ return std::make_pair(0,0);
+}
+
+u32pair_t ElfPeHeader::getMachInfo() const
+{
+ return std::make_pair(0,0);
+}
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/header.h
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/header.h (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/header.h Sun Apr 29 08:05:11 2007
@@ -1,0 +1,58 @@
+#ifndef COMPDVR_ELFHEADER_H
+#define COMPDVR_ELFHEADER_H
+
+#include <vector>
+#include <utility>
+#include "pedef.h"
+#include "util.h"
+#include "objectfile.h"
+
+class ElfPeHeader {
+public:
+ ElfPeHeader
+ (uint32_t imagebase,
+ uint32_t imagealign,
+ uint32_t filealign,
+ uint32_t stackreserve,
+ uint32_t stackcommit,
+ uint32_t heapreserve,
+ uint32_t heapcommit,
+ int subsysid,
+ bool dll,
+ ElfObjectFile *eof);
+ const ElfObjectFile::secdata_t &getData() const;
+
+private:
+ void createHeaderSection();
+ int getNumSections() const { return eof->getNumSections(); }
+ int computeSize() const;
+ int getExeFlags() const { return 0; }
+ int getDllFlags() const { return dll ? IMAGE_FILE_DLL : 0; }
+ u32pair_t getExportInfo() const;
+ u32pair_t getImportInfo() const;
+ u32pair_t getResourceInfo() const;
+ u32pair_t getExceptionInfo() const;
+ u32pair_t getSecurityInfo() const;
+ u32pair_t getRelocInfo() const;
+ u32pair_t getDebugInfo() const;
+ u32pair_t getDescrInfo() const;
+ u32pair_t getMachInfo() const;
+ u32pair_t getTlsInfo() const;
+ uint32_t getEntryPoint() const { return eof->getEntryPoint(); }
+ uint32_t getImageSize() const;
+ uint16_t getPeArch() const;
+ uint32_t saToRva(int section, uint32_t offset) const;
+ uint32_t vaToRva(uint32_t source_addr) const;
+
+ uint32_t
+ imagebase, filealign, sectionalign,
+ stackreserve, stackcommit,
+ heapreserve, heapcommit;
+ bool dll;
+ int subsysid;
+ ElfObjectFile *eof;
+ std::vector<uint8_t> data;
+ static const char *mzHeader;
+};
+
+#endif//COMPDVR_ELFHEADER_H
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/makefile
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/makefile (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/makefile Sun Apr 29 08:05:11 2007
@@ -1,0 +1,7 @@
+all: compdvr
+
+%.o: %.cpp
+ g++ -g -o $@ $<
+
+compdvr: compdvr.cpp fork_unix.cpp header.cpp objectfile.cpp util.cpp
+ g++ -g -o $@ $^ -lelf
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/objectfile.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/objectfile.cpp (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/objectfile.cpp Sun Apr 29 08:05:11
2007
@@ -1,0 +1,83 @@
+#include <libelf/libelf.h>
+#include <fcntl.h>
+#include "objectfile.h"
+
+ElfObjectFile::ElfObjectFile(const std::string &filename) : fd(-1)
+{
+ Elf_Scn *s = 0;
+ Elf32_Ehdr *ehdr;
+ fd = open(filename.c_str(), O_RDWR, 0);
+ if(fd >= 0) {
+ if(elf_version(EV_CURRENT) == EV_NONE) {
+ // Old version
+ return;
+ }
+ elfHeader = elf_begin(fd, ELF_C_RDWR, (Elf*)0);
+ if(elf_kind(elfHeader) != ELF_K_ELF) {
+ // Didn't get an elf object file
+ return;
+ }
+ ehdr = elf32_getehdr(elfHeader);
+ shnum = ehdr->e_shnum;
+ phnum = ehdr->e_phnum;
+ shstrndx = ehdr->e_shstrndx;
+ for(size_t i = 0; i < shnum; i++)
+ {
+ s = elf_nextscn(elfHeader, s);
+ if(!s) break;
+ sections.push_back(new Section(*this, s));
+ fprintf(stderr, "Got section %04d %s\n", i,
sections[i]->getName().c_str());
+ }
+ }
+}
+
+ElfObjectFile::~ElfObjectFile()
+{
+ if(elfHeader) elf_end(elfHeader);
+ if(fd >= 0) close(fd);
+}
+
+uint32_t ElfObjectFile::getEntryPoint() const
+{
+ Elf32_Ehdr *elf32ehdr = elf32_getehdr(elfHeader);
+ return elf32ehdr->e_entry;
+}
+
+void ElfObjectFile::addSection(const std::string &name, const secdata_t &data,
int type)
+{
+ Elf_Scn *newsect = elf_newscn(elfHeader),
+ *strsect = elf_getscn(elfHeader, shstrndx);
+ Elf32_Shdr *shdr = elf32_getshdr(newsect);
+ /* Create data for the new section */
+ Elf_Data *edata = elf_newdata(newsect), *strdata = elf_getdata(strsect, 0),
+ *newstrdata = elf_newdata(strsect);
+ edata->d_align = 0x1000;
+ edata->d_size = data.size();
+ edata->d_off = 0;
+ edata->d_type = ELF_T_BYTE;
+ edata->d_version = EV_CURRENT;
+ edata->d_buf = malloc(edata->d_size);
+ memcpy(edata->d_buf, &data[0], edata->d_size);
+ /* Add the name of the new section to the string table */
+ newstrdata->d_off = strdata->d_off + strdata->d_size;
+ newstrdata->d_size = name.size() + 1;
+ newstrdata->d_align = 1;
+ newstrdata->d_buf = (void *)name.c_str();
+ /* Finish the section */
+ shdr->sh_name = newstrdata->d_off;
+ shdr->sh_type = type;
+ shdr->sh_flags = 0;
+ shdr->sh_addr = 0;
+ shdr->sh_link = 0;
+ shdr->sh_info = 0;
+
+ elf_update(elfHeader, ELF_C_WRITE);
+}
+
+const ElfObjectFile::Section *ElfObjectFile::getNamedSection(const std::string &name)
const
+{
+ for(size_t i = 0; i < sections.size(); i++) {
+ if(sections[i]->getName() == name) return sections[i];
+ }
+ return NULL;
+}
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/objectfile.h
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/objectfile.h (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/objectfile.h Sun Apr 29 08:05:11 2007
@@ -1,0 +1,66 @@
+#ifndef COMPDVR_ELFOBJECT_H
+#define COMPDVR_ELFOBJECT_H
+
+#include <string>
+#include <vector>
+#include <libelf/libelf.h>
+
+class ElfObjectFile {
+public:
+ typedef std::vector<uint8_t> secdata_t;
+
+ class Section {
+ public:
+ Section(const Section &other) :
+ obj(other.obj), section(other.section) { }
+ Section(ElfObjectFile &obj, Elf_Scn *sechdr) :
+ obj(&obj), section(sechdr) { }
+ Section &operator = (const Section &other) {
+ obj = other.obj;
+ section = other.section;
+ }
+ operator bool () { return !!section; }
+ std::string getName() const {
+ Elf32_Shdr *e32shdr = elf32_getshdr(section);
+ return obj->getString(e32shdr->sh_name);
+ }
+
+ int logicalSize() const {
+ Elf32_Shdr *e32shdr = elf32_getshdr(section);
+ return e32shdr->sh_size;
+ }
+
+ uint32_t getStartRva() const {
+ Elf32_Shdr *e32shdr = elf32_getshdr(section);
+ return e32shdr->sh_addr;
+ }
+
+ private:
+ const ElfObjectFile *obj;
+ Elf_Scn *section;
+ };
+
+ ElfObjectFile(const std::string &filename);
+ ~ElfObjectFile();
+
+ Elf *operator -> () { return fd >= 0 ? elfHeader : 0; }
+ bool operator ! () const { return fd == -1 ? true : false; }
+ int getNumSections() const { return sections.size(); }
+ uint32_t getEntryPoint() const;
+ std::string getString(int offset) const {
+ return elf_strptr(elfHeader, shstrndx, offset);
+ }
+ void addSection
+ (const std::string &name, const secdata_t &data, int type = SHT_PROGBITS);
+ const Section &getSection(int sect) const { return *sections[sect]; }
+ const Section *getNamedSection(const std::string &name) const;
+
+private:
+ int fd;
+ int shnum, phnum;
+ int shstrndx;
+ Elf *elfHeader;
+ std::vector<Section*> sections;
+};
+
+#endif//COMPDVR_ELFOBJECT_H
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/pedef.h
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/pedef.h (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/pedef.h Sun Apr 29 08:05:11 2007
@@ -1,0 +1,32 @@
+#ifndef COMPDVR_PEDEF_H
+#define COMPDVR_PEDEF_H
+
+// Definitions from bernd.luevelsmeyer(a)iplan.heitec.net 's pe.txt reference
+#define IMAGE_FILE_MACHINE_I386 (0x14c)
+#define IMAGE_FILE_MACHINE_I486 (0x14d)
+#define IMAGE_FILE_MACHINE_I586 (0x14e)
+#define IMAGE_FILE_MACHINE_R3000BE (0x160)
+#define IMAGE_FILE_MACHINE_R3000 (0x162)
+#define IMAGE_FILE_MACHINE_R4000 (0x166)
+#define IMAGE_FILE_MACHINE_R10000 (0x168)
+#define IMAGE_FILE_MACHINE_ALPHA (0x184)
+#define IMAGE_FILE_MACHINE_POWERPC (0x1F0)
+// Recognize BE PowerPC by a coff BE style arch magic
+#define IMAGE_FILE_MACHINE_POWERPCBE (0xF001)
+
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
+#define IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
+#define IMAGE_FILE_32BIT_MACHINE 0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
+#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
+#define IMAGE_FILE_SYSTEM 0x1000
+#define IMAGE_FILE_DLL 0x2000
+#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
+
+#endif//COMPDVR_PEDEF_H
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/util.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/util.cpp (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/util.cpp Sun Apr 29 08:05:11 2007
@@ -1,0 +1,35 @@
+#include "util.h"
+
+uint32_t roundup(uint32_t value, int round)
+{
+ round--;
+ return (value + round) & ~round;
+}
+
+void le16write(uint8_t *dataptr, uint16_t value)
+{
+ dataptr[0] = value;
+ dataptr[1] = value >> 8;
+}
+
+void le16write_postinc(uint8_t *&dataptr, uint16_t value)
+{
+ le16write(dataptr, value); dataptr += 2;
+}
+
+void le32write(uint8_t *dataptr, uint32_t value)
+{
+ le16write(dataptr, value);
+ le16write(dataptr + 2, value >> 16);
+}
+
+void le32write_postinc(uint8_t *&dataptr, uint32_t value)
+{
+ le32write(dataptr, value); dataptr += 4;
+}
+
+void le32pwrite_postinc(uint8_t *&dataptr, const u32pair_t &value)
+{
+ le32write_postinc(dataptr, value.first);
+ le32write_postinc(dataptr, value.second);
+}
Added: branches/powerpc/reactos/tools/ppc-build/elfpe/util.h
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ppc-build…
==============================================================================
--- branches/powerpc/reactos/tools/ppc-build/elfpe/util.h (added)
+++ branches/powerpc/reactos/tools/ppc-build/elfpe/util.h Sun Apr 29 08:05:11 2007
@@ -1,0 +1,20 @@
+#ifndef COMPDVR_UTIL_H
+#define COMPDVR_UTIL_H
+
+#include <utility>
+#include <stdint.h>
+
+void le16write(uint8_t *dataptr, uint16_t value);
+void le16write_postinc(uint8_t *&dataptr, uint16_t value);
+void le32write(uint8_t *dataptr, uint32_t value);
+void le32write_postinc(uint8_t *&dataptr, uint32_t value);
+uint16_t le16read(uint8_t *dataptr);
+uint16_t le16read_postinc(uint8_t *&dataptr);
+uint32_t le32read(uint8_t *dataptr);
+uint32_t le32read_postinc(uint8_t *&dataptr);
+typedef std::pair<uint32_t, uint32_t> u32pair_t;
+void le32pwrite_postinc(uint8_t *&dataptr, const u32pair_t &pair);
+void le32pwrite(uint8_t *dataptr, const u32pair_t &pair);
+uint32_t roundup(uint32_t value, int round);
+
+#endif//COMPDVR_UTIL_H