|
From: Nicholas N. <nj...@ca...> - 2004-02-25 11:30:10
|
Hi,
I just learnt about segment registers properly for the first time. Now I
see what the fuss is all about. I have some questions about them, I would
appreciate answers from any kind soul...
- Who uses them? Some ordinary apps, I guess... does glibc, or other
relevant libraries?
- AFAICT, we virtualise the LDT, but not the GDT(?) Linux has the
modify_ldt() syscall, does it not use the GDT at all so we don't have to
worry about it, or is there something else happening?
- if segment registers are in use, if I print a pointer, I'm really only
printing the offset within the current segment, rather than the true
virtual address, right? (Which is why V must convert it, for the skin's
sake.)
- AFAICT, the following is true
- %cs is implicit operand to every instruction fetch?
- %ss is implicit operand to every stack instruction?
- %ds is implicit operand to all non-stack, non-string ops?
- %es is implicit operand to string ops?
- segment overrides are required to use %fs, %gs
When segment overrides are used, the GETSEG/USESEG pair is used to
convert far pointers to flat addresses. That's fine. But what happens
when there is no segment override? Eg. if we set %ds, which affects
most ops, are GETSEG/USESEG pairs introduced then?
Thanks.
N
|
|
From: Tom H. <th...@cy...> - 2004-02-25 11:52:37
|
In message <Pin...@ye...>
Nicholas Nethercote <nj...@ca...> wrote:
> I just learnt about segment registers properly for the first time. Now I
> see what the fuss is all about. I have some questions about them, I would
> appreciate answers from any kind soul...
I'm not a huge expert or anything, but I'll see what I cam do...
> - Who uses them? Some ordinary apps, I guess... does glibc, or other
> relevant libraries?
They are mostly a hang over from 16 bit days and 32 bit systems don't
generally use them very much. That said, they are used as a way of
doing thread local storage just because it's a convenient trick to use
for that.
Linuxthreads uses the LDT for that where the kernel loads a new LDT
each time it does a context switch and the code then uses a segment
register to index into the LDT to find the piece of TLS data it
wants. That limits you to 8192 slots because that is the size of a
descriptor table.
NPTL uses the GDT and the kernel just updates the three TLS slots in
the GDT on a context switch. Those slots effectively hold pointers to
large blocks of TLS data that are managed by glibc/libpthread.
> - AFAICT, we virtualise the LDT, but not the GDT(?) Linux has the
> modify_ldt() syscall, does it not use the GDT at all so we don't have to
> worry about it, or is there something else happening?
The CVS head does virtualise the GDT as well, or at least that part of
it that the kernel effectively exposes to user land, namely the TLS data
pointers. The set_thread_area and get_thread_area calls are used to
modify that part of the GDT.
The kernel itself uses a few other GDT entries for it's own use but
they don't change on a per-process basis as far as I know and they're
not intended for use outside the kernel.
> - if segment registers are in use, if I print a pointer, I'm really only
> printing the offset within the current segment, rather than the true
> virtual address, right? (Which is why V must convert it, for the skin's
> sake.)
Yep.
> - AFAICT, the following is true
> - %cs is implicit operand to every instruction fetch?
> - %ss is implicit operand to every stack instruction?
> - %ds is implicit operand to all non-stack, non-string ops?
> - %es is implicit operand to string ops?
> - segment overrides are required to use %fs, %gs
That sounds about right, but in 32 bit code it is rare for anything
other that %fs or %gs to be used - the code, stack and data segments
are usually fixed by the system to give a flat address space.
> When segment overrides are used, the GETSEG/USESEG pair is used to
> convert far pointers to flat addresses. That's fine. But what happens
> when there is no segment override? Eg. if we set %ds, which affects
> most ops, are GETSEG/USESEG pairs introduced then?
Not as far as I know, but I might be wrong.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Jeremy F. <je...@go...> - 2004-02-25 17:19:41
|
On Wed, 2004-02-25 at 03:51, Tom Hughes wrote: > > When segment overrides are used, the GETSEG/USESEG pair is used to > > convert far pointers to flat addresses. That's fine. But what happens > > when there is no segment override? Eg. if we set %ds, which affects > > most ops, are GETSEG/USESEG pairs introduced then? > > Not as far as I know, but I might be wrong. No, I think we just gloss over them, assuming that [cdse]s are all "flat". Very few programs play with these - I think Wine and dosemu are the only real contenders. There are also a pile of other magics associated with segments. For example, you can set 16-bit mode in cs, so that you're running 16 bit sized instructions by default (with the size override prefix meaning "32 bits"). J |