Beispiel #1
0
/* 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;
}
Beispiel #2
0
/* 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;
}