Undefined reference to printf when using GCC cross compiler - c

I'm trying to get the following simple 'Hello World' program to compile using a cross compiler (GCC 4.9.2) targeting mips:
#include <stdio.h>
int main()
{
int x = 5;
printf("x = %d\n", x);
}
The x variable is there to stop GCC changing printf to puts, which it seems to do automatically for a simple newline-terminated string.
I've built a cross compiler under ${HOME}/xc and am executing it using the following command:
${HOME}/xc/bin/mips-gcc -v hello.c
However, I'm getting the following error:
/tmp/ccW5mHJu.o: In function `main':
(.text+0x24): undefined reference to `printf'
collect2: error: ld returned 1 exit status
I'm assuming this is a problem with the linker, as I'd expect the process to fail earlier if for example stdio.h couldn't be found on the search path. I can compile a simpler program which simply returns zero, so it's not the case that the entire toolchain is broken, presumably just the standard library linking (I'm using newlib 2.2.0-1).
I get the same error regardless of whether I run the cross compiler under Linux (Ubuntu 14.10) or Cygwin (Windows 8).
The full output from GCC is:
Using built-in specs.
COLLECT_GCC=/home/paul/xc/bin/mips-gcc
COLLECT_LTO_WRAPPER=/home/paul/xc/libexec/gcc/mips/4.9.2/lto-wrapper
Target: mips
Configured with: /home/paul/xc/mips/tmp/gcc-4.9.2/configure --prefix=/home/paul/xc --target=mips --enable-languages=c --with-newlib --without-isl --without-cloogs --disable-threads --disable-libssp --disable-libgomp --disable-libmudflap
Thread model: single
gcc version 4.9.2 (GCC)
COLLECT_GCC_OPTIONS='-v'
/home/paul/xc/libexec/gcc/mips/4.9.2/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -auxbase hello -version -o /tmp/ccCpAajQ.s
GNU C (GCC) version 4.9.2 (mips)
compiled by GNU C version 4.9.1, GMP version 6.0.0, MPFR version 3.1.2, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/sys-include"
#include "..." search starts here:
#include <...> search starts here:
/home/paul/xc/lib/gcc/mips/4.9.2/include
/home/paul/xc/lib/gcc/mips/4.9.2/include-fixed
/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/include
End of search list.
GNU C (GCC) version 4.9.2 (mips)
compiled by GNU C version 4.9.1, GMP version 6.0.0, MPFR version 3.1.2, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: cffaaedf0b24662e67a5d97387fc5b17
COLLECT_GCC_OPTIONS='-v'
/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/as -EB -O1 -no-mdebug -mabi=32 -o /tmp/ccW5mHJu.o /tmp/ccCpAajQ.s
COMPILER_PATH=/home/paul/xc/libexec/gcc/mips/4.9.2/:/home/paul/xc/libexec/gcc/mips/4.9.2/:/home/paul/xc/libexec/gcc/mips/:/home/paul/xc/lib/gcc/mips/4.9.2/:/home/paul/xc/lib/gcc/mips/:/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/
LIBRARY_PATH=/home/paul/xc/lib/gcc/mips/4.9.2/:/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/lib/
COLLECT_GCC_OPTIONS='-v'
/home/paul/xc/libexec/gcc/mips/4.9.2/collect2 -plugin /home/paul/xc/libexec/gcc/mips/4.9.2/liblto_plugin.so -plugin-opt=/home/paul/xc/libexec/gcc/mips/4.9.2/lto-wrapper -plugin-opt=-fresolution=/tmp/cc8TAJb9.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -EB /home/paul/xc/lib/gcc/mips/4.9.2/crti.o /home/paul/xc/lib/gcc/mips/4.9.2/crtbegin.o -L/home/paul/xc/lib/gcc/mips/4.9.2 -L/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/lib /tmp/ccW5mHJu.o -lgcc -lgcc /home/paul/xc/lib/gcc/mips/4.9.2/crtend.o /home/paul/xc/lib/gcc/mips/4.9.2/crtn.o
/home/paul/xc/lib/gcc/mips/4.9.2/../../../../mips/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400050
/tmp/ccW5mHJu.o: In function `main':
(.text+0x24): undefined reference to `printf'
collect2: error: ld returned 1 exit status
The build script I'm using is here (I wrote it based on half a dozen tutorials which all suggested slightly different things):
https://github.com/UoMCS/mips-cross-compile
Basically it does the following steps:
Build binutils.
Build GCC (stage 1).
Build newlib.
Build GCC (stage 2).
I'm aware that there are other tools such as crosstool-ng and builtroot, however the person I'm building this toolchain for wants to edit parts of binutils before setting off the build process, and the toolchain also has to work under Cygwin (crosstool-ng won't for various reasons, including case-sensitive file paths).
I think this is probably going to be something obvious, but I've been messing around with this for a week and can't see what it could be. Any help would be greatly appreciated!

It is necessary to build libraries to go with your cross compiler. In particular, you need to have a cross-compiled version of glibc or some other implementation of the standard library, to get a version of printf().
Have a look at this link for an example of the type of things you need to consider to get all the things you need - the cross-compiler, the headers, and libraries.

Try linking the library on the command line:
${HOME}/xc/bin/mips-gcc -v hello.c -lib
Including the std libraries (lib and io)header links the implementations by default (libc.so or .a). However, you are using a 'user-defined' implementation and may not be linking the proper one.
I suggest explicit linkage on the command line. I'm not certain of the syntax.
EDIT:
Or better Still, use a makefile to compile with the following lines, and specifying other include directories in the INCLUDES place holder:
CC = gcc
CXX = g++
INCLUDES =
CFLAGS = -g -Wall $(INCLUDES)
CXXFLAGS = -g -Wall $(INCLUDES)
LDFLAGS = -g
hello: hello.o newlib.o
hello.o: hello.c newlib.h
newlib.o: newlib.c newlib.h
newlib.h is the header file you'll include in newlib.c (implementation/definition) source file (that declares the functions) and hello.c. It may be named differently from stdio.h.
Check this out, it may help:
Why do you have to link the math library in C?
and this too:
http://www.tldp.org/HOWTO/Glibc2-HOWTO-6.html

A custom specs file could work:
cd /home/paul/xc/lib/gcc/mips/4.9.2/
${HOME}/xc/bin/mips-gcc -dumpspecs > specs
Add to the specs file:
*lib:
-lc
Note that there must be empty lines before *lib: and after -lc. Perhaps you have to change the library name to the name of your newlib-c-library. Perhaps more must be added than only -lc, e.g. the *lib:-section on my Linux looks more complex.
UPDATE: The builtin specs lib for the default libraries are configured here:
In file gcc-4.9.2/gcc/gcc.c lines 527-530:
/* config.h can define LIB_SPEC to override the default libraries. */
#ifndef LIB_SPEC
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
#endif
In file gcc-4.9.2/gcc/config/mips/elf.h lines 40-42:
/* Leave the linker script to choose the appropriate libraries. */
#undef LIB_SPEC
#define LIB_SPEC ""
Perhaps the default LIB_SPEC in gcc.c works for you by commenting out lines 40-42 in elf.h.
Perhaps you need to edit elf.h and replace the empty LIB_SPEC with "-lc" or something similar.
UPDATE: When you configured gcc you gave --target=mips. In gcc-4.9.2\gcc\config.gcc there are other mips-targets which are more specific, e.g.mips*-*-linux*, perhaps selecting the appropriate one gives the right LIB_SPEC and linking will be successful.
UPDATE: big endian Linux target: mips-unknown-linux-gnu little endian Linux target: mipsel-unknown-linux-gnu source
UPDATE: Using your build script I was able to link your sample program with following modifications:
In your config.sh:
export ISL_VERSION="0.12.2"
In file gcc-4.9.2/gcc/config/mips/elf.h lines 40-42:
/* Leave the linker script to choose the appropriate libraries. */
#undef LIB_SPEC
#define LIB_SPEC "-lc -lcfe -lc"
If you don't want the modification in elf.h the libraries must be given when invoking mips-gcc.
UPDATE:
newlib doesn't work at all, GCC fails in the second stage with an error about not being able to find crti.o etc.
Strange, using your build script crti.o was created:
[osboxes#osboxes 4.9.2]$ pwd
/home/osboxes/xc/lib/gcc/mips/4.9.2
[osboxes#osboxes 4.9.2]$ ll
total 6240
-rw-r--r--. 1 osboxes osboxes 3248 May 16 19:49 crtbegin.o
-rw-r--r--. 1 osboxes osboxes 1924 May 16 19:49 crtend.o
-rw-r--r--. 1 osboxes osboxes 1040 May 16 19:49 crti.o
-rw-r--r--. 1 osboxes osboxes 1056 May 16 19:49 crtn.o
drwxrwxr-x. 3 osboxes osboxes 4096 May 16 19:49 include
drwxrwxr-x. 2 osboxes osboxes 4096 May 16 19:45 include-fixed
drwxrwxr-x. 3 osboxes osboxes 4096 May 16 19:49 install-tools
-rw-r--r--. 1 osboxes osboxes 6289352 May 16 19:49 libgcc.a
-rw-r--r--. 1 osboxes osboxes 56844 May 16 19:49 libgcov.a
drwxrwxr-x. 3 osboxes osboxes 4096 May 16 19:49 plugin
-rw-rw-r--. 1 osboxes osboxes 6215 May 18 18:45 specs

printf() was implemented in libc,
Please check your c lib, such as glibc, oh, yours is newlib.
try #4566976 's way
use readelf -s check is there a printf section exists in libc.so libc.a
( i'm not sure the lib filename in newlib, mine is glibc )

The most convenient way to achieve this is to use putchar in place of printf. May be you have to change some of your code, or may be you have to add macros/functions that may run like printf.

Related

Size of Shared Object files is huge

I compare three compilers:
GCC (x86) from Debian (6.3.0) produces hugo_x86.so with 7.8K,
GCC (ppc) from Codesourcery (4.6.0) produces hugo_46.so with 6.6K,
GCC (x86) from Buildroot 2017.08 (7.2.0) produces hugo.so with 7.5K,
GCC (ppc) from Buildroot 2017.08 (7.2.0) produces hugo.so with 67K,
GCC (ppc) from Buildroot 2017.08 (6.4.0) produces hugo.so with 67K and
GCC (ppc) from Buildroot 2017.08 (4.9.4) produces hugo.so with 67K
The code was taken from eli.thegreenplace.net:
int myglob = 42;
int ml_func(int a, int b)
{
myglob += a;
return b + myglob;
}
I ve compiled all sources like this:
powerpc-linux-gcc -c -o hugo.o hugo.c
powerpc-linux-gcc --shared -o hugo.so hugo.o
The difference between the files seems to be a padding (hexdump hugo.so | wc -l):
Debian (6.3.0): 381 lines
Codesourcery (4.6.0): 283 lines
Buildroot 2017.08 (7.2.0): 298 lines
Buildroot 2017.08 (6.4.0): 294 lines
(objdump -s shows a similar result)
Questions:
How can I analyze the difference in the Object file best? (objdump, readelf, etc)
How can I analyze the difference (e.g. default options) of the compiler best? (e.g. -dumpspecs)
What could be the reason, for blowing up the shared object? How to increase the file size?
Thanks!
--
Edit:
It is also independent of the GCC specs. I ve dumped (-dumpspec) the spec of the Codesourcery (4.6.0) GCC which produces a small shared object, and used it with the Buildroot GCC (-specs) and got again a 67K shared object.
from How to reduce ELF section padding?:
It looks like this is due to binutils 2.27 increasing the default page size of PowerPC targets to 64k, resulting in bloated binaries on embedded platforms.
There's a discussion on the crosstool-NG github here.
Configuring binutils with --disable-relro should improve things.
You can also add -Wl,-z,max-page-size=0x1000 to gcc when compiling.
When adding BR2_BINUTILS_EXTRA_CONFIG_OPTIONS="--disable-relro" to my buildroot configuration, the share object size is reduced.

gcc not finding files in dir specified with -I

I need to include some platform specific jni files in the following dir:
$ ls -l /home/ubuntu/jdk8/include/linux
total 8
-rw-r--r-- 1 ubuntu ubuntu 995 Mar 15 09:00 jawt_md.h
-rw-r--r-- 1 ubuntu ubuntu 824 Mar 15 09:00 jni_md.h
So the gcc command was appropriately (?) augmented:
gcc -I"/home/ubuntu/jdk8/include/linux" -I"$JAVA_HOME/include" ..
But the files inside the linux subdir are not found:
gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4)
COLLECT_GCC_OPTIONS='-I' '"/home/ubuntu/jdk8/include/linux"' '-I' '/home/ubuntu/jdk8/include' ..
/home/ubuntu/jdk8/include/jni.h:45:20: fatal error: jni_md.h: No such file or directory
So what needs to be tweaked here? If it matters this is on ubuntu16.0.4` and
gcc --version
gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Update Here is the inclusion statement in jni.h
#include "jni_md.h"
Now how can they expect that to be found - should it not be
#include <jni_md.h>
Update on the update Per Arkadiusz Drabczyk and a link he provided http://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html they should both be OK. In fact the behavior appears to be the same.
Note if I copy the files under include/linux/*.h to the parent include dir the compilation work: so the only problem is the include path.
YAU (Yet another update) Per Arkadiusz I tried out clang: same error.
It's possible, but unlikely, that it needs a trailing slash on the directory string. Is jni.h including <jni_md.h> or "jni_md.h" ??
Turns out the order of the options was messing up: I had
-I<something> -odmaserver.so -I<something else>
It needs to be
-I<something> -I<something else> -odmaserver.so

gcc link the shared library in specified path but not in the standard path

I came across a strange issue when using gcc to link the shared library in specified path but not in the standard path.
When I downloaded GNU readline library version 6.3 and compiled it successfully in path $HOME/Downloads.
GNU readline library needs to link libtinfo, so I installed it by sudo apt-get install libtinfo.
After that, I created a small sample test named rl.c to check it. To build my sample project, I also created two symbolic links like follow:
$ ls -lrt ~/Downloads/
drwxr-xr-x 6 sfzhang sfzhang 4096 Mar 2 15:45 readline-6.3
lrwxrwxrwx 1 sfzhang sfzhang 12 Mar 2 16:00 readline -> readline-6.3
$ ls -lrt ~/Downloads/readline-6.3/shlib/
-rwxr-xr-x 1 sfzhang sfzhang 833856 Mar 2 15:36 libreadline.so.6.3
lrwxrwxrwx 1 sfzhang sfzhang 18 Mar 2 16:28 libreadline.so -> libreadline.so.6.3
To use the new built readline library, I export the path to LD_LIBRARY_PATH:
$ echo $LD_LIBRARY_PATH
/home/sfzhang/Downloads/readline/shlib
And, I compiled rl.c using the following command:
$ gcc -o rl rl.c -I$HOME/Downloads -L$HOME/Downloads/readline/shlib -lreadline -ltinfo
Checking the rl linked libraries:
$ ldd rl
linux-vdso.so.1 => (0x00007fffe09a3000)
libreadline.so.6 => /lib/x86_64-linux-gnu/libreadline.so.6 (0x00007fe22d243000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fe22d01a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe22cc8d000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe22d492000)
I also tried anther command, but got the same result:
gcc -o rl rl.c -I$HOME/Downloads -L$HOME/Downloads/readline/shlib -lreadline -ltinfo -Wl,-rpath,$HOME/Downloads/readline/shlib
So, why the rl was liked to /lib/x86_64-linux-gnu/libreadline.so.6 but not $HOME/Downloads/readline/shlib/libreadline.so.
OS: Linux debian 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u1 x86_64 GNU/Linux
gcc: gcc version 4.7.2 (Debian 4.7.2-5)
ldd: ldd (Debian EGLIBC 2.13-38+deb7u6) 2.13
You need a symbolic link called libreadline.so.6 too, not just libreadline.so. The reason is that the soname of libreadline.so.6.3 is libreadline.so.6.
A soname is a "generic" name embedded in the library itself. When you link against a shared library that has a soname, it is that name that gets embedded in your executable and is later looked up by the dynamic linker. (For shared libraries without sonames the filename is used instead, though this is uncommon.) You can tell what the soname of a library is by running e.g.
objdump -p <library> | grep SONAME
The point of sonames is to make it so that your executable is linked against the most generic library name that should be compatible (usually this is the library name with just the major version -- 6 in this case -- tacked on), rather than just the specific (e.g., minor bug fix release) version that you happened to link against.
The output from ldd also tells you that it's looking specifically for libreadline.so.6.
If you really want a path to a library to be hardcoded in the executable, you will need to pass the following to gcc:
-Wl,-rpath=$HOME/Downloads/readline/shlib
setting custom LD_LIBRARY_PATH is not recommended, if you want to use it, use it as a parameter for execution.
LD_LIBRARY_PATH=$HOME/Downloads/readline/shlib ./rc
The are alternative ways to fix your issue:
Link against full path to the .so. E.g.
$ gcc -o rl rl.c -I$HOME/Downloads $HOME/Downloads/readline/shlib/readline.so.6.3 -ltinfo
And as #Ulfalizer suggests, you may need another symbolic link with just the major number.
If you are using LD_LIBRARY_PATH do not forget to export it.
When using -L<path> also use -Wl,-rpath,<path>, so that runtime linker ld.so.2 finds the shared library in the same path as ld does, e.g:
$ gcc -o rl rl.c -I$HOME/Downloads -L$HOME/Downloads/readline/shlib -Wl,-rpath,$HOME/Downloads/readline/shlib -lreadline -ltinfo
When debugging linker issues use readelf -d <binary> command to see which exact versions of shared libraries <binary> needs (NEEDED attribute) and where it looks for them (RPATH attribute) prior to looking in the standard linker directories (configuration in /etc/ld.so.conf/).

Compiling simple C program does not link properly

I'm trying to compile a simple C program, but apparently the program is not linking properly.
hello.c
/* Simple C program. */
#include<stdio.h>
int main() {
printf("Hello MIPS! \n");
return 0;
}
I am trying to compile the program with the following command, mips-gcc -v hello.c -o hello
The output I'm getting when I try to compile / link the program,
Using built-in specs.
COLLECT_GCC=bin/mips-gcc
COLLECT_LTO_WRAPPER=/opt/cross/gcc-mips/libexec/gcc/mips/4.8.2/lto-wrapper
Target: mips
Configured with: ../gcc-4.8.2/configure --target=mips --prefix=/opt/cross/gcc-mips --enable-interwork --enable-multilib --enable-languages=c --with-newlib --with-headers=/opt/cross/src/newlib-2.1.0/newlib/libc/include/ --disable-libssp --disable-nls
Thread model: single
gcc version 4.8.2 (GCC)
COLLECT_GCC_OPTIONS='-v' '-o' 'hello'
/opt/cross/gcc-mips/libexec/gcc/mips/4.8.2/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -auxbase hello -version -o /var/folders/1z/k_by6wd95tsccc6s1_tkttpr0000gn/T//ccqPwmTq.s
GNU C (GCC) version 4.8.2 (mips)
compiled by GNU C version 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.38), GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
#include "..." search starts here:
#include <...> search starts here:
/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/include
/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/include-fixed
/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/../../../../mips/sys-include
/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/../../../../mips/include
End of search list.
GNU C (GCC) version 4.8.2 (mips)
compiled by GNU C version 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.38), GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: e28a4def2fba399e5af333f18f473404
COLLECT_GCC_OPTIONS='-v' '-o' 'hello'
/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/../../../../mips/bin/as -EB -O1 -no-mdebug -mabi=32 -o /var/folders/1z/k_by6wd95tsccc6s1_tkttpr0000gn/T//ccgd49A6.o /var/folders/1z/k_by6wd95tsccc6s1_tkttpr0000gn/T//ccqPwmTq.s
COMPILER_PATH=/opt/cross/gcc-mips/libexec/gcc/mips/4.8.2/:/opt/cross/gcc-mips/libexec/gcc/mips/4.8.2/:/opt/cross/gcc-mips/libexec/gcc/mips/:/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/:/opt/cross/gcc-mips/lib/gcc/mips/:/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/../../../../mips/bin/
LIBRARY_PATH=/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/:/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/../../../../mips/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'hello'
/opt/cross/gcc-mips/libexec/gcc/mips/4.8.2/collect2 -EB -o hello /opt/cross/gcc-mips/lib/gcc/mips/4.8.2/crti.o /opt/cross/gcc-mips/lib/gcc/mips/4.8.2/crtbegin.o -L/opt/cross/gcc-mips/lib/gcc/mips/4.8.2 -L/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/../../../../mips/lib /var/folders/1z/k_by6wd95tsccc6s1_tkttpr0000gn/T//ccgd49A6.o -lgcc -lgcc /opt/cross/gcc-mips/lib/gcc/mips/4.8.2/crtend.o /opt/cross/gcc-mips/lib/gcc/mips/4.8.2/crtn.o
/opt/cross/gcc-mips/lib/gcc/mips/4.8.2/../../../../mips/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400038
/var/folders/1z/k_by6wd95tsccc6s1_tkttpr0000gn/T//ccgd49A6.o: In function `main':
(.text+0x18): undefined reference to `puts'
collect2: error: ld returned 1 exit status
Stop passing -v; it just produces a crazy amount of debug output that doesn't relate to your problem.
mips-gcc -o hello hello.c produces something like
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400038
ccgd49A6.o: In function `main': (.text+0x18): undefined reference to `puts'
The second error indicates that you need -lc on the end of your command line to pull in the libc library (which provides puts). The first error indicates that you also need a crt0.o from somewhere (to provide _start). In other words, you're invoking the compiler in some kind of "bare-metal" mode, where it assumes you're writing code to run directly on the machine instead of in a hosted C environment (where you'd have access to command-line arguments, and a standard library, and a filesystem, and so on).
Your problem seems similar to this guy's in 2006: http://osdir.com/ml/lib.newlib/2006-07/msg00029.html
The solution there was to use -T nullmon.ld to specify a linker directive file that included crt0.o; and also perhaps to use mips-elf-gcc instead of mips-gcc.
However, programming for bare metal usually requires that you start very low-level and not try anything as complicated as C until you've already gotten familiar with assembly. See the answers to Bare metal cross compilers input for more information (and it even talks specifically about MIPS!).

Manually compile using gcc -v

Is it possible to compile a simple Hello World program that only uses provided gcc/glibc files rather than using the default ones provided by the OS ? (Therefore, when executed, the program will only use the provided files rather than the ones the OS provides.) I've looked everywhere on the net but cannot get any to work:
I tried to manually do what this does gcc -v simple.c but I cannot reproduce it myself.
This is what I tried: (all provided files are on the Desktop)
/home/myuser/Desktop/cc1 -quiet -v simple.c -quiet -dumpbase simple.c -mtune=generic -auxbase simple -version -o /tmp/temp1.s
How can the below paths be changed to custom ones rather than default ones ?
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include search starts here:
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
GNU C (Debian 4.4.5-8) version 4.4.5 (x86_64-linux-gnu)
compiled by GNU C version 4.4.5, GMP version 4.3.2, MPFR version 3.0.0-p3.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: dac4d891d068d1bed01868869b00bd17
as -V -Qy -o /tmp/temp2.o /tmp/temp1.s
GNU assembler version 2.20.1 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.20.1-system.20100303
/home/myuser/Desktop/collect2 --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker ld-2.11.2.so crt1.o crti.o crtbegin.o /tmp/temp2.o libgcc.a --as-needed libgcc_s.so.1 --no-as-needed libc.a libgcc_s.so.1 --as-needed libgcc.a --no-as-needed crtend.o crtn.o
Why is the below /usr/bin/ld used instead of the provided ld-2.11.2.so ?
/usr/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: ld returned 1 exit status
Can anybody modify it to work ?
-v shows you the actions performed by the compiler driver. It does not affect what standard libraries you get.
To run with all custom libraries, use -nostdlib.
How can the below paths be changed to
custom ones rather than default ones ?
Simply add -I path to the compiler call. This path will be added before the internal paths.
Why is the below /usr/bin/ld used
instead of the provided ld-2.11.2.so ?
The first one is an executable binary, the second one is a shared object. You can't use a shared object in a place of a binary.

Resources