ld(1) cannot find entry symbol _start;

Robert Bonomi bonomi at mail.r-bonomi.com
Wed Sep 29 20:55:22 UTC 2010


> From owner-freebsd-questions at freebsd.org  Wed Sep 29 05:50:13 2010
> Date: Wed, 29 Sep 2010 11:51:09 +0100 (BST)
> From: Anton Shterenlikht <mexas at bristol.ac.uk>
> To: Michel Talon <talon at lpthe.jussieu.fr>
> Cc: freebsd-questions at freebsd.org
> Subject: Re: ld(1) cannot find entry symbol _start;
>
>
>
> On Tue, 28 Sep 2010, Michel Talon wrote:
>
> > Paul B Mahol said:
> > On 9/28/10, Anton Shterenlikht <mexas at bristol.ac.uk> wrote:
> >>> I'm trying to learn the very basics of the
> >>> compile - assemble - link process on FreeBSD.
> >>> Please don't shoot me.
> >> ....
> >>> Then I try to link the object file into
> >>> an executable:
> >>>
> >>> % ld tmp.o
> >>
> >> You are missing something in above command.
> >>
> >
> > More precisely, if you run gcc -v on a C file you get someting like:
> > /usr/bin/ld --eh-frame-hdr -V -dynamic-linker /libexec/ld-elf.so.1
> > /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib
> > -L/usr/lib /var/tmp//cco5EINk.o -lgcc --as-needed -lgcc_s --no-as-needed
> > -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o
> > /usr/lib/crtn.o
> >
> >
> > where the object file produced by compilation and assembling is
> > /var/tmp//cco5EINk.o
> >
> > That is adds several other object files to your own in order to get
> > an executable.
> >
> > In particular the start symbol, at which execution begins is in
> > /usr/lib/crt1.o
> >
> > as you can see from
> > niobe% nm /usr/lib/crt1.o
> >         w _DYNAMIC
> > 00000000 D __progname
> >         U _fini
> >         U _init
> >         U _init_tls
> > 00000000 T _start
> > 00000020 t _start1
> > 00000000 r abitag
> >         U atexit
> > 00000004 C environ
> >         U exit
> >         U main
> > which shows that _start is defined here, (but not e.g. _init). On the
> > other hand the function main() which is defined in your program is
> > referred to but undefined here.
>
> thank you. Where can I read more on what each file is for:
>
> % ls -al /usr/lib/crt*
> -r--r--r--  1 root  wheel  2552 Sep 15 13:52 /usr/lib/crt1.o
> -r--r--r--  1 root  wheel  4656 Sep 15 13:53 /usr/lib/crtbegin.o
> -r--r--r--  1 root  wheel  4936 Sep 15 13:53 /usr/lib/crtbeginS.o
> -r--r--r--  1 root  wheel  4656 Sep 15 13:53 /usr/lib/crtbeginT.o
> -r--r--r--  1 root  wheel  3648 Sep 15 13:53 /usr/lib/crtend.o
> -r--r--r--  1 root  wheel  3648 Sep 15 13:53 /usr/lib/crtendS.o
> -r--r--r--  1 root  wheel  1928 Sep 15 13:52 /usr/lib/crti.o
> -r--r--r--  1 root  wheel  1087 Sep 15 13:52 /usr/lib/crtn.o
>
> The sources for these files are in asm, so would be good
> to read a more accessible introduction.

Those routines set up the "run-time envrionment" that any UNIX
c-language evironment expects.  that's that the name 'crt' prefix
means '<c>-language <r>un-<t>ime'  this involves a bunch of 'gory
mechanical details' that *DON'T* really matter how they get 
accomplished, jus that they _do_ get done.  This includes things
like setting up the 'stack', and the 'heap', initializing the tables
for the dynamic-memory management routines (malloc and friends),
setting up 'stdin/stdout/stderr', and getting the command-line arguments 
processed so that they can be passed as 'argc', and 'argv' (also the 
'environment', in 'envp') to your 'main()' program.

>
> Also, it seems only crt1, crti and crtn are provided
> by FreeBSD itself (/usr/src/lib/csu/ia64), crtbegin and
> crtend are under /usr/src/contrib/gcc/config/ia64/,
> and sources for *S.o and *T.o I can't find at all.
> So which of these are specific to GCC on FreeBSD, and
> which aren't?

"who cares?" applies.  it is all simmply "required housekeeping"
go bring the state of the current running process (i.e, the task/
address-space/etc) to what is defined as the 'initial state' for
a c-language 'main()' program.
>
> For example if I use g95 compiler instead of gfortran45,
> will the linker still need all above object files?

If you use 'the compiler' to manage the linking process  -- e.g.

  {compilername} -o {executable}  {one-or-more-'object' .o file}

the right files will be automatically included in the executable.

'crt0.o' is the classical program entry point -- it may or may not
rely on other routines to get 'the environment' set up -- especially
depending on what 'advanced' features the program uses.. If you use
light-weight-process 'threads' (-lpthread)  this may call for different
crt0 code.

Unless you are engaged in porting the compiler and O/S to a completely
new hardware architecture, or trying to generate 'stand-alone' code, e.g.
for an embedded processor tht runs witout _anuting called a 'cpu', you 
don't have any reason to worry about this housekeeping code.  Its there,
it works, and it does what it's supposed to. <grin>   Oh yeah, if you 
tamper with it, you make it incompatible with the use of _any_ existing 
object files.




More information about the freebsd-questions mailing list