2017-01-14 10 views
1

GCC의 Intel 플랫폼에서 % fs 및 % gs 세그먼트 접두사에 대한 지원을 읽었습니다. "% gs 기반 포인터를 얻는 방법 또는 % gs 자체의 값을 제어하는 ​​방법은 gcc의 범위를 벗어났습니다."__seg_fs 프로그램에서 바로 에뮬레이트 할 수 있습니까?

수동으로 % fs 값을 설정할 수있는 방법을 찾고 있는데 (IA32, RH Linux에 있음) 작업하고 있습니다. % fs = % ds를 설정하면 아래의 테스트가 제대로 작동하며 예상됩니다. 그러나 % fs의 다른 값을 가지기 위해 테스트를 변경할 수 없으며 세그먼테이션 오류가 발생하지 않습니다. % fs의 값을 변경하는 것이 유일한 방법은 아니라고 생각합니다. 그래서 나는 DS와 같지 않은 % fs에 의해 다루어지는 메모리의 일부분을 만드는 방법에 대한 조언을 찾고있다.

#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

내가 __seg_gs을 구현하는 사람들 아르 민과 이야기 한/__ GCC의 seg_fs (감사 아르 민!). 기본적으로 이러한 키워드는 전역에 사용할 수 없습니다. __seg_gs/fs를 도입 할 목적은 스레드 로컬 인 메모리 영역을 동적으로 할당 할 수있는 가능성을 얻는 것이 었습니다. malloc을 사용하여 포인터에 __thread를 사용하고 메모리를 할당 할 수 없습니다. 그러나 __seg_gs/fs는 이러한 가능성을 소개합니다. 아래의 테스트는 어떻게 든 그것을 보여줍니다. arch_prctl()이 사용되었습니다. 64 비트 버전으로 만 존재합니다. 64 비트에서 __thread에는 % fs가 사용되며 % 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; 
}