_start from archive

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
dschatz
Member
Member
Posts: 61
Joined: Wed Nov 10, 2010 10:55 pm

_start from archive

Post 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?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: _start from archive

Post by bluemoon »

How you execute the linker?

something like this should work:

Code: Select all

i586-elf-ld [....] foo.o bar.a
.a should be treated as a collection of object files and linked like object files.
dschatz
Member
Member
Posts: 61
Joined: Wed Nov 10, 2010 10:55 pm

Re: _start from archive

Post 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.
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: _start from archive

Post 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.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: _start from archive

Post 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.
dschatz
Member
Member
Posts: 61
Joined: Wed Nov 10, 2010 10:55 pm

Re: _start from archive

Post 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.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: _start from archive

Post 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.
dschatz
Member
Member
Posts: 61
Joined: Wed Nov 10, 2010 10:55 pm

Re: _start from archive

Post 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.
Post Reply