【问题标题】:__seg_fs on GCC. Is it possible to emulate it just in a program?__seg_fs 在 GCC 上。是否可以仅在程序中模拟它?
【发布时间】:2017-05-29 21:51:17
【问题描述】:

我刚刚阅读了有关 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','\0'};

void fs_puts(fs_ptr *s)
{
    char buf[100];

    buf[0] = s[0];
    buf[1] = s[1];
    buf[2] = s[2];
    buf[3] = '\0';

    puts(buf);
}

void __attribute__((constructor)) set_fs()
{
    __asm__("mov %ds, %bx\n\t"
            "add $0, %bx\n\t"      //<---- if fs=ds  then the program executes as expected. If not $0 here, then segmentation fault happens.        
            "mov %bx, %fs\n\t");
}

int main()
{
    fs_puts(p);

    return 0;
}         

【问题讨论】:

    标签: gcc segments


    【解决方案1】:

    我与在 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      相关资源
      最近更新 更多