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. */
| 1748 | * bytes, searching for E8 (callq) opcodes, and dumping the symbols |
| 1749 | * and the call offset if they appear to be valid. */ |
| 1750 | void dumpX86Calls(void *addr, size_t len) { |
| 1751 | size_t j; |
| 1752 | unsigned char *p = addr; |
| 1753 | Dl_info info; |
| 1754 | /* Hash table to best-effort avoid printing the same symbol |
| 1755 | * multiple times. */ |
| 1756 | unsigned long ht[256] = {0}; |
| 1757 | |
| 1758 | if (len < 5) return; |
| 1759 | for (j = 0; j < len-4; j++) { |
| 1760 | if (p[j] != 0xE8) continue; /* Not an E8 CALL opcode. */ |
| 1761 | unsigned long target = (unsigned long)addr+j+5; |
| 1762 | target += *((int32_t*)(p+j+1)); |
| 1763 | if (dladdr((void*)target, &info) != 0 && info.dli_sname != NULL) { |
| 1764 | if (ht[target&0xff] != target) { |
| 1765 | printf("Function at 0x%lx is %s\n",target,info.dli_sname); |
| 1766 | ht[target&0xff] = target; |
| 1767 | } |
| 1768 | j += 4; /* Skip the 32 bit immediate. */ |
| 1769 | } |
| 1770 | } |
| 1771 | } |
| 1772 | |
| 1773 | void dumpCodeAroundEIP(void *eip) { |
| 1774 | Dl_info info; |
no test coverage detected