_start from archive
_start from archive
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
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.
something like this should work:
Code: Select all
i586-elf-ld [....] foo.o bar.a
Re: _start from archive
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.
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.
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: _start from archive
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.
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: _start from archive
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
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.
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
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
This suggestion was exactly what I was looking for. Thank you so much.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.
Although I didn't investigate, I believe that in newer versions of binutils, the linker will treat the start symbol differently.