Page 1 of 1

extern + global

Posted: Mon May 30, 2011 7:42 am
by mariuszp
I've been making my own executable format for my OS. I managed to make nasm output this format like this:

Code: Select all

nasm test.s -o test.out -f madd
And it works. But there is one thing I don't understand. Suppose I have code like this:

Code: Select all

extern label

mov eax,label
call [eax]
What would the value of EAX be? When I use extern nasm tells my output format driver immediately that the label is at 0, and outputs all relocations accordingly. My question is: if I used that label a couple of times, and I wanted to link that with a library, what could I do to make sure all the relocations for just that label are moved to that specific location where the library defines 'label'? Do I have to make it so that every relocation table entry sais 'this is an extern location to some symbol'?

Re: extern + global

Posted: Mon May 30, 2011 8:20 am
by mariuszp
hello?

Re: extern + global

Posted: Mon May 30, 2011 8:33 am
by Solar
mariuszp wrote:What would the value of EAX be?
Whatever value label was assigned by the linker, in the object file where it was actually defined (i.e., after relocation).

Sorry, I don't fully understand your question.

Re: extern + global

Posted: Mon May 30, 2011 8:36 am
by mariuszp
Let me explain this further. I made my own executable format, which supports relocation, but not linking. I don't know how linking with external files is performed, how do I keep track of where label is used so I can then change its value? I mean, without modifying the assembly code. There must be something to do with it inside the object file...

Re: extern + global

Posted: Mon May 30, 2011 8:55 am
by mariuszp
I understand that. What I don't understand is how does it know that a relocation is supposed to be 'external'?

Re: extern + global

Posted: Mon May 30, 2011 9:06 am
by mariuszp
LOL my question is how can i design my format so that it can support external references

Re: extern + global

Posted: Mon May 30, 2011 9:20 am
by thepowersgang
You can do that by studying other formats, and not asking poorly worded questions on the forums.

That said, from your first post, NASM should have a relocation entry referencing the symbol for each time it's used.

<edit>Oh, the irony, I missed out a word in my complaint</edit>

Re: extern + global

Posted: Mon May 30, 2011 9:26 am
by Solar
To design a file format, you should know how existing state-of-the-art formats work, and have an idea of what you want to do better (or, at least, different)...

Re: extern + global

Posted: Mon May 30, 2011 2:30 pm
by gravaera
thepowersgang wrote:You can do that by studying other formats, and not asking poorly questions on the forums.
... :?

Yo:
Relocation when dealing with external references is as simple as having the linker take stock of each external reference and compile them into a list and package that list into the executable. The Runtime (dynamic) linker looks at this list of needed relocations, and resolves them. There are two ways of doing this:

1. The list would tell the dynamic linker exactly which offset within the executable to patch up when it loads the relevant external library into the program's address space. This means that that dynamic linker would be writing directly to the executable's image, and patching directly into the image's code and data.

2. The linker would have made all functions do a "two hop" approach where there is a table (GOT, PLT etc. in ELF are examples), and the tables contains a bunch of blank 32-bit spaces, one for each externally referenced function. The linker would encode each function call to an external function as "Load the pointer in 32-bit cell X, and then jump to it". The dynamic linker is expected to fill out the pointer cells in the table with the locations of the external functions, and so the linkage is made in this case WITHOUT modifying the code and data sections of the loaded image directly.

The second case is favourable when linking to external functions, as called within the .text (code) section of an executable. Code sections are loaded as read only, etc., etc., so the most flexible design for a portable executable format would be to have a two-hop jump table approach to avoid design disconnects between conformant kernels.

Might want to read up more on dynamic linkage and all that, but this should be the basic stuff, yo.

--Good luck
gravaera

Re: extern + global

Posted: Tue May 31, 2011 10:53 pm
by rdos
I would want to implement a new executable format which would be much simpler than PE/ELF. It would be based on the compact memory model. There would be no relocation information as compact memory model does not require any runtime relocations. Dynamic link libraries would need relocations of segments and offsets of 48-bit far calls. Entries in DGROUP would not need relocations either, nor would resource entries, as these would always refer to the same segment. The only required patching would be of default code & data segments unless this is specified with fixed selectors at link-time. This could be handled at runtime by putting invalid selectors in the code, and let the protection-fault handler do the patching.

Re: extern + global

Posted: Wed Jun 01, 2011 2:09 am
by rdos
berkus wrote:
rdos wrote:I would want to implement a new executable format which would be much simpler than PE/ELF. It would be based on the compact memory model. There would be no relocation information as compact memory model does not require any runtime relocations. Dynamic link libraries would need relocations of segments and offsets of 48-bit far calls. Entries in DGROUP would not need relocations either, nor would resource entries, as these would always refer to the same segment. The only required patching would be of default code & data segments unless this is specified with fixed selectors at link-time. This could be handled at runtime by putting invalid selectors in the code, and let the protection-fault handler do the patching.
You could use ELF for that, for example.
I don't think so. ELF has no support for segmentation, and it has an assumed base-address of the executable and contains offset relocation information. In my design, the code and data segments always start a offset 0, and never need relocation. Relocation is done by changing base of the code and data selector. ELF also does not support changing SEG references to real selector references. It only supports changing 32-bit offsets using relocation tables. ELF doesn't support dynamic linking using 48-bit imports either. ELF only supports changing a 32-bit offset when resolving imported references.

One feature of PE/ELF that I would want to keep is the page-aligned structure. This has advantages as individual pages in the executable can be loaded on demand when referenced. This can be implemented just as well in the segmented design. The only requirement is that code and data segments are allocated with page-alignment.