(addr)
| 98 | |
| 99 | // resolve(addr) -> { lib, text } (lib may be null if unknown) |
| 100 | function resolve(addr) { |
| 101 | if (!addr || addr.isNull()) return { lib: null, text: "(null)" }; |
| 102 | const key = addr.toString(); |
| 103 | const hit = symCache.get(key); |
| 104 | if (hit) return hit; |
| 105 | |
| 106 | let out = { lib: null, text: key }; |
| 107 | if (dladdr) { |
| 108 | try { |
| 109 | if (dladdr(addr, dlInfo) !== 0) { |
| 110 | const fname = dlInfo.readPointer(); |
| 111 | const fbase = dlInfo.add(8).readPointer(); |
| 112 | const sname = dlInfo.add(16).readPointer(); |
| 113 | const saddr = dlInfo.add(24).readPointer(); |
| 114 | const lib = fname.isNull() ? null : (fname.readCString() || "").split("/").pop(); |
| 115 | let text; |
| 116 | if (!sname.isNull()) { |
| 117 | const nm = sname.readCString(); |
| 118 | const off = addr.sub(saddr); |
| 119 | text = off.compare(0) === 0 ? `${nm} @ ${lib}` : `${nm}+0x${off.toString(16)} @ ${lib}`; |
| 120 | } else if (lib) { |
| 121 | text = `${lib}+0x${addr.sub(fbase).toString(16)}`; |
| 122 | } else { |
| 123 | text = key; |
| 124 | } |
| 125 | out = { lib, text }; |
| 126 | } |
| 127 | } catch (e) {} |
| 128 | } |
| 129 | symCache.set(key, out); |
| 130 | return out; |
| 131 | } |
| 132 | |
| 133 | // routineModuleOffset(addr) -> { module, offset } using the module table. |
| 134 | function routineModuleOffset(addr) { |
no test coverage detected