Scans the (assumed) x86 code starting at addr, for a max of `len` * bytes, searching for E8 (callq) opcodes, and dumping the symbols * and the call offset if they appear to be valid. */
| 1970 | * bytes, searching for E8 (callq) opcodes, and dumping the symbols |
| 1971 | * and the call offset if they appear to be valid. */ |
| 1972 | void dumpX86Calls(void *addr, size_t len) { |
| 1973 | size_t j; |
| 1974 | unsigned char *p = (unsigned char*)addr; |
| 1975 | Dl_info info; |
| 1976 | /* Hash table to best-effort avoid printing the same symbol |
| 1977 | * multiple times. */ |
| 1978 | unsigned long ht[256] = {0}; |
| 1979 | |
| 1980 | if (len < 5) return; |
| 1981 | for (j = 0; j < len-4; j++) { |
| 1982 | if (p[j] != 0xE8) continue; /* Not an E8 CALL opcode. */ |
| 1983 | unsigned long target = (unsigned long)addr+j+5; |
| 1984 | target += *((int32_t*)(p+j+1)); |
| 1985 | if (dladdr((void*)target, &info) != 0 && info.dli_sname != NULL) { |
| 1986 | if (ht[target&0xff] != target) { |
| 1987 | printf("Function at 0x%lx is %s\n",target,info.dli_sname); |
| 1988 | ht[target&0xff] = target; |
| 1989 | } |
| 1990 | j += 4; /* Skip the 32 bit immediate. */ |
| 1991 | } |
| 1992 | } |
| 1993 | } |
| 1994 | |
| 1995 | void dumpCodeAroundEIP(void *eip) { |
| 1996 | Dl_info info; |