]> git.alrj.org Git - bold.git/blobdiff - bold
License change, small enhancements, version bump.
[bold.git] / bold
diff --git a/bold b/bold
new file mode 100755 (executable)
index 0000000..cbeeac5
--- /dev/null
+++ b/bold
@@ -0,0 +1,168 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+# kate: space-indent on; indent-width 2; mixedindent off; indent-mode python;
+
+# Copyright (C) 2009 Amand 'alrj' Tihon <amand.tihon@alrj.org>
+#
+# 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 <amand.tihon@alrj.org>"
+__version__ = "0.1.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 ['.', 'data', '/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 boldsymres-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.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)
+