How to interpret segment register accesses on x86-64?

前端 未结 2 630
春和景丽
春和景丽 2021-01-02 11:10

With this function:

mov    1069833(%rip),%rax        # 0x2b5c1bf9ef90 <_fini+3250648>
add    %fs:0x0,%rax
retq

How do I interpret the

相关标签:
2条回答
  • 2021-01-02 11:34

    This code:

    mov    1069833(%rip),%rax        # 0x2b5c1bf9ef90 <_fini+3250648>
    add    %fs:0x0,%rax
    retq
    

    is returning the address of a thread-local variable. %fs:0x0 is the address of the TCB (Thread Control Block), and 1069833(%rip) is the offset from there to the variable, which is known since the variable resides either in the program or on some dynamic library loaded at program's load time (libraries loaded at runtime via dlopen() need some different code).

    This is explained in great detail in Ulrich Drepper's TLS document, specially §4.3 and §4.3.6.

    0 讨论(0)
  • 2021-01-02 11:43

    I'm not sure they've been called segment register since the bad old days of segmented architecture. I believe the proper term is a selector (but I could be wrong).

    However, I think you just need at the first quadword (64 bits) in the fs area.

    The %fs:0x0 bit means the contents of the memory at fs:0. Since you've used the generic add (rather than addl for example), I think it will take the data width from the target %rax.

    In terms of getting the actual value, it depends on whether you're in legacy or long mode.

    In legacy mode, you'll have to get the fs value and look it up in the GDT (or possibly LDT) in order to get the base address.

    In long mode, you'll need to look at the relevant model specific registers. If you're at this point, you've moved beyond my level of expertise unfortunately.

    0 讨论(0)
提交回复
热议问题