| 77 | } |
| 78 | |
| 79 | std::optional<std::pair<void*, size_t>> robaseby(dev_t dev, ino_t ino) { |
| 80 | struct State { |
| 81 | dev_t dev; |
| 82 | ino_t ino; |
| 83 | std::optional<std::pair<void*, size_t>> result; |
| 84 | } state = { dev, ino }; |
| 85 | |
| 86 | dl_iterate_phdr([](struct dl_phdr_info* info, size_t, void* data) -> int { |
| 87 | auto* s = static_cast<State*>(data); |
| 88 | |
| 89 | struct stat st{}; |
| 90 | if (stat(info->dlpi_name, &st) != 0) |
| 91 | return 0; |
| 92 | |
| 93 | if (st.st_dev != s->dev || st.st_ino != s->ino) |
| 94 | return 0; |
| 95 | |
| 96 | for (int i = 0; i < info->dlpi_phnum; ++i) { |
| 97 | const auto& phdr = info->dlpi_phdr[i]; |
| 98 | if (phdr.p_type == PT_LOAD && |
| 99 | (phdr.p_flags & PF_R) && |
| 100 | !(phdr.p_flags & PF_X)) // r--p only |
| 101 | { |
| 102 | uintptr_t base = info->dlpi_addr + phdr.p_vaddr; |
| 103 | size_t size = phdr.p_memsz; |
| 104 | s->result = std::make_pair(reinterpret_cast<void*>(base), size); |
| 105 | return 1; // Stop searching |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | return 0; |
| 110 | }, &state); |
| 111 | |
| 112 | return state.result; |
| 113 | } |
| 114 | |
| 115 | int forkcall(const std::function<int()> &lambda) |
| 116 | { |