;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;; Working with program symbols ;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; include 'sort.inc' ; compare proc for sorter compare: cmpsd jnz @f cmp esi, edi @@: ret ; compare proc for sorter 2 compare2: cmpsd @@: cmpsb jnz @f cmp byte [esi-1], 0 jnz @b cmp esi, edi @@: ret free_symbols: mov ecx, [symbols] jecxz @f mcall 68, 13 and [symbols], 0 and [num_symbols], 0 @@: ret ;----------------------------------------------------------------------------- ; Load symbols event OnLoadSymbols.fileerr: test ebp, ebp jz @f mcall 68, 13, edi ret @@: push eax mcall 68, 13, edi mov esi, aCannotLoadFile call put_message_nodraw pop eax cmp eax, 0x20 jae .unk mov esi, [load_err_msgs + eax*4] test esi, esi jnz put_message .unk: mov esi, unk_err_msg2 jmp put_message OnLoadSymbols: xor ebp, ebp ; load input file mov esi, [curarg] call free_symbols .silent: ; esi = ptr to symbols filename xor edi, edi cmp [num_symbols], edi ; Any previously loaded symbols? je .loadfile call free_symbols ; Yep, free them .loadfile: mov ebx, fn70_attr_block ; Get file attributes mov [ebx+21], esi mcall 70 test eax, eax jnz .fileerr cmp dword [fileattr+36], edi ; Is upper dword of filesize larger then 0? jnz .memerr mov ecx, dword [fileattr+32] ; Lower dword of filesize mcall 68, 12 ; allocate the memory test eax, eax jz .memerr mov edi, eax mov ebx, fn70_read_block mov [ebx+12], ecx mov [ebx+16], edi mov [ebx+21], esi mcall 70 ; Read the file into the allocated buffer test eax, eax jnz .fileerr ; calculate memory requirements to load debug symbols lea edx, [ecx+edi-1] ; edx = EOF-1 mov esi, edi xor ecx, ecx mov [symbol_section], 1 ;;;;; .calcloop: cmp esi, edx jae .calcdone cmp byte[esi], ' ' ; skip spaces at the beginning of a line jne .not_space inc esi jmp .calcloop .not_space: cmp byte[esi], '.' jne .not_section inc esi mov [symbol_section], 0 cmp dword[esi], 'text' je .section_ok cmp dword[esi], 'data' je .section_ok cmp dword[esi], 'bss ' jne .skipline .section_ok: inc [symbol_section] jmp .skipline .not_section: cmp [symbol_section], 0 je .skipline cmp word[esi], '0x' jne .skipline inc esi inc esi @@: cmp esi, edx jae .calcdone lodsb or al, 20h sub al, '0' cmp al, 9 jbe @b sub al, 'a'-'0'-10 cmp al, 15 jbe @b dec esi @@: cmp esi, edx ja .calcdone lodsb cmp al, 20h je @b jb .calcloop cmp al, 9 jz @b add ecx, 12+1 inc [num_symbols] @@: inc ecx cmp esi, edx ja .calcdone lodsb cmp al, 0xD jz .calcloop cmp al, 0xA jz .calcloop jmp @b .skipline: cmp esi, edx jae .calcdone lodsb cmp al, 0xD jz .calcloop cmp al, 0xA jz .calcloop jmp .skipline .calcdone: ; Allocate memory to place the debug symbols in mcall 68, 12 test eax, eax jnz .memok inc ebx mov ecx, edi mov al, 68 mcall .memerr: mov esi, aNoMemory jmp put_message .memok: mov [symbols], eax mov ebx, eax push edi mov esi, edi mov edi, [num_symbols] lea ebp, [eax+edi*4] lea edi, [eax+edi*8] ; Actual loading of the debug symbols ; esi->input, edx->EOF, ebx->ptrs, edi->names mov [symbol_section], 1 ;;;;; .readloop: cmp esi, edx jae .readdone cmp byte[esi], ' ' jne .not_space2 inc esi jmp .readloop .not_space2: cmp byte[esi], '.' jne .not_section2 inc esi mov [symbol_section], 0 cmp dword[esi], 'text' je .section_ok2 cmp dword[esi], 'data' je .section_ok2 cmp dword[esi], 'bss ' jne .readline .section_ok2: inc [symbol_section] jmp .readline .not_section2: cmp [symbol_section], 0 je .readline cmp word[esi], '0x' jnz .readline inc esi inc esi xor eax, eax xor ecx, ecx @@: shl ecx, 4 add ecx, eax cmp esi, edx jae .readdone lodsb or al, 20h sub al, '0' cmp al, 9 jbe @b sub al, 'a'-'0'-10 cmp al, 15 jbe @b dec esi @@: cmp esi, edx ja .readdone lodsb cmp al, 20h jz @b jb .readloop cmp al, 9 jz @b mov dword [ebx], edi add ebx, 4 mov dword [ebp], edi add ebp, 4 mov dword [edi], ecx add edi, 4 stosb @@: xor eax, eax stosb cmp esi, edx ja .readdone lodsb cmp al, 0xD jz .readloop cmp al, 0xA jz .readloop mov byte [edi-1], al jmp @b .readline: cmp esi, edx jae .readdone lodsb cmp al, 0xD jz .readloop cmp al, 0xA jz .readloop jmp .readline .readdone: pop ecx mcall 68, 13 mov ecx, [num_symbols] mov edx, [symbols] mov ebx, compare call sort mov ecx, [num_symbols] lea edx, [edx+ecx*4] mov ebx, compare2 call sort mov esi, aSymbolsLoaded call put_message jmp draw_disasm ;----------------------------------------------------------------------------- ; ; in: EAX = address ; out: ESI, CF find_symbol: cmp [num_symbols], 0 jnz @f .ret0: xor esi, esi stc ret @@: push ebx ecx edx xor edx, edx mov esi, [symbols] mov ecx, [num_symbols] mov ebx, [esi] cmp [ebx], eax jz .donez jb @f pop edx ecx ebx jmp .ret0 @@: ; invariant: symbols_addr[edx] < eax < symbols_addr[ecx] ; TODO: add meaningful label names .0: push edx .1: add edx, ecx sar edx, 1 cmp edx, [esp] jz .done2 mov ebx, [esi+edx*4] cmp [ebx], eax jz .done ja .2 mov [esp], edx jmp .1 .2: mov ecx, edx pop edx jmp .0 .donecont: dec edx .done: test edx, edx jz @f mov ebx, [esi+edx*4-4] cmp [ebx], eax jz .donecont @@: pop ecx .donez: mov esi, [esi+edx*4] add esi, 4 pop edx ecx ebx clc ret .done2: lea esi, [esi+edx*4] pop ecx edx ecx ebx stc ret ;----------------------------------------------------------------------------- ; ; in: esi->name ; out: if found: CF = 0, EAX = value ; otherwise CF = 1 find_symbol_name: cmp [num_symbols], 0 jnz @f .stc_ret: stc ret @@: push ebx ecx edx edi push -1 pop edx mov ebx, [symbols] mov ecx, [num_symbols] lea ebx, [ebx+ecx*4] ; invariant: symbols_name[edx] < name < symbols_name[ecx] .0: push edx .1: add edx, ecx sar edx, 1 cmp edx, [esp] jz .done2 call .cmp jz .done jb .2 mov [esp], edx jmp .1 .2: mov ecx, edx pop edx jmp .0 .done: pop ecx .donez: mov eax, [ebx+edx*4] mov eax, [eax] pop edi edx ecx ebx clc ret .done2: pop edx edi edx ecx ebx stc ret .cmp: mov edi, [ebx+edx*4] push esi add edi, 4 @@: cmpsb jnz @f cmp byte [esi-1], 0 jnz @b @@: pop esi ret