]> git.alrj.org Git - bold.git/blob - doc/README
Add documentation.
[bold.git] / doc / README
1 .. HTML version generated with rst2html -t README > README.html
2
3 .. |date| date:: %b %e, %Y
4
5 Bold - The Byte Optimized Linker
6 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7
8 :Author:    Amand Tihon
9 :Contact:   <amand.tihon@alrj.org>
10 :Version:   0.1.0
11 :Date:      |date|
12 :Copyright: GNU GPL version 3 + Exception, see copyright file.
13
14 .. sectnum::
15
16 .. contents:: Table of contents
17    :backlinks: none
18
19
20 Abstract
21 ========
22
23 Bold is an ELF linker, currently only targetting x86_64 under Linux. Being
24 limited in capabilities, it should not be considered as an all-purpose linker.
25
26
27 Rationale
28 =========
29
30 Bold's main purpose is to generate very small executable programs.
31
32 While ``ld`` from the GNU binutils can do almost anything anyone would ever
33 need, some specific goals need an awful lot of tweaking, or can simply not be
34 achieved. Bold uses several tricks to reduce the size of the final executable
35 binary.
36
37
38 Getting Bold
39 ============
40
41 You can download the tarball from http://www.alrj.org/projects/bold
42 or get the latest development version with the following git command: ::
43
44   git clone http://git.alrj.org/git/bold.git
45
46 A gitweb interface is also available at http://git.alrj.org/
47
48
49 Requirements
50 ============
51
52 Bold itself is entirely written in Python. There are no additionnal
53 dependencies.
54
55 The runtime library that contains the external symbols resolver is written
56 in assembler (Intel syntax). An assembler like Nasm or Yasm is needed to
57 recompile the source code into an object file.
58
59
60 Installation
61 ============
62
63 TBD.
64
65
66 Using Bold
67 ==========
68
69 Synopsys
70 --------
71
72   bold [options] objfile...
73
74
75 Description
76 -----------
77
78 Bold combines a number of object files, relocate their data and resolves their
79 symbols references, in order to generate executable binaries.
80
81 Bold has only one, very specific purpose: making small executables.
82
83 Options
84 -------
85
86 --version
87   Show program's version and exit.
88
89 -h, --help
90   Show help message and exit.
91
92 -e SYMBOL, --entry=SYMBOL
93   Use SYMBOL as the explicit symbol for beginning execution of your program.
94   If ``--raw`` is specified, it defaults to ``_start``.
95
96 -l LIBNAME, --library=LIBNAME
97   Link against the shared library specified by LIBNAME. Bold relies on python's
98   ctypes module to find the libraries. This option may be used any number of
99   times.
100
101 -L DIRECTORY, --library-path=DIRECTORY
102   This option does nothing, and is present ony for compatibility reasons. It
103   MAY get implemented in the future, though. This option may be used any number
104   of times.
105
106 -o FILE, --output=FILE
107   Set the output file name (default value is a.out).
108
109 --raw
110   Don't include the builtin external symbols resolution code. This is
111   described in details further in this document.
112
113 -c, --ccall
114   Make external symbols directly callable by C, without having to declare the
115   pointers on functions. This option adds 6 bytes for each externally defined
116   function. This is described in details further in this document.
117
118 -a, --align
119   Align the wrappers for external symbols on an 8 byte boundary, to take
120   advantage of the RIP-relative addressing. This is described in details
121   further in this document.
122
123
124 Notes
125 -----
126
127 The ``LD_PRELOAD`` environment variable may not always work (as expected or
128 at all).
129
130 The ``main()`` function is called without any argument. Its return code is used
131 as exit code, though.
132
133
134 Internals
135 =========
136
137 External symbols resolution
138 ---------------------------
139
140 The "import by hash" method is from parapete, leblane, las, as described on
141 http://www.pouet.net/topic.php?which=5392
142
143
144 Calling from C
145 --------------
146
147 If you write your code in C and need to call the external symbols, you
148 basically have two options. The first one is to redefine them (or define new
149 ones) to call by pointers. For instance, ::
150
151   int SDL_Init(int);
152
153 would become: ::
154
155   int (*SDL_Init)(int);
156
157 Repeat it for all functions, or write a tool to automate it (hint: look at
158 http://research.mercury-labs.org/ibh-i386-0.2.2.tar.gz for help).
159
160 There's a second possibility however, and it's the one used by Bold when you
161 specify the ``--ccall`` option: make the resolved symbol point, not to the
162 address of the function, but to a JMP instruction to the actual address: ::
163
164   global SDL_Init
165   
166   .text
167   
168   SDL_Init:          jmp [rel _bold__SDL_Init]
169   SDL_SetVideoMode:  jmp [rel _bold__SDL_SetVideoMode]
170   
171   .bss
172   
173   _bold__SDL_Init          resq        ; Filled by the import by hash code
174   _bold__SDL_SetVideoMode  resq
175
176
177 This approach takes 6 bytes (the JMP instruction) for each external function
178 used.
179
180
181 Aligning
182 --------
183
184 The x86_64 architecture has this nice thing called "RIP-relative addressing".
185 If all the JMP instructions are in the same order than the pointers to the
186 functions they refer to, having them aligned with the pointers would result
187 in identical instructions. This is done with the ``--align`` option.
188
189 Adding two null bytes between each JMP enlarges the final executable by
190 2 x (number of function - 1) bytes, and may seem to go against our goal.
191 However, the result is a repetition of the *same eight bytes*, something that
192 can improve compression a lot!
193
194
195 Additional Trick 1: DT_DEBUG
196 ----------------------------
197
198 Bold declares a global symbol named ``_dt_debug``, that points to the value of
199 the ``DT_DEBUG`` entry of the ``DYNAMIC`` table, for easy access. Just in case,
200 the ``DYNAMIC`` table can also be reached using the global ``_DYNAMIC`` symbol.
201
202 Additional Trick 2: Short DYNAMIC table
203 ---------------------------------------
204
205 Executables generated by ``ld`` usually have a lot of entries in their
206 ``DYNAMIC`` table. Bold puts only the strict necessary:
207
208 - One ``DT_NEEDED`` entry for each shared library to load (obviously).
209 - A ``DT_SYMTAB`` entry, with null-pointer. Without this one, the interpreter
210   wouldn't do its job.
211 - a ``DT_DEBUG`` entry, that will be used for symbol resolution.
212
213 And that's it!
214
215
216