__seg_fs在海湾合作委员会.是否可以仅在程序中模拟它



我刚刚读到了 GCC 中英特尔平台上对 %fs 和 %gs 段前缀的支持。有人提到,"获取基于 %gs 的指针或控制%gs 本身的值超出了 gcc 的范围;"

我正在寻找一种手动可以设置 %fs 的值的方法(我在 IA32、RH Linux 上)并使用它。当我刚刚设置 %fs=%ds 时,下面的测试工作正常,这是意料之中的。但是我无法更改测试以具有另一个 %fs 值并且不会得到分段错误。我开始认为更改 %fs 的值并不是唯一要做的事情。所以我正在寻找一个建议,如何使 %fs 寻址的内存部分不等于 DS。

#include <stddef.h>
typedef char __seg_fs fs_ptr;
fs_ptr p[] = {'h','e','l','l','o',''};
void fs_puts(fs_ptr *s)
{
    char buf[100];
    buf[0] = s[0];
    buf[1] = s[1];
    buf[2] = s[2];
    buf[3] = '';
    puts(buf);
}
void __attribute__((constructor)) set_fs()
{
    __asm__("mov %ds, %bxnt"
            "add $0, %bxnt"      //<---- if fs=ds  then the program executes as expected. If not $0 here, then segmentation fault happens.        
            "mov %bx, %fsnt");
}
int main()
{
    fs_puts(p);
    return 0;
}         

我已经和在GCC中实现了__seg_gs/__seg_fs的Armin交谈过(谢谢Armin!)。所以基本上我不能将这些关键字用于全局变量。引入 __seg_gs/fs 的目的是能够动态分配线程本地的内存区域。我们不能将__thread用于指针并使用malloc为其分配内存。但是__seg_gs/fs引入了这种可能性。下面的测试以某种方式说明了这一点。请注意,使用了 arch_prctl()。它仅作为 64 位版本存在。另请注意,%fs 用于 64 位__thread,%gs 可用。

#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <asm/ldt.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <asm/prctl.h>
#include <sys/syscall.h> 
#include <unistd.h> 
typedef __seg_gs char gs_str;
void gs_puts(gs_str *ptr)
{
    int i;
    char buf[100];
    for(i = 0; i < 100; i++)
        buf[i] = ptr[i];
    puts(buf);
}
int main()
{
    int i;
    void *buffer = malloc(100 * sizeof(char));
    arch_prctl(ARCH_SET_GS, buffer);
    gs_str *gsobj = (gs_str *)0;
    for (i = 0; i < 100; i++)
        gsobj[i] = 'a';       /* in the %gs space */
    gs_puts(gsobj);
    return 0;
}

相关内容

  • 没有找到相关文章

最新更新