Page 1 of 1
_start from archive
Posted: Fri Apr 13, 2012 8:59 am
by dschatz
As part of my build system I package up most of the kernel components into an archive (.a file). I then link this with an object file to produce the binary. As part of this, the _start symbol is defined in the archive. My linker (gnu binutils) will not pull _start out from the archive and all the related dependencies and link together the binary (Instead, at the end complaining that _start is not defined). Is there any way to change this behavior?
Re: _start from archive
Posted: Fri Apr 13, 2012 9:05 am
by bluemoon
How you execute the linker?
something like this should work:
.a should be treated as a collection of object files and linked like object files.
Re: _start from archive
Posted: Fri Apr 13, 2012 10:34 am
by dschatz
I execute it through gcc:
gcc <assorted options> -o <outputfile> foo.o bar.a
Where _start is in bar.a
This in turn calls the linker of course. I don't think the linker ever treats an archive as a set of object files though, there are some semantics to what it pulls out of the archive and what it doesn't. Typically there is a left-to-right symbol resolution.
If I explicitly put start.o in the link line, it works.
Re: _start from archive
Posted: Fri Apr 13, 2012 11:23 am
by xenos
I guess the linker includes only those object files in bar.a which contain symbols that are needed to resolve references in foo.o. In order to include the whole archive (including the one containing _start) you need to pass something like --whole-archive to the linker.
Re: _start from archive
Posted: Fri Apr 13, 2012 12:37 pm
by Owen
A Unix-style linker processes its parameters from left to right, extracting only the objects from a static archive required to serve the dependencies of the so-far considered objects. It only starts considering special symbols like _start once it has a properly linked program.
Re: _start from archive
Posted: Fri Apr 13, 2012 1:06 pm
by dschatz
This isn't entirely true:
with -M passed to the linker:
GNU ld (GNU Binutils for Ubuntu) 2.21.53.20110810
/usr/bin/ld: mode elf_x86_64
attempt to open apps/helloworld/helloworld.o succeeded
apps/helloworld/helloworld.o
attempt to open libfoo.a succeeded
Archive member included because of file (symbol)
...
libfoo.a(start.o) (_start)
(libfoo.a)start.o
...
The linker is smart enough to grab the _start symbol out of the archive.
However, in other environments I don't have the same behavior. I wonder if it is a binutils version issue or some issue with the output format or other flags that may be different.
Re: _start from archive
Posted: Sat Apr 14, 2012 1:33 pm
by qw
The linker looks in archives for symbols that are referenced in the object files but are yet undefined. So the question is, does it treat "_start" like any other undefined symbol. Maybe
-u _start will do the trick.
Re: _start from archive
Posted: Mon Apr 16, 2012 10:38 am
by dschatz
Hobbes wrote:The linker looks in archives for symbols that are referenced in the object files but are yet undefined. So the question is, does it treat "_start" like any other undefined symbol. Maybe
-u _start will do the trick.
This suggestion was exactly what I was looking for. Thank you so much.
Although I didn't investigate, I believe that in newer versions of binutils, the linker will treat the start symbol differently.