amd64 環境での PTR_MANGLE/PTR_DEMANGLE の実装を確認してみた

glibc-2.7 のソースコードで確認した。以下は jmp_buf から実際のアドレスを抜き出すテストプログラム。

#include <stdio.h>
#include <setjmp.h>

#define PTR_DEMANGLE(var) asm("rorq $17, %0;" \
                              "xorq %%fs:0x30, %0;" : "=r"(var) : "0"(var))

int main(int argc, char** argv)
{
    long direct_rsp, direct_pc;
    long setjmp_rsp, setjmp_pc;

    jmp_buf jmpBuf;

    asm("movq %%rsp, %0;" : "=r"(direct_rsp));

    asm("callq label;"
        "label: popq %0;" : "=r"(direct_pc));

    printf("direct_RSP = %llX, direct_PC = %llX\n", direct_rsp, direct_pc);

    setjmp(jmpBuf);

    setjmp_rsp = jmpBuf[0].__jmpbuf[6]; // RSP                                                                                                                  
    setjmp_pc = jmpBuf[0].__jmpbuf[7]; // PC                                                                                                                    

    PTR_DEMANGLE(setjmp_rsp);
    PTR_DEMANGLE(setjmp_pc);

    printf("setjmp_RSP = %llX, setjmp_PC = %llX\n", setjmp_rsp, setjmp_pc);

    return 0;
}
$ ./a.out 
direct_RSP = 7FFF6559A860, direct_PC = 40050C
setjmp_RSP = 7FFF6559A860, setjmp_PC = 400534