海湾合作委员会的__seg_fs。是否可以在程序中模拟它?

时间:2017-01-14 17:40:50

标签: gcc segments

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

1 个答案:

答案 0 :(得分:1)

我和Armin谈过,他在GCC中实现了__seg_gs / __ seg_fs(感谢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;
}