From: Amand Tihon Date: Sat, 8 Aug 2009 17:45:26 +0000 (+0200) Subject: Add documentation. X-Git-Tag: bold-0.1.0~3 X-Git-Url: https://git.alrj.org/?p=bold.git;a=commitdiff_plain;h=2513fd6b1f728766c9a13ebf8cda8355f6288626 Add documentation. --- diff --git a/doc/README b/doc/README new file mode 100644 index 0000000..a66fb64 --- /dev/null +++ b/doc/README @@ -0,0 +1,216 @@ +.. HTML version generated with rst2html -t README > README.html + +.. |date| date:: %b %e, %Y + +Bold - The Byte Optimized Linker +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:Author: Amand Tihon +:Contact: +:Version: 0.1.0 +:Date: |date| +:Copyright: GNU GPL version 3 + Exception, see copyright file. + +.. sectnum:: + +.. contents:: Table of contents + :backlinks: none + + +Abstract +======== + +Bold is an ELF linker, currently only targetting x86_64 under Linux. Being +limited in capabilities, it should not be considered as an all-purpose linker. + + +Rationale +========= + +Bold's main purpose is to generate very small executable programs. + +While ``ld`` from the GNU binutils can do almost anything anyone would ever +need, some specific goals need an awful lot of tweaking, or can simply not be +achieved. Bold uses several tricks to reduce the size of the final executable +binary. + + +Getting Bold +============ + +You can download the tarball from http://www.alrj.org/projects/bold +or get the latest development version with the following git command: :: + + git clone http://git.alrj.org/git/bold.git + +A gitweb interface is also available at http://git.alrj.org/ + + +Requirements +============ + +Bold itself is entirely written in Python. There are no additionnal +dependencies. + +The runtime library that contains the external symbols resolver is written +in assembler (Intel syntax). An assembler like Nasm or Yasm is needed to +recompile the source code into an object file. + + +Installation +============ + +TBD. + + +Using Bold +========== + +Synopsys +-------- + + bold [options] objfile... + + +Description +----------- + +Bold combines a number of object files, relocate their data and resolves their +symbols references, in order to generate executable binaries. + +Bold has only one, very specific purpose: making small executables. + +Options +------- + +--version + Show program's version and exit. + +-h, --help + Show help message and exit. + +-e SYMBOL, --entry=SYMBOL + Use SYMBOL as the explicit symbol for beginning execution of your program. + If ``--raw`` is specified, it defaults to ``_start``. + +-l LIBNAME, --library=LIBNAME + Link against the shared library specified by LIBNAME. Bold relies on python's + ctypes module to find the libraries. This option may be used any number of + times. + +-L DIRECTORY, --library-path=DIRECTORY + This option does nothing, and is present ony for compatibility reasons. It + MAY get implemented in the future, though. This option may be used any number + of times. + +-o FILE, --output=FILE + Set the output file name (default value is a.out). + +--raw + Don't include the builtin external symbols resolution code. This is + described in details further in this document. + +-c, --ccall + Make external symbols directly callable by C, without having to declare the + pointers on functions. This option adds 6 bytes for each externally defined + function. This is described in details further in this document. + +-a, --align + Align the wrappers for external symbols on an 8 byte boundary, to take + advantage of the RIP-relative addressing. This is described in details + further in this document. + + +Notes +----- + +The ``LD_PRELOAD`` environment variable may not always work (as expected or +at all). + +The ``main()`` function is called without any argument. Its return code is used +as exit code, though. + + +Internals +========= + +External symbols resolution +--------------------------- + +The "import by hash" method is from parapete, leblane, las, as described on +http://www.pouet.net/topic.php?which=5392 + + +Calling from C +-------------- + +If you write your code in C and need to call the external symbols, you +basically have two options. The first one is to redefine them (or define new +ones) to call by pointers. For instance, :: + + int SDL_Init(int); + +would become: :: + + int (*SDL_Init)(int); + +Repeat it for all functions, or write a tool to automate it (hint: look at +http://research.mercury-labs.org/ibh-i386-0.2.2.tar.gz for help). + +There's a second possibility however, and it's the one used by Bold when you +specify the ``--ccall`` option: make the resolved symbol point, not to the +address of the function, but to a JMP instruction to the actual address: :: + + global SDL_Init + + .text + + SDL_Init: jmp [rel _bold__SDL_Init] + SDL_SetVideoMode: jmp [rel _bold__SDL_SetVideoMode] + + .bss + + _bold__SDL_Init resq ; Filled by the import by hash code + _bold__SDL_SetVideoMode resq + + +This approach takes 6 bytes (the JMP instruction) for each external function +used. + + +Aligning +-------- + +The x86_64 architecture has this nice thing called "RIP-relative addressing". +If all the JMP instructions are in the same order than the pointers to the +functions they refer to, having them aligned with the pointers would result +in identical instructions. This is done with the ``--align`` option. + +Adding two null bytes between each JMP enlarges the final executable by +2 x (number of function - 1) bytes, and may seem to go against our goal. +However, the result is a repetition of the *same eight bytes*, something that +can improve compression a lot! + + +Additional Trick 1: DT_DEBUG +---------------------------- + +Bold declares a global symbol named ``_dt_debug``, that points to the value of +the ``DT_DEBUG`` entry of the ``DYNAMIC`` table, for easy access. Just in case, +the ``DYNAMIC`` table can also be reached using the global ``_DYNAMIC`` symbol. + +Additional Trick 2: Short DYNAMIC table +--------------------------------------- + +Executables generated by ``ld`` usually have a lot of entries in their +``DYNAMIC`` table. Bold puts only the strict necessary: + +- One ``DT_NEEDED`` entry for each shared library to load (obviously). +- A ``DT_SYMTAB`` entry, with null-pointer. Without this one, the interpreter + wouldn't do its job. +- a ``DT_DEBUG`` entry, that will be used for symbol resolution. + +And that's it! + + +