I am writing an OS kernel in Rust, and have reached the stage of linking said kernel to a bootloader written in Assembly. The kernel (kernel.rs) compiles fine to kernel.o using rustc with the x86_64-unknown-none target.
The problem arises when I try to link this kernel to my bootloader. I attempt to link kernel.o to kernel_enter.o (compiled from a .asm file) with the ld linker:
ld -o "full_kernel.bin" -Ttext 0x1000 "kernel_enter.o" "kernel.o" --oformat binary
and received the the following error:
ld: kernel.o: error adding symbols: file in wrong format
I have tried to build with x86_64-unknown-uefi, and with i686-unknown-uefi and the i386-elf-ld linker.
I have also read of the possibility of writing custom targets with JSON. Knowing how to do that would probably solve my problem.
Thanks.
Related
Do find out where in memory a certain variable is located I wished to create a new section next to .data and then use PROVIDE. The first step was to obtain the current linker script with ld --verbose and then use it to link with -T amd64.ld (amd64.ld is the file to which I saved the output of ld --vebose) the expectation being that I would get the same final ELF as when no linker script argument (-T) was given. However build fails with /usr/bin/ld: internal error ../../ld/ldlang.c 4986
Using gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 and GNU ld (GNU Binutils for Ubuntu) 2.30
Anyone knows how to link with the default linker script?
The root cause was that -T was given twice, i.e. -Tamd64.ld -Tamd64.ld
For example, consider that I wrote a Fortran program in one computer and want to run it on another computer which may not have required libraries and/or has a different compiler (or even better, no Fortran compiler at all). Is it possible to create an executable with all its dependencies?
I am using gfortran (7.2.1) in Fedora 26 and sometimes use LAPACK routines in my code.
Using -static option with the program
program main
write (*,*) 'Hello'
end
I get the output
gfortran -static a.f90
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
There is no error with gfortran -static-libgfortran a.f90
In Fedora, gcc does not ship by default with static libraries.
You need to install the package glibc-static for the -static option to work, as hinted in this related question.
Note that -static-libgfortran will only do static linking of the libgfortran library and that you must have static versions of your dependencies as well.
The best option is to use Alpine Linux that uses musl libc. I highly recommend using the docker image (only 5 Mb).
i am trying to build a custom version of the linux kernel 3.8 and i want my linker to behave a bit different so i changed its ldscripts.
Specifically I configure binutils -> make -> change ldscripts -> make install.
However when i try to compile libc using my linker the only thing i see is this :
GNU ld (GNU Binutils) 2.23
Supported emulations:
elf32_sparc
sparclinux
elf64_sparc
sun4
using internal linker script:
==================================================
/* Script for --shared -z combreloc: shared library, combine & sort relocs */
etc
The thing is that i have changed my ldscripts and prepended a tag at the beginning of each script in order to recognize them but my compiler does not seem to care.
However i don't have any other elf scripts in my system so the option of searching the wrong library path is not actually an option.
Is there something i am missing here?
Notice that i am cross compiling for sparc
You can pass a custom linker script to ld:
ld -T <path/to/file> ...
or to gcc:
gcc -Wl,-T,<path/tofile> ...
Default ld scripts get compiled into compiler driver (gcc) so you should at least rebuild the toolchain.
That's also probably the case that gcc will not look at any linker scripts other than built into it, so you'll have to modify them in toolchain (it's probably in spec files somewhere).
I make a very simple program hello in C. When use ld in the exe file returns this
ld: error in hello(.eh_frame); no .eh_frame_hdr table will be created.
I don't define any LD_LIBRAY_PATH or paths in /etc/ld.so.conf I've tried the same with the ls and returns:
ld: error in /bin/ls(.eh_frame); no .eh_frame_hdr table will be created.
ld: warning: cannot find entry symbol _start; defaulting to 0000000000402920
What's happening? I'm using a Debian and my GCC version is (Debian 4.7.2-5).
I believe the utility you meant to use was ldd (LDD), not ld.
ldd will show all the shared linked libraries your exe uses.. or, at least, were linked it at compile time.
I don't think you understand what ld does. ld takes "object files" (code that has been compiled but not linked, usually stored in .o files) and libraries (sets of object files collected into a single .a or .so file), and joins them to produce an executable that the operating system can run.
When you invoke ld with a single argument, it expects that argument to be an object file. In your case, you're using it on "hello" and "/bin/ls", which are executables that have already been linked, thereby producing the (admittedly confusing) error message.
I suspect that your confusion stems from the fact that when you compile your source with gcc, it will also link it with the standard library and produce an executable file (like "hello") unless you specifically tell it not to. No separate linking step is necessary.
For reference, here are the gcc manual page and the ld manual page.
I wrote a basic hello world program in haskel and tried to compile it with:
ghc filename.hs. It produces .hi and .o files but no executable and displays
this error in the linker:
marox#IT-marox:~/Marox$ ghc tupel.hs
Linking tupel ...
/usr/bin/ld: --hash-size=31: unknown option
/usr/bin/ld: use the --help option for usage information
collect2: ld returned 1 exit status
Googling didn't return any useful information.
I am on ubuntu 12.04.
How can I fix this?
Have you binutils-gold installed? If yes, this is the problem (since the gold linker does not support --hash-size AFAIK).
Possible solutions:
remove gold
your ld probably links to ld.gold, so change the symlink to ld.ld
tell the haskell compiler explicitly which linker to use with the -pgml option: ghc -pgml ld.ld tupel.hs
install ghc from source, since the configure script of ghc will then build ghc so that it won't use --hash-size
Depending on your version of ghc, you can adjust the linker settings in ghc's setting file /usr/lib/ghc-your.ghc.version/settings
Update - gold on Ubuntu 12.10 appears to move GNU ld to ld.bfd. To fix this problem I deleted the ld link as recommended and remade the link with
ln -s ld.bfd ld
ghc compilations are now going through.
(Couldn't see how to subvert the settings file in usr/lib/ghc, as the entry is for gcc which passes through its commandline to ld, although this would have been my preferred option, in case something else needs ld to be the way it was.)
Thanks to Dominic for the pointer of where to look! It was driving me crazy...