]> git.alrj.org Git - bold.git/blob - bold.py
Correct stupid bug, use a simple hash function.
[bold.git] / bold.py
1 #! /usr/bin/python
2 # -*- coding: utf-8 -*-
3 # kate: space-indent on; indent-width 2; mixedindent off; indent-mode python;
4
5 # Copyright (C) 2009 Amand 'alrj' Tihon <amand.tihon@alrj.org>
6 #
7 # This file is part of bold, the Byte Optimized Linker.
8 #
9 # You can redistribute this file and/or modify it under the terms of the
10 # GNU Lesser General Public License as published by the Free Software
11 # Foundation, version 2.1.
12
13 __author__ = "Amand Tihon <amand.tihon@alrj.org>"
14 __version__ = "0.0.1"
15
16
17 from Bold.linker import BoldLinker
18 from Bold.errors import *
19 from optparse import OptionParser
20 import os, sys
21
22 class BoldOptionParser(OptionParser):
23   """Bold option parser."""
24   global __version__
25   _usage_message = "%prog [options] file..."
26   _version_message = "%%prog version %s" % __version__
27   _description_message = """A limited ELF linker for x86_64. It is
28 intended to create very small executables with the least possible overhead."""
29
30   def __init__(self):
31     OptionParser.__init__(self, usage=self._usage_message,
32       version=self._version_message, description=self._description_message,
33       add_help_option=True, prog="bold")
34
35     self.set_defaults(entry="_start", outfile="a.out", raw=False, ccall=False)
36
37     self.add_option("-e", "--entry", action="store", dest="entry",
38       metavar="SYMBOL", help="Set the entry point (default: _start)")
39
40     self.add_option("-l", "--library", action="append", dest="shlibs",
41       metavar="LIBNAME", help="Search for library LIBNAME")
42
43     self.add_option("-o", "--output", action="store", dest="outfile",
44       metavar="FILE", help="Set output file name (default: a.out)")
45
46     self.add_option("--raw", action="store_true", dest="raw",
47       help="Don't include the symbol resolution code (default: include it)")
48
49     self.add_option("-c", "--ccall", action="store_true", dest="ccall",
50       help="Make external symbol callable by C (default: no)")
51
52
53 def main():
54   parser = BoldOptionParser()
55   options, args = parser.parse_args()
56
57   if not args:
58     print >>sys.stderr, "No input files"
59     return 1
60
61   linker = BoldLinker()
62
63   for infile in args:
64     try:
65       linker.add_object(infile)
66     except UnsupportedObject, e:
67       print >>sys.stderr, e
68       return 1
69     except IOError, e:
70       print >>sys.stderr, e
71       return 1
72
73   if options.ccall and options.raw:
74     # ccall implies that we include the symbol resolution code...
75     print >>sys.stderr, "Including symbol resolution code because of -c."
76     options.raw = False
77
78   if not options.raw:
79     for d in ['data', '/usr/lib/bold/', '/usr/local/lib/bold', '.']:
80       f = os.path.join(d, 'bold_ibh-x86_64.o')
81       try:
82         linker.add_object(f)
83         break
84       except UnsupportedObject, e:
85         # file was found, but is not recognized
86         print >>sys.stderr, e
87         return 1
88       except IOError, e:
89         # not found, try next directory
90         pass
91     else:
92       print >>sys.stderr, "Could not find boldsymres-x86_64.o."
93       return 1
94
95   if options.shlibs:
96     for shlib in options.shlibs:
97       try:
98         linker.add_shlib(shlib)
99       except LibNotFound, e:
100         print >>sys.stderr, e
101         return 1
102
103   linker.entry_point = options.entry
104
105   try:
106     linker.build_symbols_tables()
107     linker.build_external(with_jump=options.ccall)
108
109     linker.link()
110   except UndefinedSymbol, e:
111     print >>sys.stderr, e
112     return 1
113   except RedefinedSymbol, e:
114     print >>sys.stderr, e
115     return 1
116
117   # Remove the file if it was present
118   try:
119     os.unlink(options.outfile)
120   except os.error, e:
121     if e.errno == 2: # No such file
122       pass
123
124   try:
125     o = open(options.outfile, "wb")
126   except IOError, e:
127     print >>sys.stderr, e
128     return 1
129
130   linker.tofile(o)
131   o.close()
132   
133   try:
134     os.chmod(options.outfile, 0755)
135   except IOError, e:
136     print >>sys.stderr, e
137     return 1
138
139   return 0
140
141
142 if __name__ == "__main__":
143   try:
144     rcode = main()
145   except Exception, e:
146     raise
147     print >>sys.stderr, "Unhandled error:", e
148     rcode = 1
149
150   exit(rcode)
151