Page 1 of 1
how system associates linker sections with segment registers
Posted: Wed Jun 09, 2010 7:16 pm
by rknox
I am trying to understand how the system associates linker sections with segment registers.
Its clear how to associate code sections and data sections with linker sections via the linker script.
Then there is some intermediate process that associates these linker sections with segment registers. This is where I am hazy.
It is clear how to set up segment attributes in the gdt and how to associate gdt entries with registers ds es fs gs ss.
It is clear how to cause CS to be associated with the desired offset in the gdt (via the far jmp, etc).
But it is not clear who associates linker segment .text with CS, or who associates linker segment .data with whatever segment register it is associated with.
With core dumps and/or experimentally zeroing various segment registers I might be able to figure out what is happening, but I am trying to understand where one controls the process.
If I wanted to create a linker segment .rodata (and I don't particularly want to, but using this as an example) and later associate it with gdt offset 0x18, how would I get the system to put it on a different segment register than the rest of the data, and how would I know which register that was?
I read in info ld about a library BFD which associates architecture definition with back end rules - maybe that is where I want to look? If so, does anyone know where BFD is?
I know this association does not take place in the loader, because I am using my own loader and I am not doing it there. Ld was told by the script that the executable was "binary'. Apparently the association is made in ld?
Can anyone lead me to light and out of this darkness?
Re: how system associates linker sections with segment regis
Posted: Wed Jun 09, 2010 7:32 pm
by NickJohnson
Based on the naming, it seems that you're using ELF. ELF, afaik, always requires a flat memory model, which means the segment bases must be 0 and their limits must be the top of memory. ELF load segments and x86 segmentation are related only by name. More concisely: the system doesn't associate linker sections with segment registers.
Re: how system associates linker sections with segment regis
Posted: Wed Jun 09, 2010 7:58 pm
by gerryg400
I think gcc is also a problem. AFAIK, the 32bit and 64bit x86 compiler versions never generate code to load a segment, nor do they generate code that uses a segment override. So you are stuck in one 'segment' if you are using an HLL.
Re: how system associates linker sections with segment regis
Posted: Wed Jun 09, 2010 9:22 pm
by rknox
Yes - flat model. I understand that all the registers now point at the same range of memory addresses, and have the same read/write attributes (except for Cs which points at the same range of memory but is associated with a gdt entry that is marked code - read only).
The data segment registers are being used as shown by the fact that if I point ES FS and GS at the null gdt entry the program blows up. I have not taken the time to do that one by one yet, so I dont know exactly which are being used.
As I understand flat model, the segment registers can all point at the same space but differ in their read/write attributes and so one could be read only and the the others read/write. In that case, I would expect that one could associate some data section - name it what you want - with the segment register that points to a read only entry in the gdt.
I am not locked in on elf - and the files are not elf when they leave the linker because I've set the attribute "binary". My loader merely dumps them into memory and branches to the start address. When you look at a dump of the file - no loader data structures. Exactly match the assembler code described in the asm and C listings.
Imagine that I write the whole thing in an assembler - and pick the file format you suggest. In that case, can I associate some of the data with one seg register and another section of data with another? If not, why do they bother to give me an unlimited number of entries in the gdt? Why not just 3 - null, code and data?
I'm still confused. Maybe I completely misunderstand protected mode - flat model? I've read the Intel documents (at least some since the set is about 5000 pages long) and concluded - maybe incorrectly - that you should be able to associate different material with different gdt entries. What am I missing?
Re: how system associates linker sections with segment regis
Posted: Wed Jun 09, 2010 10:15 pm
by gerryg400
Imagine that I write the whole thing in an assembler - and pick the file format you suggest. In that case, can I associate some of the data with one seg register and another section of data with another? If not, why do they bother to give me an unlimited number of entries in the gdt? Why not just 3 - null, code and data?
If you write it in assembler and link it yourself, you can certainly segment your data (at least in 32bit mode). The reason they give you so many entries in GDT ?
- 2 code segments (one 3GB and one 4GB) is a conventient way of protecting your high quarter kernel from user mode access.
- For backward compatability, you may want to support v86 mode and you'll need entries for that.
- Some OS's use segmentation to separate processes in memory, so from the OS point of view, each process needs its own segment entries in the GDT.
- You need GDT entries for TSS's. And every core in a multicore machine needs one.
Intel/AMD provide many options to the OS designer, some are commonly used, some aren't. Most modern OS's don't use segments or hardware taskswitching. This probably played a part in AMD dropping them in 64bit mode.
Re: how system associates linker sections with segment regis
Posted: Wed Jun 09, 2010 11:55 pm
by rknox
Gerry
The light is starting to come on.
If I wanted to place data in two different segments then I would not set them up as flat, but instead read only would be here and read/write would be there?
But how would I associate the data with the segments?
Maybe I put some r/w data at 60000 and some r/o data at 70000. Then I make two entries in the gdt - 0x10 relating to 60000-6ffff 0x18 for 70000-7ffff? And I make all my code references of the form seg:offset?
Am I getting close or totally lost??
If it is like the above, then I start to see that the way the compiler and linker work just won't get me from here to there.
I dont want to do this, but am trying to understand the architecture.
Lost in Los Angeles.
****
Re: how system associates linker sections with segment regis
Posted: Thu Jun 10, 2010 12:28 am
by gerryg400
If I wanted to place data in two different segments then I would not set them up as flat, but instead read only would be here and read/write would be there?
That's correct. Your assembler can make different segments. And you can write assember code to access the 2 segments. Your linker script would need to keep the segments separate. Then your loader/kernel can put them anywhere in memory and setup the GDT for you.
Maybe I put some r/w data at 60000 and some r/o data at 70000. Then I make two entries in the gdt - 0x10 relating to 60000-6ffff 0x18 for 70000-7ffff? And I make all my code references of the form seg:offset?
Am I getting close or totally lost??
No, not lost. You would have for example DS=0x10 and FS=0x18 and use a segment override prefix whenever you wanted the access the FS segment. DS is used by default.
Re: how system associates linker sections with segment regis
Posted: Thu Jun 10, 2010 3:12 am
by Solar
There is no implicit association of linker sections with segment registers.
There is a part of your OS called the "loader". It is responsible for putting a binary loaded from file into memory in some way. What you do with which part of the binary is completely up to you; this is where "association" is done or not done. You have to keep in mind (as already discussed) that code generated by GCC assumes a flat memory model, and that the pieces of code have to find each other (keyword: relocation), so your choices are limited.
Re: how system associates linker sections with segment regis
Posted: Thu Jun 10, 2010 3:28 am
by gerryg400
The data segment registers are being used as shown by the fact that if I point ES FS and GS at the null gdt entry the program blows up. I have not taken the time to do that one by one yet, so I dont know exactly which are being used.
It's very likely ES. There are some instructions that use es:edi as a destination pointer, e.g movs
Re: how system associates linker sections with segment regis
Posted: Thu Jun 10, 2010 4:58 am
by Solar
Last time I checked this - which admittedly was during GCC 3.x times - GCC code used DS and ES regularily, and used one of FS / GS (I think FS) for exception handling, leaving GS theoretically free for whatever you'd need a segment register for.
However, that's gory GCC innards, and I wouldn't bet my project on that staying unchanged.
Re: how system associates linker sections with segment regis
Posted: Thu Jun 10, 2010 6:28 am
by Owen
Solar wrote:Last time I checked this - which admittedly was during GCC 3.x times - GCC code used DS and ES regularily, and used one of FS / GS (I think FS) for exception handling, leaving GS theoretically free for whatever you'd need a segment register for.
However, that's gory GCC innards, and I wouldn't bet my project on that staying unchanged.
GCC ignores FS and GS completely, with one small exception: It can use GS (32-bit) or FS (64-bit) for some kind of thread local storage thing. Presumably if you wanted you could instruct it to use one of your choosing. This requires runtime support to enable.
Another exception is Windows exception handling (Excuse the pun). That uses FS IIRC. Exception handling on other platforms uses a completely different and much more efficient (For the no exception case anyway) method.
It expects that DS = ES = SS, and that CS and DS have matching base and limits.
Re: how system associates linker sections with segment regis
Posted: Thu Jun 10, 2010 8:38 am
by rknox
I was lost in the clouds and you gentlemen have made it clear.
So simple once you get the wrong assumptions out of your head.
Thank you so much!
What a fantastic resource.