#! /usr/bin/python # -*- coding: utf-8 -*- # kate: space-indent on; indent-width 2; mixedindent off; indent-mode python; # Copyright (C) 2009 Amand 'alrj' Tihon # # This file is part of bold, the Byte Optimized Linker. # # You can redistribute this file and/or modify it under the terms of the # GNU General Public License as published by the Free Software Foundation, # either version 3 of the License or (at your option) any later version. __author__ = "Amand Tihon " __version__ = "0.2.0" from Bold.linker import BoldLinker from Bold.errors import * from optparse import OptionParser import os, sys class BoldOptionParser(OptionParser): """Bold option parser.""" global __version__ _usage_message = "%prog [options] objfile..." _version_message = "%%prog version %s" % __version__ _description_message = """A limited ELF linker for x86_64. It is intended to create very small executables with the least possible overhead.""" def __init__(self): OptionParser.__init__(self, usage=self._usage_message, version=self._version_message, description=self._description_message, add_help_option=True, prog="bold") self.set_defaults(entry=None, outfile="a.out", raw=False, ccall=False, align=False) self.add_option("-e", "--entry", action="store", dest="entry", metavar="SYMBOL", help="Set the entry point (default: _start)") self.add_option("-l", "--library", action="append", dest="shlibs", metavar="LIBNAME", help="Search for library LIBNAME") self.add_option("-L", "--library-path", action="append", dest="libpath", metavar="DIRECTORY", help="Add DIRECTORY to library search path. (Ignored, for compatibility only.") self.add_option("-o", "--output", action="store", dest="outfile", metavar="FILE", help="Set output file name (default: a.out)") self.add_option("--raw", action="store_true", dest="raw", help="Don't include the builtin external symbols resolution code") self.add_option("-c", "--ccall", action="store_true", dest="ccall", help="Make external symbol callable by C (default: no)") self.add_option("-a", "--align-ccall", action="store_true", dest="align", help="Align C callable symbols with actual functions pointers") def main(): parser = BoldOptionParser() options, args = parser.parse_args() if not args: print >>sys.stderr, "No input files" return 1 # Take a copy of args objects = args[:] if options.align and not options.ccall: print >>sys.stderr, "Making external symbols callable by C because of -a." options.ccall = True if options.ccall and options.raw: # ccall implies that we include the symbol resolution code... print >>sys.stderr, "Including symbol resolution code because of -c." options.raw = False if not options.raw: for d in ['.', 'runtime', '/usr/lib/bold/', '/usr/local/lib/bold']: f = os.path.join(d, 'bold_ibh-x86_64.o') if os.path.isfile(f): objects.append(f) break else: print >>sys.stderr, "Could not find bold_ibh-x86_64.o." return 1 # Try reordering objects ? linker = BoldLinker() for infile in objects: try: linker.add_object(infile) except UnsupportedObject, e: print >>sys.stderr, e return 1 except IOError, e: print >>sys.stderr, e return 1 if options.shlibs: for shlib in options.shlibs: try: linker.add_shlib(shlib) except LibNotFound, e: print >>sys.stderr, e return 1 if options.entry is not None: linker.entry_point = options.entry else: if not options.raw: linker.entry_point = "_bold__ibh_start" try: linker.build_symbols_tables() linker.check_external() linker.build_external(with_jump=options.ccall, align_jump=options.align) linker.link() except UndefinedSymbol, e: print >>sys.stderr, e return 1 except RedefinedSymbol, e: print >>sys.stderr, e return 1 # Remove the file if it was present try: os.unlink(options.outfile) except os.error, e: if e.errno == 2: # No such file pass try: o = open(options.outfile, "wb") except IOError, e: print >>sys.stderr, e return 1 linker.tofile(o) o.close() try: os.chmod(options.outfile, 0755) except IOError, e: print >>sys.stderr, e return 1 return 0 if __name__ == "__main__": try: rcode = main() except Exception, e: raise print >>sys.stderr, "Unhandled error:", e rcode = 1 exit(rcode)