| 311 | } |
| 312 | |
| 313 | static int |
| 314 | reloc_read(const struct buffer *in, struct parsed_elf *pelf, |
| 315 | struct xdr *xdr, int bit64) |
| 316 | { |
| 317 | struct buffer b; |
| 318 | Elf64_Word i; |
| 319 | Elf64_Ehdr *ehdr; |
| 320 | |
| 321 | ehdr = &pelf->ehdr; |
| 322 | pelf->relocs = calloc(ehdr->e_shnum, sizeof(Elf64_Rela *)); |
| 323 | |
| 324 | /* Allocate array for each section that contains relocation entries. */ |
| 325 | for (i = 0; i < ehdr->e_shnum; i++) { |
| 326 | Elf64_Shdr *shdr; |
| 327 | Elf64_Rela *rela; |
| 328 | Elf64_Xword j; |
| 329 | Elf64_Xword nrelocs; |
| 330 | int is_rela; |
| 331 | |
| 332 | shdr = &pelf->shdr[i]; |
| 333 | |
| 334 | /* Only process REL and RELA sections. */ |
| 335 | if (shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA) |
| 336 | continue; |
| 337 | |
| 338 | DEBUG("Checking relocation section %u\n", i); |
| 339 | |
| 340 | /* Ensure the section that relocations apply is a valid. */ |
| 341 | if (shdr->sh_info >= ehdr->e_shnum || |
| 342 | shdr->sh_info == SHN_UNDEF) { |
| 343 | ERROR("Relocations apply to an invalid section: %u\n", |
| 344 | shdr[i].sh_info); |
| 345 | return -1; |
| 346 | } |
| 347 | |
| 348 | is_rela = shdr->sh_type == SHT_RELA; |
| 349 | |
| 350 | /* Determine the number relocations in this section. */ |
| 351 | nrelocs = shdr->sh_size / shdr->sh_entsize; |
| 352 | |
| 353 | pelf->relocs[i] = calloc(nrelocs, sizeof(Elf64_Rela)); |
| 354 | |
| 355 | buffer_splice(&b, in, shdr->sh_offset, shdr->sh_size); |
| 356 | if (check_size(in, shdr->sh_offset, buffer_size(&b), |
| 357 | "relocation section")) { |
| 358 | ERROR("Relocation section %u failed.\n", i); |
| 359 | return -1; |
| 360 | } |
| 361 | |
| 362 | rela = pelf->relocs[i]; |
| 363 | for (j = 0; j < nrelocs; j++) { |
| 364 | if (bit64) { |
| 365 | rela->r_offset = xdr->get64(&b); |
| 366 | rela->r_info = xdr->get64(&b); |
| 367 | if (is_rela) |
| 368 | rela->r_addend = xdr->get64(&b); |
| 369 | } else { |
| 370 | uint32_t r_info; |
no test coverage detected