//------------------------------------------------------------------ // segvtrap.s // // This example shows how a signal-handler can be used to help // diagnose the cause of a 'Segmentation Violation" exception. // // to assemble: $ as segvtrap.s -o segvtrap.o // and to link: $ ld segvtrap.o -o segvtrap // // programmer: ALLAN CRUSE // written on: 15 APR 2007 //------------------------------------------------------------------ # manifest constants .equ sys_EXIT, 1 .equ sys_WRITE, 4 .equ sys_SIGNAL, 48 .equ SIGSEGV, 11 .equ STDOUT, 1 .section .text _start: # install our signal-handling function mov $sys_SIGNAL, %eax # system-call ID-number mov $SIGSEGV, %ebx # signal-number to catch lea action, %ecx # signal-handler address int $0x80 # invoke kernel service or %eax, %eax # successfully installed? jnz exit # no, exit program early # setup some recognizable register-values mov $0xAAAAAAAA, %eax mov $0xBBBBBBBB, %ebx mov $0xCCCCCCCC, %ecx mov $0xDDDDDDDD, %edx mov $0xEEEEEEEE, %esi mov $0xFFFFFFFF, %edi mov $0x12345678, %ebp # now try to execute a 'privileged' instruction hlt # to trigger a segfault exit: # terminate this program mov $sys_EXIT, %eax # system-call ID-number mov $0, %ebx # setup our return-code int $0x80 # invoke kernel service .section .data names: .ascii " sig GS FS ES DS" .ascii " EDI ESI EBP ESP EBX EDX ECX EAX" .ascii " int err EIP CS EFL ESP SS" buf: .ascii " nnn=xxxxxxxx \n" len: .int . - buf msg: .ascii "\n [CS:EIP] " ops: .ascii "xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx \n" osz: .int . - msg .section .text action: # this is the entry-point to our signal-handler push %ebp mov %esp, %ebp # setup stackframe access mov $19, %esi # initial element-number nxelt: # format the element-name mov names(, %esi, 4), %eax # lookup element-name mov %eax, buf # store name in buffer # format the element-value mov 8(%ebp, %esi, 4), %eax # lookup element-value lea buf+5, %edi # point to dest'n field call eax2hex # convert value to hex # write the buffer to standard-output mov $sys_WRITE, %eax # system-call ID-number mov $STDOUT, %ebx # device-file ID-number lea buf, %ecx # address of string mov len, %edx # length of string int $0x80 # invoke kernel service dec %esi # decrement element-number jns nxelt # again if non-negative # exhibit the faulting instruction's machine-code mov 68(%ebp), %esi # EIP-image into ESI lea ops, %edi # point to dest'n buffer mov $15, %ecx # number of bytes to show lea hex, %ebx # setup EBX for 'xlat' cld # do forward processing nxbyt: lodsb # instruction-byte into AL xor %ah, %ah # clear adjacent register ror $4, %ax # rotate register-pair ror $4, %ah # rotate upper-register xlat # convert AL to numeral stosb # and store to buffer xchg %ah, %al # exchange registers xlat # convert AL to numeral stosb # and store to buffer inc %edi # advance buffer-pointer loop nxbyt # again for other bytes # write the buffer to standard-output mov $sys_WRITE, %eax # system-call ID-number mov $STDOUT, %ebx # device-file ID-number lea msg, %ecx # address of message mov osz, %edx # length of message int $0x80 # invoke kernel service # terminate this program jmp exit # back to 'bash' shell hex: .ascii "0123456789ABCDEF" # translation-table eax2hex: # converts the value in EAX to a hexadecimal string at EDI pushal mov $8, %ecx nxnyb: rol $4, %eax mov %al, %bl and $0xF, %ebx mov hex(%ebx), %dl mov %dl, (%edi) inc %edi loop nxnyb popal ret .global _start .end