Runs static terminator routines after main returns.During the process' execution, handles calls to lazily-bound symbol stubs by binding the symbols, provides runtime dynamic loading services (via the dl*() API), and provides hooks for gdb and other debuggers to get critical information.Sets up the parameters to the executable's main function and calls it.Runs static initializers for the executable.Links those libraries into the executable by immediately binding non-lazy symbols and setting up the necessary tables for lazy binding.Recursively and cachingly loads all dependent dynamic libraries the executable links to into the process' memory space, including any necessary perusal of search paths from both the environment and the executable's "runpaths".Bootstraps itself based on the very simple raw stack set up for the process by the kernel.The process of linking dynamic libraries is similar, but not identical, and for brevity's sake I won't go into it here.ĭyld is actually responsible for quite a bit of work, all told. Obviously, this is a huge simplification and applies only to executables. Static linking, then, combines object files, resolves symbol references to external libraries, applies the relocations for those symbols, and builds a complete executable. Another peek at the load commands puts this in the _TEXT,_stubs section, which we'll look at in detail later. Replaced 0 with the address of the symbol stub for puts(), which comes immediately after main.The resulting address is 0x100000f61, which a peek at the load commands ( otool -l test) tells us is the exact beginning of the _TEXT,_cstring section. Replaced 0 with the actual offset from the leaq instruction to the L_str symbol, which in this case is 0x29.I don't know exactly why this is done, though I assume it has something to do with cache efficiency. This aligns the _TEXT segment flush up against the _DATA segment. The first 0xf35 (actually, 0xa0f, since the larger offset doesn't account for the file's Mach-O header) bytes of _TEXT are zeroed out. Located the _TEXT segment at the standard executable load address for x86_64, 0x0000000100000000, and the _TEXT,_text section at 0xf36 after that.Why does static linking matter to dynamic linking? Because the static linker, ld (and ld64) is responsible for transforming symbol references in your source code into indirect symbol lookups for dyld to use later. This is the step that typically happens after compiling, where the machine language the compiler churned out from your source code, the object files, are 'linked' together into a single binary file. So, let's start by talking about static linking, generally referred to simply as 'linking'. If you're curious about the particulars, I strongly recommend dyld's source code, which is publicly available at. Some of the deeper logic is new to me, so sorry in advance for any inaccuracies.īecause the precise details of how dyld works are quite complicated and change frequently, and because I don't yet know all of those details myself, most of my examination of it in this article is simplified, and in some places purely conceptual. I found this particular corner of the system interesting, and I see a lot of people having trouble with linking issues, so I decided to do an article about the basics of dynamic linking. In the course of a recent job interview, I had an opportunity to study some of the internals of dyld, the OS X dynamic linker.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |