/*
 */


//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//


#include <stdlib.h>
#include <iostream>
#include <strstream>
#include <fstream>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <cstring>

using namespace std;

typedef std::string                      string_t;
typedef std::vector< string_t >          strings_t;
typedef std::map< string_t, string_t >   str_hash_t;
typedef std::pair< string_t, string_t >  str_pair_t;
#ifdef _WIN32
    typedef long long  int64_t;
#endif

string_t
shift( strings_t & strs ) {
    string_t first = strs.front();
    strs.erase( strs.begin() );
    return first;
} // shift

string_t
find(
    str_hash_t const & hash,
    string_t const &   key
) {
    string_t value;
    str_hash_t::const_iterator it = hash.find( key );
    if ( it != hash.end() ) {
        value = it->second;
    }; // if
    return value;
} // find

void die( string_t const & message ) {
    std::cerr << message << std::endl;
    exit( 1 );
} // die

void stop( string_t const & message ) {
    printf( "%s\n", message.c_str() );
    exit( 1 );
}

// An entry in the symbol table of a .obj file.
struct symbol_t {
    long long        name;
    unsigned         value;
    unsigned  short  section_num;
    unsigned  short  type;
    char             storage_class;
    char             nAux;
}; // struct symbol_t


class _rstream_t : public std::istrstream {

    private:

        const char * buf;

    protected:

        _rstream_t( pair< const char *, streamsize > p )
            : istrstream( p.first, p.second ), buf( p.first )
        {
        }

        ~_rstream_t() {
            delete [] buf;
        }

}; // class _rstream_t

/* A stream encapuslating the content of a file or the content of a string, overriding the
   >> operator to read various integer types in binary form, as well as a symbol table
   entry.
*/
class rstream_t : public _rstream_t {
private:

    template< typename type_t >
    inline rstream_t & do_read( type_t & x ) {
	read( (char*) & x, sizeof( type_t ) );
	return * this;
    }

    static pair<const char*, streamsize> getBuf(const char *fileName) {
	ifstream raw(fileName,ios::binary | ios::in);
	if(!raw.is_open())
	    stop("rstream.getBuf: Error opening file");
	raw.seekg(0,ios::end);
	streampos fileSize = raw.tellg();
	if(fileSize < 0)
	    stop("rstream.getBuf: Error reading file");
	char *buf = new char[fileSize];
	raw.seekg(0,ios::beg);
	raw.read(buf, fileSize);
	return pair<const char*, streamsize>(buf,fileSize);
    }
public:
    // construct from a string
    rstream_t( const char * buf, streamsize size ) :
        _rstream_t( pair< const char *, streamsize >( buf, size ) )
    {}
    /* construct from a file whole content is fully read once to initialize the content of
       this stream
    */
    rstream_t( string_t const & fileName )
        : _rstream_t( getBuf( fileName.c_str() ) )
    {
    }

    rstream_t & operator >>( int & x ) {
	return do_read(x);
    }
    rstream_t & operator >>(unsigned &x) {
	return do_read(x);
    }
    rstream_t & operator>>(short &x) {
	return do_read(x);
    }
    rstream_t & operator>>(unsigned short &x) {
	return do_read(x);
    }
    rstream_t & operator>>( symbol_t & e ) {
	read((char*)&e, 18);
	return *this;
    }
}; // class rstream_t

// string table in a .OBJ file
class StringTable {
private:
    map<string, unsigned> directory;
    size_t length;
    char *data;

    // make <directory> from <length> bytes in <data>
    void makeDirectory(void) {
	unsigned i = 4;
	while(i < length) {
	    string s = string(data + i);
	    directory.insert(make_pair(s, i));
	    i += s.size() + 1;
	}
    }
    // initialize <length> and <data> with contents specified by the arguments
    void init(const char *_data) {
	unsigned _length = *(unsigned*)_data;

	if(_length < sizeof(unsigned) || _length != *(unsigned*)_data)
	    stop("StringTable.init: Invalid symbol table");
	if(_data[_length - 1]) {
	    // to prevent runaway strings, make sure the data ends with a zero
	    data = new char[length = _length + 1];
	    data[_length] = 0;
	} else {
	    data = new char[length = _length];
	}
	*(unsigned*)data = length;
	memcpy( data + sizeof(unsigned), _data + sizeof(unsigned), length - sizeof(unsigned) );
	makeDirectory();
    }
public:
    StringTable( rstream_t & f ) {
	/* Construct string table by reading from f.
	 */
	streampos s;
	unsigned strSize;
	char *strData;

	s = f.tellg();
	f>>strSize;
	if(strSize < sizeof(unsigned))
	    stop("StringTable: Invalid string table");
	strData = new char[strSize];
	*(unsigned*)strData = strSize;
	// read the raw data into <strData>
	f.read(strData + sizeof(unsigned), strSize - sizeof(unsigned));
	s = f.tellg() - s;
	if(s < strSize)
	    stop("StringTable: Unexpected EOF");
	init(strData);
	delete[]strData;
    }
    StringTable(const set<string> &strings) {
	/* Construct string table from given strings.
	 */
	char *p;
	set<string>::const_iterator it;
	size_t s;

	// count required size for data
	for(length = sizeof(unsigned), it = strings.begin(); it != strings.end(); ++it) {
	    size_t l = (*it).size();

	    if(l > (unsigned) 0xFFFFFFFF)
		stop("StringTable: String too long");
	    if(l > 8) {
		length += l + 1;
		if(length > (unsigned) 0xFFFFFFFF)
		    stop("StringTable: Symbol table too long");
	    }
	}
	data = new char[length];
	*(unsigned*)data = length;
	// populate data and directory
	for(p = data + sizeof(unsigned), it = strings.begin(); it != strings.end(); ++it) {
	    const string &str = *it;
	    size_t l = str.size();
	    if(l > 8) {
		directory.insert(make_pair(str, p - data));
		memcpy(p, str.c_str(), l);
		p[l] = 0;
		p += l + 1;
	    }
	}
    }
    ~StringTable() {
	delete[] data;
    }
    /* Returns encoding for given string based on this string table.
       Error if string length is greater than 8 but string is not in
       the string table--returns 0.
    */
    int64_t encode(const string &str) {
	int64_t r;

	if(str.size() <= 8) {
	    // encoded directly
	    ((char*)&r)[7] = 0;
	    strncpy((char*)&r, str.c_str(), 8);
	    return r;
	} else {
	    // represented as index into table
	    map<string,unsigned>::const_iterator it = directory.find(str);
	    if(it == directory.end())
		stop("StringTable::encode: String now found in string table");
	    ((unsigned*)&r)[0] = 0;
	    ((unsigned*)&r)[1] = (*it).second;
	    return r;
	}
    }
    /* Returns string represented by x based on this string table.
       Error if x references an invalid position in the table--returns
       the empty string.
    */
    string decode(int64_t x) const {
	if(*(unsigned*)&x == 0) {
	    // represented as index into table
	    unsigned &p = ((unsigned*)&x)[1];
	    if(p >= length)
		stop("StringTable::decode: Invalid string table lookup");
	    return string(data + p);
	} else {
	    // encoded directly
	    char *p = (char*)&x;
	    int i;

	    for(i = 0; i < 8 && p[i]; ++i);
	    return string(p, i);
	}
    }
    void write(ostream &os) {
	os.write(data, length);
    }
};


void
obj_copy(
    string_t const &    src,    // Name of source file.
    string_t const &    dst,    // Name of destination file.
    str_hash_t const &  redefs  // List of redefinititions.
) {

    set< string > strings; // set of all occurring symbols, appropriately prefixed
    streampos fileSize;
    size_t strTabStart;
    unsigned symTabStart;
    unsigned symNEntries;
    int i;


    string const error_reading = "Error reading \"" + src + "\" file: ";

    rstream_t in( src );

    in.seekg( 0, ios::end );
    fileSize = in.tellg();

    in.seekg( 8 );
    in >> symTabStart >> symNEntries;
    strTabStart = symTabStart + 18 * size_t( symNEntries );
    in.seekg( strTabStart );
    if ( in.eof() ) {
        stop( error_reading + "Unexpected end of file" );
    }
    StringTable stringTableOld( in ); // Read original string table.

    if ( in.tellg() != fileSize ) {
        stop( error_reading + "Unexpected data after string table" );
    }

    // compute set of occurring strings with prefix added
    for ( i = 0; i < symNEntries; ++ i ) {

	symbol_t e;

	in.seekg( symTabStart + i * 18 );
	if ( in.eof() ) {
            stop("hideSymbols: Unexpected EOF");
        }
	in >> e;
	if ( in.fail() ) {
            stop("hideSymbols: File read error");
        }
	if ( e.nAux ) {
            i += e.nAux;
        }
	const string & s = stringTableOld.decode( e.name );
	// if symbol is extern and found in <hide>, prefix and insert into strings,
	// otherwise, just insert into strings without prefix
        string_t name = find( redefs, s );
	strings.insert( name != "" && e.storage_class == 2 ? name : s );
    }

    ofstream out( dst.c_str(), ios::trunc | ios::out | ios::binary );
    if ( ! out.is_open() ) {
        stop("hideSymbols: Error opening output file");
    }

    // make new string table from string set
    StringTable stringTableNew = StringTable( strings );

    // copy input file to output file up to just before the symbol table
    in.seekg( 0 );
    char * buf = new char[ symTabStart ];
    in.read( buf, symTabStart );
    out.write( buf, symTabStart );
    delete [] buf;

    // copy input symbol table to output symbol table with name translation
    for ( i = 0; i < symNEntries; ++ i ) {
	symbol_t e;

	in.seekg( symTabStart + i * 18 );
	if ( in.eof() ) {
            stop("hideSymbols: Unexpected EOF");
        }
	in >> e;
	if ( in.fail() ) {
            stop("hideSymbols: File read error");
        }
	const string & s = stringTableOld.decode( e.name );
	out.seekp( symTabStart + i * 18 );
        string_t name = find( redefs, s );
	e.name = stringTableNew.encode( ( e.storage_class == 2 && name != "" ) ? name : s );
	out.write( (char*) & e, 18 );
	if ( out.fail() ) {
            stop( "hideSymbols: File write error" );
        }
	if ( e.nAux ) {
	    // copy auxiliary symbol table entries
	    int nAux = e.nAux;
	    for (int j = 1; j <= nAux; ++j ) {
		in >> e;
		out.seekp( symTabStart + ( i + j ) * 18 );
		out.write( (char*) & e, 18 );
	    }
	    i += nAux;
	}
    }
    // output string table
    stringTableNew.write( out );
}


void
split( string_t const & str, char ch, string_t & head, string_t & tail ) {
    string_t::size_type pos = str.find( ch );
    if ( pos == string_t::npos ) {
        head = str;
        tail = "";
    } else {
        head = str.substr( 0, pos );
        tail = str.substr( pos + 1 );
    }; // if
} // split


void help() {
    std::cout
        << "NAME\n"
        << "    objcopy -- copy and translate object files\n"
        << "\n"
        << "SYNOPSIS\n"
        << "    objcopy options... source destination\n"
        << "\n"
        << "OPTIONS\n"
        << "    --help  Print this help and exit.\n"
        << "    --redefine-sym old=new\n"
        << "            Rename \"old\" symbol in source object file to \"new\" symbol in\n"
        << "            destination object file.\n"
        << "    --redefine-syms sym_file\n"
        << "            For each pair \"old new\" in sym_file rename \"old\" symbol in \n"
        << "            source object file to \"new\" symbol in destination object file.\n"
        << "\n"
        << "ARGUMENTS\n"
        << "    source  The name of source object file.\n"
        << "    destination\n"
        << "            The name of destination object file.\n"
        << "\n"
        << "DESCRIPTION\n"
        << "    This program implements a minor bit of Linux* OS's objcopy utility on Windows* OS.\n"
        << "    It can copy object files and edit its symbol table.\n"
        << "\n"
        << "EXAMPLES\n"
        << "    \n"
        << "        > objcopy --redefine-sym fastcpy=__xxx_fastcpy a.obj b.obj\n"
        << "\n";
} // help


int
main( int argc, char const * argv[] ) {

    strings_t   args( argc - 1 );
    str_hash_t  redefs;
    strings_t   files;

    std::copy( argv + 1, argv + argc, args.begin() );

    while ( args.size() > 0 ) {
        string_t arg = shift( args );
        if ( arg.substr( 0, 2 ) == "--" ) {
            // An option.
            if ( 0  ) {
            } else if ( arg == "--help" ) {
                help();
                return 0;
            } else if ( arg == "--redefine-sym" ) {
                if ( args.size() == 0 ) {
                    die( "\"" + arg + "\" option requires an argument" );
                }; // if
                // read list of symbol pairs "old new" from command line.
                string_t redef = shift( args );
                string_t old_sym;
                string_t new_sym;
                split( redef, '=', old_sym, new_sym );
                if ( old_sym.length() == 0 || new_sym.length() == 0 ) {
                    die( "Illegal redefinition: \"" + redef + "\"; neither old symbol nor new symbol may be empty" );
                }; // if
                redefs.insert( str_pair_t( old_sym, new_sym ) );
            } else if ( arg == "--redefine-syms" ) {
                if ( args.size() == 0 ) {
                    die( "\"" + arg + "\" option requires an argument" );
                }; // if
                // read list of symbol pairs "old new" from file.
                string_t fname = shift( args );
                string_t redef;
		ifstream ifs( fname.c_str() );
		while ( ifs.good() ) {
                    getline( ifs, redef );// get pair of old/new symbols separated by space
                    string_t old_sym;
                    string_t new_sym;
                    // AC: gcount() does not work here (always return 0), so comment it
                    //if ( ifs.gcount() ) { // skip empty lines
                    split( redef, ' ', old_sym, new_sym );
                    if ( old_sym.length() == 0 || new_sym.length() == 0 ) {
                        break;  // end of file reached (last empty line)
                        //die( "Illegal redefinition: \"" + redef + "\"; neither old symbol nor new symbol may be empty" );
                    }; // if
                    redefs.insert( str_pair_t( old_sym, new_sym ) );
                    //}
		}
            } else {
                die( "Illegal option: \"" + arg + "\"" );
            }; // if
        } else {
            // Not an option, a file name.
            if ( files.size() >= 2 ) {
                die( "Too many files specified; two files required (use --help option for help)" );
            }; // if
            files.push_back( arg );
        }; // if
    }; // while
    if ( files.size() < 2 ) {
        die( "Not enough files specified; two files required (use --help option for help)" );
    }; // if

    obj_copy( files[ 0 ], files[ 1 ], redefs );

    return 0;

} // main


// end of file //
