If mmap is used (as for shared objects), code address at runtime can be arbitrary. This function translates an absolute address into a relative address to the object file it belongs to, based on the current memory mapping of this process.
| 218 | // address to the object file it belongs to, based on the current memory |
| 219 | // mapping of this process. |
| 220 | static uintptr_t GetRelativeAddress(uintptr_t abs_addr) { |
| 221 | Dl_info info; |
| 222 | struct link_map *map; |
| 223 | |
| 224 | if (dladdr1(reinterpret_cast<void *>(abs_addr), &info, |
| 225 | reinterpret_cast<void **>(&map), RTLD_DL_LINKMAP) != 0) { |
| 226 | // Normally the base_addr of the executable will be just 0x0 |
| 227 | uintptr_t base_addr = reinterpret_cast<uintptr_t>(map->l_addr); |
| 228 | return abs_addr - base_addr; |
| 229 | } else { |
| 230 | // Error happend. Use the absolute address as a fallback, hoping the address |
| 231 | // is from the main executable. |
| 232 | return abs_addr; |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | // addr2line must be available. |
| 237 | // Returns the code lines [lineno - context, lineno + context] */ |