How do you solve the order problem when you link the .o file

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
benjixu
Posts: 11
Joined: Sat Oct 02, 2021 10:28 pm
Libera.chat IRC: Benji

How do you solve the order problem when you link the .o file

Post by benjixu »

I often have linking problems, when I build a project with multiple static libraries. When I am going to link the .o files. Then, I found this problem that is if I change the .o files' order, I won't correctly run this kernel. Later, I searched a lot of materials, and I found this:
On Unix-like systems, the traditional behavior of compilers and linkers
is to search for external functions from left to right in the object files
specified on the command line. This means that the object file which
contains the definition of a function should appear after any files which
call that function.

Most current compilers and linkers will search all object files, regardless
of order, but since not all compilers do this it is best to follow the
convention of ordering object files from left to right.
The link instruction are:

Code: Select all

1. ld -nostdlib -T link.lds -o kernel.elf print_amd64.o main.o kernel.o trapa.o trap.o 
2. ld -nostdlib -T link.lds -o kernel.elf kernel.o main.o trapa.o trap.o print_amd64.o

objcopy -O binary kernel.elf kernel.bin

dd if=kernel.bin of=boot.img bs=512 count=100 seek=6 conv=notrunc

qemu-system-x86_64 -cpu Skylake-Server -m 512 -hda boot.img -boot d
The first ld instruction is the right and the second one is wrong. In this case, I can certainly change this order of the .o files to make it link correctly. But I use the makefile to compile the huge system containing a lot of files. It is pretty hard to command the makefile to compile each file in order. Do you have any idea to solve this problem?
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: How do you solve the order problem when you link the .o

Post by nullplan »

So what is the problem with the second command line? You have not actually said what happens when you use it, only that it doesn't work, which isn't a problem report. But you do use objcopy to remove the ELF headers, so I am going to assume the problem is the multiboot header not getting to the right place. That's what dedicated sections are for.

The linker treats object files and static libraries specified on command line differently from each other. Object files are always linked in, object files in static libraries are only linked in if referenced by the current set of undefined symbols. The upshot is that you may have to specify the same library multiple times to resolve all dependencies, and that order of libraries matters.
Carpe diem!
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How do you solve the order problem when you link the .o

Post by iansjack »

The multiboot header or is it that the program doesn't know it's start address as the headers have been removed?
benjixu
Posts: 11
Joined: Sat Oct 02, 2021 10:28 pm
Libera.chat IRC: Benji

Re: How do you solve the order problem when you link the .o

Post by benjixu »

nullplan wrote:So what is the problem with the second command line? You have not actually said what happens when you use it, only that it doesn't work, which isn't a problem report. But you do use objcopy to remove the ELF headers, so I am going to assume the problem is the multiboot header not getting to the right place. That's what dedicated sections are for.

The linker treats object files and static libraries specified on command line differently from each other. Object files are always linked in, object files in static libraries are only linked in if referenced by the current set of undefined symbols. The upshot is that you may have to specify the same library multiple times to resolve all dependencies, and that order of libraries matters.
I am so glad that got your response. I am sorry I didn't describe it clearly. Actually, the ld can link the .o files as well, and I can got the .bin file. But after that, when I use qemu to boot the kernel, I found that I can't start it. I searched a lot of materials last night, and at this time, I end up found that this problem occurred by the enter function: start. as long as I put the kernel.o at the first, I can correctly run it in the qemu. I attached all project files here, so that you can test them by yourself. And Plus, If I use the makefile to compile all projects I can't adjust the order when I use the ld to link the files. Since it is the simplest project, When we build a big and complicated kernel, we have to compile a lot of files in each directory. So we hardly are able to arrange the order manually. Do you have an idea to solve this program?
Attachments
trap.zip
Project files
(35 KiB) Downloaded 44 times
Last edited by benjixu on Mon Oct 11, 2021 2:44 pm, edited 1 time in total.
benjixu
Posts: 11
Joined: Sat Oct 02, 2021 10:28 pm
Libera.chat IRC: Benji

Re: How do you solve the order problem when you link the .o

Post by benjixu »

iansjack wrote:The multiboot header or is it that the program doesn't know it's start address as the headers have been removed?
I guess that the CPU can't find the entrance of kernel.asm. I attach all project files here, you can test by yourself. and Plus, If I use the makefile to compile all projects I can't adjust the order when I use the ld to link the files. Since it is the simplest project, When we build a big kernel, we have to make a lot of files in each directory. So we hardly are able to arrange the order manually. Do you have an idea to solve this program?
Attachments
trap.zip
(35 KiB) Downloaded 45 times
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: How do you solve the order problem when you link the .o

Post by Octocontrabass »

Your loader jumps to address 0x200000, but you actually want it to jump to the start of the .text section from kernel.o. When you link your object files in a different order, the .text section from a different object file might end up at that address.

You can change your linker script to always put the .text section from kernel.o first, or you can come up with a new section name for the entry point in kernel.asm and change your linker script to always put that new section first.
benjixu
Posts: 11
Joined: Sat Oct 02, 2021 10:28 pm
Libera.chat IRC: Benji

Re: How do you solve the order problem when you link the .o

Post by benjixu »

Octocontrabass wrote:Your loader jumps to address 0x200000, but you actually want it to jump to the start of the .text section from kernel.o. When you link your object files in a different order, the .text section from a different object file might end up at that address.

You can change your linker script to always put the .text section from kernel.o first, or you can come up with a new section name for the entry point in kernel.asm and change your linker script to always put that new section first.
How can I alter the link script? I have no sense in link script?
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: How do you solve the order problem when you link the .o

Post by Octocontrabass »

benjixu wrote:How can I alter the link script?
Here is one way you could do it:

Code: Select all

...
SECTIONS
{
    . = 0x200000;
    /* make sure the .text section from kernel.o ends up at 0x200000 */
    .text.entry : {
        kernel.o(.text)
    }

    .text : {
        *(.text)
...
(I haven't tested this so it may not be entirely correct.)
benjixu
Posts: 11
Joined: Sat Oct 02, 2021 10:28 pm
Libera.chat IRC: Benji

Re: How do you solve the order problem when you link the .o

Post by benjixu »

Octocontrabass wrote:
benjixu wrote:How can I alter the link script?
Here is one way you could do it:

Code: Select all

...
SECTIONS
{
    . = 0x200000;
    /* make sure the .text section from kernel.o ends up at 0x200000 */
    .text.entry : {
        kernel.o(.text)
    }

    .text : {
        *(.text)
...
(I haven't tested this so it may not be entirely correct.)
Yes, you are correct. And plus, if I want to put the main.o in the second one. How can I do?
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: How do you solve the order problem when you link the .o

Post by Octocontrabass »

Why do you want to change how main.o is linked?
benjixu
Posts: 11
Joined: Sat Oct 02, 2021 10:28 pm
Libera.chat IRC: Benji

Re: How do you solve the order problem when you link the .o

Post by benjixu »

Octocontrabass wrote:Why do you want to change how main.o is linked?
I just want to know how do you write the link script.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How do you solve the order problem when you link the .o

Post by iansjack »

Post Reply