.text .global __set_thread_area .type __set_thread_area,@function __set_thread_area: push %ebx push $0x51 push $0xfffff push 16(%esp) call 1f /* ebx : 0x51 : 0xfffff : arg : 1f */ 1: addl $4f-1b,(%esp) /* ebx : 0x51 : 0xfffff : arg : 4f */ pop %ecx mov (%ecx),%edx push %edx /* ebx : 0x51 : 0xfffff : arg : [4f] */ mov %esp,%ebx xor %eax,%eax mov $243,%al int $128 /* set_thread_area({.index = [4f], .base = arg, .limit=0xfffff, .seg32_bits, .limit_in_pages, .usable}) */ testl %eax,%eax jnz 2f /* if that failed, go to 2 */ movl (%esp),%edx movl %edx,(%ecx) /* save index in [4f] */ leal 3(,%edx,8),%edx /* multiply index by 8 to get offset for segment selector, add 3 to get CPL 3 */ 3: movw %dx,%gs 1: addl $16,%esp popl %ebx ret 2: mov %ebx,%ecx xor %ebx,%ebx xor %edx,%edx mov %ebx,(%esp) mov $1,%bl mov $16,%dl mov $123,%al int $128 /* modify_ldt(1, {.index = 0, .base = arg, .limit=0xfffff, .seg32_bits, .limit_in_pages, .usable}, 16)*/ testl %eax,%eax jnz 1b /* if that failed, just clean up and return */ mov $7,%dl /* else the segment selector has offset 0, is in the LDT, and CPL 3 */ inc %al /* and return 1 */ jmp 3b .data .align 4 4: .long -1