/* Load phdrs and scns included in the sections. scns will be sorted. */ seg_t *getSegs(FILE *fp, const char *path, Elf32_Ehdr *ehdr, const scn_t *scns) { Elf32_Half i, j, k; scn_t *tmp; seg_t *segs; if (fp == NULL || path == NULL || ehdr == NULL || scns == NULL) return NULL; segs = malloc(ehdr->e_phnum * sizeof(seg_t)); if (segs == NULL) { perror(path); return NULL; } if (fseek(fp, ehdr->e_phoff, SEEK_SET)) { perror(path); return NULL; } i = 0; while (i < ehdr->e_phnum) { if (fread(&segs[i].phdr, sizeof(segs[i].phdr), 1, fp) <= 0) { perror(path); free(segs); return NULL; } if (segs[i].phdr.p_type == PT_ARM_EXIDX) ehdr->e_phnum--; else { segs[i].shnum = 0; i++; } } mapOverScnSeg(segCntScns, (scn_t *)scns, segs, ehdr); for (i = 0; i < ehdr->e_phnum; i++) { segs[i].scns = malloc(segs[i].shnum * sizeof(scn_t)); if (segs[i].scns == NULL) { perror(NULL); while (i) { i--; free(segs[i].scns); } free(segs); return NULL; } segs[i].shnum = 0; } mapOverScnSeg(segCntMapScns, (scn_t *)scns, segs, ehdr); for (i = 0; i < ehdr->e_phnum; i++) { if (segs[i].phdr.p_type != PT_LOAD) continue; for (j = 1; j < segs[i].shnum; j++) { tmp = segs[i].scns[j]; if (segs[i].scns[j - 1]->shdr.sh_addr > tmp->shdr.sh_addr) { k = j; do { segs[i].scns[k] = segs[i].scns[k - 1]; k--; } while (k > 0 && segs[i].scns[k - 1]->shdr.sh_addr > tmp->shdr.sh_addr); segs[i].scns[k] = tmp; } } } return segs; }
/* Load phdrs and scns included in the sections. scns will be sorted. */ seg_t *getSegs(FILE *fp, const char *path, Elf32_Ehdr *ehdr, scn_t *scns, seg_t **rela, const scn_t *relMark) { Elf32_Half i, j, k, relaPhndx; scn_t *tmp; seg_t *segs; if (fp == NULL || path == NULL || ehdr == NULL || scns == NULL || rela == NULL || relMark == NULL) { return NULL; } segs = malloc(ehdr->e_phnum * sizeof(seg_t)); if (segs == NULL) { perror(path); return NULL; } if (fseek(fp, ehdr->e_phoff, SEEK_SET)) { perror(path); return NULL; } i = 0; relaPhndx = 0; while (i < ehdr->e_phnum) { if (fread(&segs[i].phdr, sizeof(segs[i].phdr), 1, fp) <= 0) { if (feof(fp)) { fprintf(stderr, "%s: Unexpected EOF\n", path); errno = EILSEQ; } else perror(path); free(segs); return NULL; } switch (segs[i].phdr.p_type) { case PT_ARM_EXIDX: ehdr->e_phnum--; break; case 0x60000000: relaPhndx = i; default: segs[i].shnum = 0; i++; } } if (relaPhndx == 0) { fprintf(stderr, "%s: PT_PSP2_RELA not found\n", path); errno = EILSEQ; free(segs); return NULL; } *rela = segs + relaPhndx; mapOverScnSeg(segCntScns, scns, segs, ehdr, relaPhndx, relMark); for (i = 0; i < ehdr->e_phnum; i++) { segs[i].scns = malloc(segs[i].shnum * sizeof(scn_t)); if (segs[i].scns == NULL) { perror(NULL); while (i) { i--; free(segs[i].scns); } free(segs); return NULL; } segs[i].shnum = 0; } mapOverScnSeg(segCntMapScns, scns, segs, ehdr, relaPhndx, relMark); for (i = 0; i < ehdr->e_phnum; i++) { if (segs[i].phdr.p_type != PT_LOAD) continue; for (j = 1; j < segs[i].shnum; j++) { tmp = segs[i].scns[j]; if (segs[i].scns[j - 1]->shdr.sh_addr > tmp->shdr.sh_addr) { k = j; do { segs[i].scns[k] = segs[i].scns[k - 1]; k--; } while (k > 0 && segs[i].scns[k - 1]->shdr.sh_addr > tmp->shdr.sh_addr); segs[i].scns[k] = tmp; } } } return segs; }