diff options
Diffstat (limited to 'openmp/runtime/tools/objcopy.cpp')
-rw-r--r-- | openmp/runtime/tools/objcopy.cpp | 520 |
1 files changed, 0 insertions, 520 deletions
diff --git a/openmp/runtime/tools/objcopy.cpp b/openmp/runtime/tools/objcopy.cpp deleted file mode 100644 index a2811c6261d..00000000000 --- a/openmp/runtime/tools/objcopy.cpp +++ /dev/null @@ -1,520 +0,0 @@ -/* - */ - - -//===----------------------------------------------------------------------===// -// -// 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 // |