What is the difference between crtbegin.o, crtbeginT.o and crtbeginS.o?
I will quote it following, in case that URL disappears.
Mini FAQ about the misc libc/gcc crt files.
Some definitions:
PIC - position independent code (-fPIC)
PIE - position independent executable (-fPIE -pie)
crt - C runtime
crt0.o crt1.o etc...
Some systems use crt0.o, while some use crt1.o (and a few even use crt2.o
or higher). Most likely due to a transitionary phase that some targets
went through. The specific number is otherwise entirely arbitrary -- look
at the internal gcc port code to figure out what your target expects. All
that matters is that whatever gcc has encoded, your C library better use
the same name.
This object is expected to contain the _start symbol which takes care of
bootstrapping the initial execution of the program. What exactly that
entails is highly libc dependent and as such, the object is provided by
the C library and cannot be mixed with other ones.
On uClibc/glibc systems, this object initializes very early ABI requirements
(like the stack or frame pointer), setting up the argc/argv/env values, and
then passing pointers to the init/fini/main funcs to the internal libc main
which in turn does more general bootstrapping before finally calling the real
main function.
glibc ports call this file 'start.S' while uClibc ports call this crt0.S or
crt1.S (depending on what their gcc expects).
crti.o
Defines the function prologs for the .init and .fini sections (with the _init
and _fini symbols respectively). This way they can be called directly. These
symbols also trigger the linker to generate DT_INIT/DT_FINI dynamic ELF tags.
These are to support the old style constructor/destructor system where all
.init/.fini sections get concatenated at link time. Not to be confused with
newer prioritized constructor/destructor .init_array/.fini_array sections and
DT_INIT_ARRAY/DT_FINI_ARRAY ELF tags.
glibc ports used to call this 'initfini.c', but now use 'crti.S'. uClibc
also uses 'crti.S'.
crtn.o
Defines the function epilogs for the .init/.fini sections. See crti.o.
glibc ports used to call this 'initfini.c', but now use 'crtn.S'. uClibc
also uses 'crtn.S'.
Scrt1.o
Used in place of crt1.o when generating PIEs.
gcrt1.o
Used in place of crt1.o when generating code with profiling information.
Compile with -pg. Produces output suitable for the gprof util.
Mcrt1.o
Like gcrt1.o, but is used with the prof utility. glibc installs this as
a dummy file as it's useless on linux systems.
crtbegin.o
GCC uses this to find the start of the constructors.
crtbeginS.o
Used in place of crtbegin.o when generating shared objects/PIEs.
crtbeginT.o
Used in place of crtbegin.o when generating static executables.
crtend.o
GCC uses this to find the start of the destructors.
crtendS.o
Used in place of crtend.o when generating shared objects/PIEs.
General linking order:
crt1.o crti.o crtbegin.o [-L paths] [user objects] [gcc libs] [C libs] [gcc libs] crtend.o crtn.o
What's the usage of Mcrt1.o and Scrt1.o?
Files of the form *crt*.o
are invariably C runtime startup code (the bulk of the C runtime tends to exist in libraries, the startup code is an object file as it's always needed).
The description of the various types can be found here, copied below to make the answer self-contained. First some definitions:
Mini FAQ about the misc libc/gcc crt files.
Some definitions:
PIC - position independent code (-fPIC)
PIE - position independent executable (-fPIE -pie)
crt - C runtime
Then the various startup object files:
crt0.o
Older style of the initial runtime code ? Usually not generated anymore
with Linux toolchains, but often found in bare metal toolchains. Serves
same purpose as crt1.o (see below).
crt1.o
Newer style of the initial runtime code. Contains the _start symbol which
sets up the env with argc/argv/libc _init/libc _fini before jumping to the
libc main. glibc calls this file 'start.S'.
crti.o
Defines the function prolog; _init in the .init section and _fini in the
.fini section. glibc calls this 'initfini.c'.
crtn.o
Defines the function epilog. glibc calls this 'initfini.c'.
Scrt1.o
Used in place of crt1.o when generating PIEs.
gcrt1.o
Used in place of crt1.o when generating code with profiling information.
Compile with -pg. Produces output suitable for the gprof util.
Mcrt1.o
Like gcrt1.o, but is used with the prof utility. glibc installs this as
a dummy file as it's useless on linux systems.
And some others:
crtbegin.o
GCC uses this to find the start of the constructors.
crtbeginS.o
Used in place of crtbegin.o when generating shared objects/PIEs.
crtbeginT.o
Used in place of crtbegin.o when generating static executables.
crtend.o
GCC uses this to find the start of the destructors.
crtendS.o
Used in place of crtend.o when generating shared objects/PIEs.
Finally, common linking order:
General linking order:
crt1.o crti.o crtbegin.o [-L paths] [user objects] [gcc libs]
[C libs] [gcc libs] crtend.o crtn.o
How does the linker know which archives to link together?
we could get the last line from the output which generates the ELF binary
That in fact isn't the actual command that generates the ELF binary. collect
in turn invokes ld
, and that command generates the binary.
how does the linker know that these files should be linked
It doesn't. GCC told it (by supplying them on command line).
GCC has a compiled-in specs
file, which is a domain-specific language little program, that tells GCC what arguments it should supply to the linker.
You can examine the built-in specs
with gcc -dumpspecs
. You will see that the program is actually quite complicated, and that crtbegin.o
is only used when -static
and -pie
or -shared
are not. The -shared
implies crtbeginS.o
, and -static
implies crtbeginT.o
.
if I don't want to use the standard C library
Use -nostdlib
flag in that case.
given a directory of object files that contain the definitions of these functions, how to know the files that are needed to pass to the linker
The ones that define functions that you use. This might help.
What does start address mean for dynamic library?
Just as in a program, the start address (a.k.a entry point address) of a shared library is simply
the start address of the .text
segment, containing all the executable
code.
Here's a toy shared library too illustrate:
foo.c
#include <stdio.h>
void foo(void)
{
printf(__func__);
}
Compile and link:
$ gcc -Wall -Wextra -fPIC -c foo.c
$ gcc -shared -o libfoo.so foo.o -Wl,-Map=libfoo.map
Let's see its start address:
$ objdump -f libfoo.so
libfoo.so: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000000530
We requested a linker map file, libfoo.map
, when we linked the SO. Here's
the .text
section from that map file:
.text 0x0000000000000530 0xf2
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
.text 0x0000000000000530 0x0 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
.text 0x0000000000000530 0xda /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
.text 0x000000000000060a 0x18 foo.o
0x000000000000060a foo
.text 0x0000000000000622 0x0 /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
.text 0x0000000000000622 0x0 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
*(.gnu.warning)
As per objdump
, it starts at address 0x530. It is 0xf2 bytes long. From the five
files that the linker loaded:
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
foo.o
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
The input .text
section of crti.o
was empty and contributed 0 bytes.
Then crtbeginS.o
contributed 0xda bytes, but no symbols. Then foo.o
contributed 0x18 bytes at address 0x60a, including the symbol foo
. ThencrtendS.o
and crtn.o
each contributed 0 bytes. 0xda + 0x18 = 0xf2. (The
files that had empty .text
sections will have contributed something to
other output sections, not shown).
So, at the start address of the library we find the code crtbeginS.o
,
which is C runtime initialization code - the shared library version -
for finding global constructor functions (i.e. constructors of any C++
global objects or C functions qualified
with __attribute((constructor))
). See this question and answer.
In summary, the start address of the shared library enters that library's contribution
to the runtime initialization of the program with which it is dynamically linked.
Trouble building gcc on 64bit RHEL5
It seems your folder /foo/lib/gcc/x86_64-unknown-linux-gnu/lib64 where libgcc_s.so is not included. For the sake of experiment do this:
gcc-4.0 -v t.cc -L/foo/lib/gcc/x86_64-unknown-linux-gnu/lib64
Why are there multiple libgcc.a shipped with android NDK, which one should be used to link with?
thumb
refers to the instruction set (most ARM processors have different runtime-switchable operating modes that give you different instruction sets). Non-thumb presumably meansarm
.hard
refers to an ABI-variant determining how floating-point arguments are passed to functions (this is now deprecated AFAIK).- The libraries not having
armv7-a
in the path are presumably for the now-deprecatedarmeabi
(i.e. ARMv5TE).
ld: cannot find crt1.o: No such file or directory
Just try a simple puts("Hello world") compiling with cc hello.c (no other options). If still have same issue most likely your toolchain is wrongly installed, else, check the linker options, may you are setting to not find standard libraries.
Hope it helps.
Related Topics
Execute a Process from Memory Within Another Process
Segmentation Fault When Sending Struct Having Std::Vector Member
Building Glew on Windows with Mingw
End of File(Eof) of Standard Input Stream (Stdin)
How to Read/Write Arbitrary Bits in C/C++
How Are Iterators and Pointers Related
How to Initialize a Const Field in Constructor
Using Float Gives "Call to Overloaded Function Is Ambiguous" Error
Detecting CPU Architecture Compile-Time
Difference Between Try-Catch Syntax for Function
How to Force Linker to Use Shared Library Instead of Static Library
Missing Lboost_Thread-Mt in Mongodb Cpp Driver (Ubuntu Server X64)
Is String::C_Str() No Longer Null Terminated in C++11
In Which Order Should Floats Be Added to Get the Most Precise Result
What Expressions Yield a Reference Type When Decltype Is Applied to Them