Dynamically linking shared libraries

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
computafreak
Member
Member
Posts: 76
Joined: Sun Dec 14, 2008 1:53 pm

Dynamically linking shared libraries

Post by computafreak »

I've been stuck on this for a little while now, so would appreciate some help. I've been trying to separate my kernel into multiple files, and have been using shared libraries. I build the library like this:

Code: Select all

i586-elf-gcc -fPIC -g -W -shared -B symbolic -Werror -Wall -Wpointer-arith -Wcast-align -Wno-unused-parameter -nostdlib -fno-builtin -fno-rtti -fno-exceptions -I ./Include/ -I ../../Kernel/Include -c "INPUT" -o "OUTPUT"
I then link it by giving the object files to i586-elf-ld, passing only the -shared argument. This results in a shared library, with no linker or compiler errors or warnings.

I had a problem with linking my main executable when I did that though, due to undefined references. This wasn't resolved when I attempted to link the shared library I created as a library with the -L switch. The errors were resolved when I tacked the shared library onto the end of the input object file paths, and I can boot my OS.

I know that this doesn't completely link the library though (maybe it just adds some entries to the v-tables?), because when I enter a command which uses the library I get a page fault. Clearly I need to relocate and link the library. Unfortunately, I don't know how to do this. I have the shared library loaded by GrUB as a module, so there aren't any problems accessing it. So I suppose my question is this: how do I dynamically link a shared library into my kernel? If it makes any difference (to be honest I don't see how it could), the shared library is written in C++
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: Dynamically linking shared libraries

Post by yemista »

Where address do library functions fault on? This can at least tell you where the library is being linked to and the symbol table from ld can tell you where it actually is. Maybe is has something to do with the librarys linker file?
MikeP
Posts: 3
Joined: Fri Jul 17, 2009 5:24 am

Re: Dynamically linking shared libraries

Post by MikeP »

Short answer: you have to look through the program header table to find the PT_DYNAMIC segment, and interpret the things it contains. DT_NEEDED elements in the main program tell you which shared libraries it wants to link against, and DT_REL, DT_RELA and DT_JMPREL elements contain lists of relocations that you have to process before starting the main program.

Basically each relocation consists of

- a symbol name - you have to look through the symbol tables of the shared libraries, and find the one that defines the required symbol
- an address within your program
- a type, which tells you how to modify the word at that address to perform the fixup - usually it's some variant of adding the address of the symbol you just looked up to the contents of memory at that location.

The long answer: http://www.skyfree.org/linux/references/ELF_Format.pdf - dynamic linking is described on page 2-10 and onwards - but if you're lazy like me you don't necessarily have to implement it all; I don't use the PT_INTERP header at all, for instance, I just have a function in kernel space for mapping a new shared library into a process and doing all the fixups.
computafreak
Member
Member
Posts: 76
Joined: Sun Dec 14, 2008 1:53 pm

Re: Dynamically linking shared libraries

Post by computafreak »

I don't think that it's the linker file - I don't have one in the build process of my shared library. My library function faults on 0xFF642F20 in Bochs, which doesn't correspond to any addresses in my linker maps or disassemblies. The page fault occurs in the constructor of the class in the shared library, but I assume that if it can't run one method from a shared library, it won't be able to run any of them. I know that it's not the library code at fault - I could compile it directly into the kernel and it'd work.

In case it helps, here's a snapshot of my OS' screen

Code: Select all

A page fault exception has ocurred. The details are displayed below:
        Page present: yes
        Occured during a memory writing operation
        Ocurred in supervisor mode
        Ocurred at memory address 0xFF642F20
        End of kernel is 0x113D59
        Registers:
                CR0: 0xE0000011
                CR1: reserved (should always be 0x0)
                CR2: 0xFF642F20
                CR3: 0x1D8E000
                CR4: 0x0
        EIP: 0x0
        EAX: 0x1D75718  EBX: 0x1D75718  ECX: 0x7        EDX: 0x1D75718
        EDI: 0x2CF0A    ESI: 0x102376   EBP: 0x112F10   ESP: 0x112E78
        CS: 0x8 DS: 0x1D70010   SS: 0x8
        Error code: 0x2                 UserESP: 0x0
Stack trace:
        0x104E42:
        0x104BE6:
        0x101E44:
        0x100037:
Apologies: this post only really applies to the first reply. I can't reply to the second reply at the moment, I'm about to go out. I'll reply in the morning; sorry!
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Dynamically linking shared libraries

Post by pcmattman »

I've been trying to separate my kernel into multiple files, and have been using shared libraries.
You may be better off linking into small objects rather than shared libraries, using the "-r" switch to GCC/LD, if these functions are remaining in kernel land.
computafreak
Member
Member
Posts: 76
Joined: Sun Dec 14, 2008 1:53 pm

Re: Dynamically linking shared libraries

Post by computafreak »

MikeP, thanks for the link and summary; I'm reading them now. For future reference, is this the same process that is used to load an ELF executable, with the additional step of calling the entry point?

pcmattman, I've looked into the -r switch, and information seems to be a little vague. What would be the benefits of using this over shared libraries? By the looks of it, I would still need to link it
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Dynamically linking shared libraries

Post by pcmattman »

The -r switch basically does everything except the final link (outputs just an object file, not an executable). This means when you load the object, your loader fixes up the undefined references against symbols in the kernel or something.

You haven't explained exactly why you think you need shared libraries, or what these multiple files actually do, so it might help to get a bit of a picture of what you're trying to do.
computafreak
Member
Member
Posts: 76
Joined: Sun Dec 14, 2008 1:53 pm

Re: Dynamically linking shared libraries

Post by computafreak »

I understand now. It does an incremental link, and my OS simply finishes the job. That does sound a little simpler, and it sounds as if the loading technique could be used when I get around to executing programs. But would I be be able to directly use the methods inside it? The reason I'm using a shared library is because once it has had all of the references resolved, I can use the methods inside the module as if the library was compiled into the kernel completely to start with. If I link against a 'half-linked' file to be able to directly use the classes and methods, wouldn't this just link it completely into the kernel?

As for context, I've got the main kernel, and one module. The module basically contains all the PCI functions. These functions are in a class and some structures. The kernel has a function, GetPCI, which tries to directly call the class' constructor and methods, printing the result to the screen. I compile the PCI module as a shared library to prevent the dependencies from getting resolved (for convenience), then copy it into the ISO image. I then compile and link the main kernel, tacking the compiled PCI module onto the end of the object files, and giving the compiler a copy of the PCI module's header file. I get no errors when linking either of the modules
Post Reply