* Load a set of maps. */
| 179 | * Load a set of maps. |
| 180 | */ |
| 181 | static NO_INLINE void e9load_maps(const e9_map_s *maps, uint32_t num_maps, |
| 182 | const uint8_t *elf_base, int fd, mmap_t mmap) |
| 183 | { |
| 184 | for (uint32_t i = 0; i < num_maps; i++) |
| 185 | { |
| 186 | const uint8_t *addr = (maps[i].abs? (const uint8_t *)NULL: elf_base); |
| 187 | addr += (intptr_t)maps[i].addr * PAGE_SIZE; |
| 188 | size_t len = (size_t)maps[i].size * PAGE_SIZE; |
| 189 | off_t offset = (off_t)maps[i].offset * PAGE_SIZE; |
| 190 | int prot = (maps[i].r? PROT_READ: 0x0) | |
| 191 | (maps[i].w? PROT_WRITE: 0x0) | |
| 192 | (maps[i].x? PROT_EXEC: 0x0); |
| 193 | int flags = MAP_FIXED | MAP_PRIVATE; |
| 194 | #if 0 |
| 195 | e9debug("mmap(addr=%p,size=%U,offset=+%U,prot=%c%c%c)", |
| 196 | addr, len, offset, |
| 197 | (maps[i].r? 'r': '-'), (maps[i].w? 'w': '-'), |
| 198 | (maps[i].x? 'x': '-')); |
| 199 | #endif |
| 200 | intptr_t result = mmap((void *)addr, len, prot, flags, fd, offset); |
| 201 | if (result < 0) |
| 202 | e9panic("mmap(addr=%p,size=%U,offset=+%U,prot=%c%c%c) failed " |
| 203 | "(errno=%u)%s", addr, len, offset, |
| 204 | (maps[i].r? 'r': '-'), (maps[i].w? 'w': '-'), |
| 205 | (maps[i].x? 'x': '-'), -(int)result, |
| 206 | (-(int)result == ENOMEM? |
| 207 | "\nhint: see the e9patch manpage for more information.": |
| 208 | "")); |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | /* |
| 213 | * Signal handler. |