home *** CD-ROM | disk | FTP | other *** search
- ; Return the name of the (2nd level) caller of the caller.
- ;
- ; e.g. if you have (in C)
- ;
- ; void foo (void)
- ; {
- ; bar();
- ; }
- ;
- ; void bar (void)
- ; {
- ; char *func = caller();
- ; }
- ;
- ; func should contain "bar".
- ;
- a1 RN 0
- a2 RN 1
- a3 RN 2
- a4 RN 3
- v1 RN 4
- v2 RN 5
- v3 RN 6
- v4 RN 7
- v5 RN 8
- v6 RN 9
- fp RN 10
- ip RN 11
- sp RN 12
- sl RN 13
- lk RN 14
- pc RN 15
-
- AREA |Caller|, CODE, READONLY
-
- name
- DCB "caller",0
- ALIGN
- DCD &FF000000 :OR: ( {PC} - name )
-
- EXPORT caller
-
- caller
- TEQ fp, #0 ; If frame pointer is 0 then
- ADREQ a1, null ; there is no backtrace structure
- MOVEQS pc, lk
-
- LDR a1, [fp, #-12] ; Get caller's frame pointer
- TEQ a1, #0 ; If 0, no backtrace structure
- ADREQ a1, null
- MOVEQS pc, lk
-
- LDR a1, [a1] ; Get caller's PC (return data save)
- BIC a1, a1, #&FC000003 ; Convert to an address
- SUB a1, a1, #12 ; Go to return data save instruction
-
- prev LDR a2, [a1, #-4]! ; Get previous word
- MOV a3, a2, LSR #24 ; Test top 8 bits
- TEQ a3, #&FF ; If they're FF, we've found the name
- BNE prev
-
- BIC a2, a2, #&FF000000 ; Get the name offset
- SUB a1, a1, a2 ; Point to the caller's name
- MOVS pc, lk ; Return
-
- null
- DCB "",0
- ALIGN
-
- END
-