2017-01-14 9 views
1

Ich habe gerade über die Unterstützung für% fs und% gs Segmentpräfixe auf den Intel-Plattformen in GCC gelesen. Es wurde erwähnt, dass "die Art, wie Sie% gs-basierte Zeiger erhalten oder den -Wert von% gs selbst steuern, außerhalb des Geltungsbereichs von gcc liegt."__seg_fs auf GCC. Ist es möglich, es nur in einem Programm zu emulieren?

Ich suche nach einer Möglichkeit, wenn ich manuell den Wert von% fs einstellen kann (ich bin auf IA32, RH Linux) und arbeite damit. Wenn ich nur% fs =% ds einstelle funktioniert der Test unten gut und das wird erwartet. Aber ich kann den Test nicht ändern, um einen anderen Wert von% fs zu erhalten und keinen Segmentierungsfehler zu erhalten. Ich fange an zu denken, dass die Änderung des Wertes von% fs nicht das einzige ist, was zu tun ist. Ich bin also auf der Suche nach einem Ratschlag, wie man einen Teil des Speichers mit% fs adressieren kann, der nicht gleich DS ist.

#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; 
}   

Antwort

1

Ich habe mit Armin gesprochen, die __seg_gs/__ seg_fs in GCC umgesetzt (Danke Armin!). Also im Grunde kann ich diese Schlüsselwörter nicht für globale verwenden. Das Ziel der Einführung von __seg_gs/fs bestand darin, Speicherbereiche dynamisch zuzuweisen, die Thread-lokal sind. Wir können __thread nicht für einen Zeiger verwenden und ihm mit malloc einen Speicher zuweisen. Aber __seg_gs/fs führen diese Möglichkeit ein. Der Test unten veranschaulicht das irgendwie. Beachten Sie, dass arch_prctl() verwendet wurde. Es existiert nur als 64-Bit-Version. Beachten Sie auch, dass% fs für __thread auf 64-Bit verwendet wird und% gs frei ist.

#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; 
} 
Verwandte Themen