How to link 2 files with different starting addresses with ld - gcc

I am trying to build a small os. I have an asm file that puts the processor in 64 bit mode with paging enabled. After this, i am jumping to my C code. I want the C code and asm code to be linked into the same file but the C code to have base address at 0xFFFFFF8000000000 and the asm file at 0x5000. How can I do this with ld.
This is what I have so far:
nasm -f elf64 os_init.asm -o ../bin/os_init.o
gcc -c -Os -nostdlib -nostartfiles -nodefaultlibs -fno-builtin vga/*.c utils/*.c *.c memory_management/*.c
ld -Ttext 0x5000 ../bin/os_init.o *.o -o ../bin/kernel.out
objcopy -S -O binary ../bin/kernel.out ../bin/kernel.bin
Currently both files are linked at 0x5000

Related

MinGW compilation "file not recognized: File format not recognized"

I'm trying to compile a c++ program and I am having some issues. In particular, when I use x86_64-w64-mingw32-gcc as my compiler, it complains half way through my compilation saying "tmp/src/libfastms/solver/solver.cpp.o: file not recognized: File format not recognized".
Here is my makefile (not mine, I'm trying to adapt this makefile to a cygwin environment) https://pastebin.com/vgnVYJUL
Here is the console output when I run make:
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/solver/solver.cpp.o src/libfastms/solver/solver.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/solver/solver_base.cpp.o src/libfastms/solver/solver_base.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/solver/solver_host.cpp.o src/libfastms/solver/solver_host.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/util/has_cuda.cpp.o src/libfastms/util/has_cuda.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/util/image_mat.cpp.o src/libfastms/util/image_mat.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
ld -r -o tmp/src/libfastms/libfastms.o tmp/src/libfastms/solver/solver.cpp.o tmp/src/libfastms/solver/solver_base.cpp.o tmp/src/libfastms/solver/solver_host.cpp.o tmp/src/libfastms/util/has_cuda.cpp.o tmp/src/libfastms/util/image_mat.cpp.o
tmp/src/libfastms/solver/solver.cpp.o: file not recognized: File format not recognized
Makefile:167: recipe for target 'tmp/src/libfastms/libfastms.o' failed
make: *** [tmp/src/libfastms/libfastms.o] Error 1
Some other notes:
I don't have this problem when I compile with g++ (only seems to be minGW)
A common solution to this problem is to clean the directory of residual object files. This does not work.
Another common reason for this is trying to compile .h files. Obviously I am not doing this.
Thanks in advance.
You are compiling your object files with a 64-bit compiler driver, w64-mingw32-gcc,
and with -m64 you are explicitly directing it to generate 64-bit code (unnecessarily,
as that is its default). But you are linking with a 32-bit linker that does not
understand 64-bit object files.
This is happening because in your makefile you are, unusually, invoking ld
explicitly for your incremental solver linkage:
COMMAND_LINK_SOLVER=ld -r -o $# $^
rather than delegating linkage to your compiler driver in the usual way, and
a 32-bit ld from a different toolchain is being found in your PATH before
the 64-bit one belonging to your mingw-w64 toolchain.
To avoid this, invoke the linker via the compiler driver as normal, which for your
solver linkage means:
COMMAND_LINK_SOLVER=$(GXX) -Wl,-r -o $# $^
You can depend on w64-mingw32-gcc to invoke the ld that was installed with it.
There is no need to correct your main linkage as it is already done the right way.

How to get gcc LTO work with library archives?

gcc experts,
I'm trying to use gcc lto with library archives, as the gcc comes with my system (RedHat Enterprise Linux 5.7) doesn't work with -flto (neither for my Ubuntu 14.10), so I build binutils && gcc from scratch.
Here is what I did:
1. Build binutils-2.22 with --enable-plugins
2. Build gcc-4.7.2 with --with-plugin-ld=/path/to/ld/built/in/step1 --enable-lto
3. Then for the following simple test:
// 1.c:
int foo(void)
{ return 0; }
// 2.c:
extern int foo(void)
int main(void)
{ return foo(); }
The following can get foo() inlined:
my_gcc -O3 -flto -c -o 1.o 1.c
my_gcc -O3 -flto -c -o 2.o 2.c
my_gcc -O3 -flto -o a.out 1.o 2.o
While the following can't:
my_gcc -O3 -flto -c -o 1.o 1.c
my_gcc -O3 -flto -c -o 2.o 2.c
my_ar cr --plugin <my_gcc>/libexec/gcc/x86_64-redhat-linux/4.7.2/liblto_plugin.so 1.a 1.o
my_ar cr --plugin <my_gcc>/libexec/gcc/x86_64-redhat-linux/4.7.2/liblto_plugin.so 2.a 2.o
gcc -O3 -flto -fuse-linker-plugin -o a.out 1.a 2.a
As the building system for the product I'm working on has to use archives, then what I can do to let lto work with library archive?
Your help will be much much appreciated.
Thanks a lot.
When linking, the order in which the libraries are listed on the command line, matters. So when compiling from the archives, you should swap 1.a and 2.a:
gcc -O3 -flto -fuse-linker-plugin -o a.out 2.a 1.a
I tested with gcc 4.9.2 and the disassembly, obtained with objdump -d a.out, shows that foo() is being inlined.

Compiling kernel, ld doesn't have the -T option

I made a custom bash script for assembling, compiling, and linking the kernel but when it gets to the line for linking i run into an error (see below). Im running this on OSX, newest build so im not sure why. Any suggestions?
ld: unknown option: -T
My script:
echo Now assembling, compiling, and linking your kernel:
nasm -f aout -o start.o start.asm
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno- builtin -I./include -c -o main.o main.c
ld -T link.ld -o kernel.bin start.o
echo Done!
Before you try to create your own build scripts, have you managed to get the OSX kernel to build with its own scripts? This site by one of Apple's kernel engineers tells you how it's done.

GCC suppress flags

I'm trying to create a shared library with my gcc. It's a gcc for vxworks (thats probably the problem...).
I use the gcc as following:
./gcc -shared -B/path/to/gnutools/bin -o test.so test.c
Result:
/path/to/ld: -r and -shared may not be used together
collect2: ld returned 1 exit status
If I try the same with the linux gcc, there's no problem. So i guess the gcc for VxWorks automatically passes the -r (or -i, which is the same and results in the same) flag to the linker. Is there a way to suppress this?
Greetz
marty
PS: making it static is not really an alternative...
Try compile object file separately with -fPIC and then link:
gcc -Wall -fPIC -c -o test.o test.c
gcc -Wall -shared -o test.so test.o
Another suggestion is to use libtool (at least to figure out the correct flags).
A workaround may be to go directly with ld:
ld -shared -o test.so test.o -lc

combine two GCC compiled .o object files into a third .o file

How does one combine two GCC compiled .o object files into a third .o file?
$ gcc -c a.c -o a.o
$ gcc -c b.c -o b.o
$ ??? a.o b.o -o c.o
$ gcc c.o other.o -o executable
If you have access to the source files the -combine GCC flag will merge the source files before compilation:
$ gcc -c -combine a.c b.c -o c.o
However this only works for source files, and GCC does not accept .o files as input for this command.
Normally, linking .o files does not work properly, as you cannot use the output of the linker as input for it. The result is a shared library and is not linked statically into the resulting executable.
$ gcc -shared a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable
./executable: error while loading shared libraries: c.o: cannot open shared object file: No such file or directory
$ file c.o
c.o: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Passing -relocatable or -r to ld will create an object that is suitable as input of ld.
$ ld -relocatable a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable
The generated file is of the same type as the original .o files.
$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
$ file c.o
c.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
For an in-depth explanation see MaskRay's Relocatable linking article.
If you want to create an archive of two or more .o files (i.e.. a static library) use the ar command:
ar rvs mylib.a file1.o file2.o

Resources