void test_segs(void)

{

    struct modify_ldt_ldt_s ldt;

    long long ldt_table[3];

    int res, res2;

    char tmp;

    struct {

        uint32_t offset;

        uint16_t seg;

    } __attribute__((packed)) segoff;



    ldt.entry_number = 1;

    ldt.base_addr = (unsigned long)&seg_data1;

    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;

    ldt.seg_32bit = 1;

    ldt.contents = MODIFY_LDT_CONTENTS_DATA;

    ldt.read_exec_only = 0;

    ldt.limit_in_pages = 1;

    ldt.seg_not_present = 0;

    ldt.useable = 1;

    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */



    ldt.entry_number = 2;

    ldt.base_addr = (unsigned long)&seg_data2;

    ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;

    ldt.seg_32bit = 1;

    ldt.contents = MODIFY_LDT_CONTENTS_DATA;

    ldt.read_exec_only = 0;

    ldt.limit_in_pages = 1;

    ldt.seg_not_present = 0;

    ldt.useable = 1;

    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */



    modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */

#if 0

    {

        int i;

        for(i=0;i<3;i++)

            printf("%d: %016Lx\n", i, ldt_table[i]);

    }

#endif

    /* do some tests with fs or gs */

    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));



    seg_data1[1] = 0xaa;

    seg_data2[1] = 0x55;



    asm volatile ("fs movzbl 0x1, %0" : "=r" (res));

    printf("FS[1] = %02x\n", res);



    asm volatile ("pushl %%gs\n"

                  "movl %1, %%gs\n"

                  "gs movzbl 0x1, %0\n"

                  "popl %%gs\n"

                  : "=r" (res)

                  : "r" (MK_SEL(2)));

    printf("GS[1] = %02x\n", res);



    /* tests with ds/ss (implicit segment case) */

    tmp = 0xa5;

    asm volatile ("pushl %%ebp\n\t"

                  "pushl %%ds\n\t"

                  "movl %2, %%ds\n\t"

                  "movl %3, %%ebp\n\t"

                  "movzbl 0x1, %0\n\t"

                  "movzbl (%%ebp), %1\n\t"

                  "popl %%ds\n\t"

                  "popl %%ebp\n\t"

                  : "=r" (res), "=r" (res2)

                  : "r" (MK_SEL(1)), "r" (&tmp));

    printf("DS[1] = %02x\n", res);

    printf("SS[tmp] = %02x\n", res2);



    segoff.seg = MK_SEL(2);

    segoff.offset = 0xabcdef12;

    asm volatile("lfs %2, %0\n\t"

                 "movl %%fs, %1\n\t"

                 : "=r" (res), "=g" (res2)

                 : "m" (segoff));

    printf("FS:reg = %04x:%08x\n", res2, res);



    TEST_LR("larw", "w", MK_SEL(2), 0x0100);

    TEST_LR("larl", "", MK_SEL(2), 0x0100);

    TEST_LR("lslw", "w", MK_SEL(2), 0);

    TEST_LR("lsll", "", MK_SEL(2), 0);



    TEST_LR("larw", "w", 0xfff8, 0);

    TEST_LR("larl", "", 0xfff8, 0);

    TEST_LR("lslw", "w", 0xfff8, 0);

    TEST_LR("lsll", "", 0xfff8, 0);



    TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1);

    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3);

    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1);

}

void test_segs(void)

{

    struct modify_ldt_ldt_s ldt;

    long long ldt_table[3];

    int res, res2;

    char tmp;

    struct {

        uint32_t offset;

        uint16_t seg;

    } __attribute__((packed)) segoff;



    ldt.entry_number = 1;

    ldt.base_addr = (unsigned long)&seg_data1;

    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;

    ldt.seg_32bit = 1;

    ldt.contents = MODIFY_LDT_CONTENTS_DATA;

    ldt.read_exec_only = 0;

    ldt.limit_in_pages = 1;

    ldt.seg_not_present = 0;

    ldt.useable = 1;

    modify_ldt(1, &ldt, sizeof(ldt)); 



    ldt.entry_number = 2;

    ldt.base_addr = (unsigned long)&seg_data2;

    ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;

    ldt.seg_32bit = 1;

    ldt.contents = MODIFY_LDT_CONTENTS_DATA;

    ldt.read_exec_only = 0;

    ldt.limit_in_pages = 1;

    ldt.seg_not_present = 0;

    ldt.useable = 1;

    modify_ldt(1, &ldt, sizeof(ldt)); 



    modify_ldt(0, &ldt_table, sizeof(ldt_table)); 

#if 0

    {

        int i;

        for(i=0;i<3;i++)

            printf("%d: %016Lx\n", i, ldt_table[i]);

    }

#endif

    

    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));



    seg_data1[1] = 0xaa;

    seg_data2[1] = 0x55;



    asm volatile ("fs movzbl 0x1, %0" : "=r" (res));

    printf("FS[1] = %02x\n", res);



    asm volatile ("pushl %%gs\n"

                  "movl %1, %%gs\n"

                  "gs movzbl 0x1, %0\n"

                  "popl %%gs\n"

                  : "=r" (res)

                  : "r" (MK_SEL(2)));

    printf("GS[1] = %02x\n", res);



    

    tmp = 0xa5;

    asm volatile ("pushl %%ebp\n\t"

                  "pushl %%ds\n\t"

                  "movl %2, %%ds\n\t"

                  "movl %3, %%ebp\n\t"

                  "movzbl 0x1, %0\n\t"

                  "movzbl (%%ebp), %1\n\t"

                  "popl %%ds\n\t"

                  "popl %%ebp\n\t"

                  : "=r" (res), "=r" (res2)

                  : "r" (MK_SEL(1)), "r" (&tmp));

    printf("DS[1] = %02x\n", res);

    printf("SS[tmp] = %02x\n", res2);



    segoff.seg = MK_SEL(2);

    segoff.offset = 0xabcdef12;

    asm volatile("lfs %2, %0\n\t"

                 "movl %%fs, %1\n\t"

                 : "=r" (res), "=g" (res2)

                 : "m" (segoff));

    printf("FS:reg = %04x:%08x\n", res2, res);



    TEST_LR("larw", "w", MK_SEL(2), 0x0100);

    TEST_LR("larl", "", MK_SEL(2), 0x0100);

    TEST_LR("lslw", "w", MK_SEL(2), 0);

    TEST_LR("lsll", "", MK_SEL(2), 0);



    TEST_LR("larw", "w", 0xfff8, 0);

    TEST_LR("larl", "", 0xfff8, 0);

    TEST_LR("lslw", "w", 0xfff8, 0);

    TEST_LR("lsll", "", 0xfff8, 0);



    TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1);

    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3);

    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1);

}

void FUNC_0(void)

{

    struct modify_ldt_ldt_s VAR_0;

    long long VAR_1[3];

    int VAR_2, VAR_3;

    char VAR_4;

    struct {

        uint32_t offset;

        uint16_t seg;

    } __attribute__((packed)) VAR_5;



    VAR_0.entry_number = 1;

    VAR_0.base_addr = (unsigned long)&seg_data1;

    VAR_0.limit = (sizeof(seg_data1) + 0xfff) >> 12;

    VAR_0.seg_32bit = 1;

    VAR_0.contents = MODIFY_LDT_CONTENTS_DATA;

    VAR_0.read_exec_only = 0;

    VAR_0.limit_in_pages = 1;

    VAR_0.seg_not_present = 0;

    VAR_0.useable = 1;

    modify_ldt(1, &VAR_0, sizeof(VAR_0)); 



    VAR_0.entry_number = 2;

    VAR_0.base_addr = (unsigned long)&seg_data2;

    VAR_0.limit = (sizeof(seg_data2) + 0xfff) >> 12;

    VAR_0.seg_32bit = 1;

    VAR_0.contents = MODIFY_LDT_CONTENTS_DATA;

    VAR_0.read_exec_only = 0;

    VAR_0.limit_in_pages = 1;

    VAR_0.seg_not_present = 0;

    VAR_0.useable = 1;

    modify_ldt(1, &VAR_0, sizeof(VAR_0)); 



    modify_ldt(0, &VAR_1, sizeof(VAR_1)); 

#if 0

    {

        int i;

        for(i=0;i<3;i++)

            printf("%d: %016Lx\n", i, VAR_1[i]);

    }

#endif

    

    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));



    seg_data1[1] = 0xaa;

    seg_data2[1] = 0x55;



    asm volatile ("fs movzbl 0x1, %0" : "=r" (VAR_2));

    printf("FS[1] = %02x\n", VAR_2);



    asm volatile ("pushl %%gs\n"

                  "movl %1, %%gs\n"

                  "gs movzbl 0x1, %0\n"

                  "popl %%gs\n"

                  : "=r" (VAR_2)

                  : "r" (MK_SEL(2)));

    printf("GS[1] = %02x\n", VAR_2);



    

    VAR_4 = 0xa5;

    asm volatile ("pushl %%ebp\n\t"

                  "pushl %%ds\n\t"

                  "movl %2, %%ds\n\t"

                  "movl %3, %%ebp\n\t"

                  "movzbl 0x1, %0\n\t"

                  "movzbl (%%ebp), %1\n\t"

                  "popl %%ds\n\t"

                  "popl %%ebp\n\t"

                  : "=r" (VAR_2), "=r" (VAR_3)

                  : "r" (MK_SEL(1)), "r" (&VAR_4));

    printf("DS[1] = %02x\n", VAR_2);

    printf("SS[VAR_4] = %02x\n", VAR_3);



    VAR_5.seg = MK_SEL(2);

    VAR_5.offset = 0xabcdef12;

    asm volatile("lfs %2, %0\n\t"

                 "movl %%fs, %1\n\t"

                 : "=r" (VAR_2), "=g" (VAR_3)

                 : "m" (VAR_5));

    printf("FS:reg = %04x:%08x\n", VAR_3, VAR_2);



    TEST_LR("larw", "w", MK_SEL(2), 0x0100);

    TEST_LR("larl", "", MK_SEL(2), 0x0100);

    TEST_LR("lslw", "w", MK_SEL(2), 0);

    TEST_LR("lsll", "", MK_SEL(2), 0);



    TEST_LR("larw", "w", 0xfff8, 0);

    TEST_LR("larl", "", 0xfff8, 0);

    TEST_LR("lslw", "w", 0xfff8, 0);

    TEST_LR("lsll", "", 0xfff8, 0);



    TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1);

    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3);

    TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1);

}

void FUNC_0(void)
{ struct modify_ldt_ldt_s VAR_0; long long VAR_1[3]; int VAR_2, VAR_3; char VAR_4; struct { uint32_t offset; uint16_t seg; } __attribute__((packed)) VAR_5; VAR_0.entry_number = 1; VAR_0.base_addr = (unsigned long)&seg_data1; VAR_0.limit = (sizeof(seg_data1) + 0xfff) >> 12; VAR_0.seg_32bit = 1; VAR_0.contents = MODIFY_LDT_CONTENTS_DATA; VAR_0.read_exec_only = 0; VAR_0.limit_in_pages = 1; VAR_0.seg_not_present = 0; VAR_0.useable = 1; modify_ldt(1, &VAR_0, sizeof(VAR_0)); VAR_0.entry_number = 2; VAR_0.base_addr = (unsigned long)&seg_data2; VAR_0.limit = (sizeof(seg_data2) + 0xfff) >> 12; VAR_0.seg_32bit = 1; VAR_0.contents = MODIFY_LDT_CONTENTS_DATA; VAR_0.read_exec_only = 0; VAR_0.limit_in_pages = 1; VAR_0.seg_not_present = 0; VAR_0.useable = 1; modify_ldt(1, &VAR_0, sizeof(VAR_0)); modify_ldt(0, &VAR_1, sizeof(VAR_1)); #if 0
{ int i; for(i=0;i<3;i++) printf("%d: %016Lx\n", i, VAR_1[i]); } #endif
asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); seg_data1[1] = 0xaa; seg_data2[1] = 0x55; asm volatile ("fs movzbl 0x1, %0" : "=r" (VAR_2)); printf("FS[1] = %02x\n", VAR_2); asm volatile ("pushl %%gs\n"
"movl %1, %%gs\n"
"gs movzbl 0x1, %0\n"
"popl %%gs\n"
: "=r" (VAR_2)
: "r" (MK_SEL(2))); printf("GS[1] = %02x\n", VAR_2); VAR_4 = 0xa5; asm volatile ("pushl %%ebp\n\t"
"pushl %%ds\n\t"
"movl %2, %%ds\n\t"
"movl %3, %%ebp\n\t"
"movzbl 0x1, %0\n\t"
"movzbl (%%ebp), %1\n\t"
"popl %%ds\n\t"
"popl %%ebp\n\t"
: "=r" (VAR_2), "=r" (VAR_3)
: "r" (MK_SEL(1)), "r" (&VAR_4)); printf("DS[1] = %02x\n", VAR_2); printf("SS[VAR_4] = %02x\n", VAR_3); VAR_5.seg = MK_SEL(2); VAR_5.offset = 0xabcdef12; asm volatile("lfs %2, %0\n\t"
"movl %%fs, %1\n\t"
: "=r" (VAR_2), "=g" (VAR_3)
: "m" (VAR_5)); printf("FS:reg = %04x:%08x\n", VAR_3, VAR_2); TEST_LR("larw", "w", MK_SEL(2), 0x0100); TEST_LR("larl", "", MK_SEL(2), 0x0100); TEST_LR("lslw", "w", MK_SEL(2), 0); TEST_LR("lsll", "", MK_SEL(2), 0); TEST_LR("larw", "w", 0xfff8, 0); TEST_LR("larl", "", 0xfff8, 0); TEST_LR("lslw", "w", 0xfff8, 0); TEST_LR("lsll", "", 0xfff8, 0); TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1); TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3); TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1); }