How to load Dynamic Link 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
User avatar
Coconut9
Member
Member
Posts: 51
Joined: Sat May 20, 2017 1:25 am
Location: PCI bus: 3, slot: 9, function: 5

How to load Dynamic Link Libraries

Post by Coconut9 »

A program most of times loads some DLLs to run at runtime. Where to load the DLL? The DLL contains absolute memory access so we run into a problem! I thought that I can load the DLL as second program and use the kernel for communication (and maybe the page(s) that DLL use for storing data to be mapped at the programs VAS). I believe there exist another way, isn't it?
How people react when a new update of your OS is coming:
Linux user: Cool, more free stuff!
Mac user: Ooh I have to pay!
Windows user: Ah not again!
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How to load Dynamic Link Libraries

Post by iansjack »

I reserve a memory area to load dynamic libraries and then maintain a table of which library is loaded where.
User avatar
zaval
Member
Member
Posts: 659
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: How to load Dynamic Link Libraries

Post by zaval »

ARISTOS wrote: A program most of times loads some DLLs to run at runtime. Where to load the DLL? The DLL contains absolute memory access so we run into a problem! I thought that I can load the DLL as second program and use the kernel for communication (and maybe the page(s) that DLL use for storing data to be mapped at the programs VAS). I believe there exist another way, isn't it?
You mention DLLs. This is PE formatted executables. Even though they contain "absolute addresses", approach taken by PE avoids "problems" of colliding images. It's called Base Relocation. DLL image has (Preferred) Image Base, at the load time loader sees where to load the library for the process, if the Preferred Image Base the DLL is linked at is available, in the process' AS, it maps the DLL there, by per section basis. Sections are aligned at page size, so mapping is done by per page. If the Base is not available, it relocates the image, applying fixups for every address reference inside your code and data and for Image Base field. .reloc section holds relocation information. And again, - maps the image into process' address space.
There are system supplied DLLs, that you can avoid relocations for, just placing them in "reserved areas" of AS. But also it could be possible to do this for every DLL, it would require from you some architecting, you need to invent some facility aiding in achieveing this. Some service collecting info about what DLL a program loads, maybe some info at the package installation time, some kind of dependency expression, some system database holding this information etc. Anyway, any program package uses a set of DLLs, there is ways to hint the system about this set and try to avoid the need of relocations by accounting these DLLs and allocating AS region for them. Especially this could be easy for wide architectures, thus 64 bit ones.

There is also a position independent code, PIC, approach. I know little about it, it's common for ELF shared objects. There, shared objects could be loaded (mapped) at any region of AS, but some other restrictions apply like invariance of distance between ELF segments. Global Offset Table, GOT and Procedure Linkage Table, PLT in the architecture specific "supplements" for the ELF are your friends there.

If you are asking about how to know what to load, then, PE uses Import Tables. Import Directory Table, Import Lookup Table and Import Address Table. They tell what functions from what libraries are needed. IDT contains entries for every DLL the image imports from, the name of DLL and pointers to ILT and IAT. ILT serves as a source of the information about what functions are imported, IAT is filled by the loader at load time with addresses of the funtions. Basically IAT entries are function pointer variables, the code inside the image references. It's a very easy binding mechanism. Loader finds functions either by the name (slower), or by a number, ordinal, much faster. DLLs have export tables the loader inspects, that complement all this elegant binding mechanism.

For the "delayed loading" or the loading at runtime, other than at the start, it should be the same, allocating the space, checking for the relocation need, applying relocations if needed, mapping. The program shouldn't bother with this at all. The OS does the same as with start up DLLs.
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: How to load Dynamic Link Libraries

Post by ~ »

I am working in implementing a pure NASM-generated 32-bit DLL without using linkers, only NASM. It will allow you to see how to create the export table, export a function and call it from another program, as well as the full executable or DLL format (the same format with an export table) and specifying the base address for linking to a proper place:

http://f.osdev.org/viewtopic.php?t=32538
http://f.osdev.org/viewtopic.php?t=32538
Post Reply