Esempio n. 1
0
void
tcElf_tpElfMSB(void)
{
	int fd;
	Elf *e;
	TS_PHDR *ph;

	TP_CHECK_INITIALIZATION();

	tet_infoline("assertion:" TS_ICNAME "(E) returns the correct MSB phdr.");

	TS_OPEN_FILE(e,"phdr.msb" __XSTRING(TS_PHDRSZ),ELF_C_READ,fd);

	if ((ph = TS_ICFUNC(e)) == NULL) {
		tet_infoline("fail: " TS_ICNAME "() failed.");
		tet_result(TET_FAIL);
		return;
	}

	tet_result(check_phdr(ph));

	(void) elf_end(e);
	(void) close(fd);
}
/*
 * Dump crash to file
 */
static int write_elf(Elf32_Ehdr *elfhdr_addr, int fd)
{
	Elf32_Ehdr *oldhdr = elfhdr_addr;
	Elf32_Ehdr *ehdr;
	Elf32_Phdr *phdr;
	u32 i;
	u32 offset;
	u32 tot;
	u32 phdr_cnt;
	u32 notes_cnt = 0;
	u32 save;
	u32 len;

	offset = oldhdr->e_ehsize + oldhdr->e_phentsize * oldhdr->e_phnum;
	ehdr = (Elf32_Ehdr *) malloc(offset);
	if (ehdr == NULL) {
		debug("elf header alloc error\n");
		return -1;
	}
	memcpy(ehdr, oldhdr, offset);

	/*
	 * check program header entries and update length
	 * for merged PT_NOTE segments
	 */
	tot = 0;
	phdr_cnt = ehdr->e_phnum;
	debug("phdr_cnt=%d\n", phdr_cnt);
	for (i = 0; i < phdr_cnt; i++) {
		phdr = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_ehsize +
				       i * ehdr->e_phentsize);
		len = check_phdr(phdr);
		debug("prog hdr %d: %x ad %x len %x adjusted to %x\n",
		      i, (u32) phdr, phdr->p_paddr, phdr->p_filesz, len);
		phdr->p_filesz = len;
		phdr->p_memsz = len;
		if (phdr->p_type == PT_NOTE) {	/* note segment */
			tot += len;
			notes_cnt++;
		}
	}
	debug("Length of %d note segments: %x\n", notes_cnt, tot);

	/*
	 * all PT_NOTE segments have been merged into one.
	 * Update ELF Header accordingly
	 */
	ehdr->e_phnum = phdr_cnt - notes_cnt + 1;

	/* write elf header into file on sdcard */
	if (write_chunk(fd, ehdr, (size_t) ehdr->e_ehsize)) {
		free(ehdr);
		return -1;
	}

	/* write program headers into file on sdcard */
	offset = ehdr->e_ehsize + ehdr->e_phentsize * ehdr->e_phnum;
	debug("Write Phdr: proghdr_cnt=%d\n", phdr_cnt);
	for (i = 0; i < phdr_cnt; i++) {
		phdr = (Elf32_Phdr *) ((char *)ehdr + ehdr->e_ehsize +
				       i * ehdr->e_phentsize);
		save = phdr->p_filesz;
		if (i == 0) {
			phdr->p_filesz = tot;
			phdr->p_memsz = tot;
		} else if (phdr->p_type == PT_NOTE) /* note segment */
			continue;
		phdr->p_offset = offset;
		debug("prog hdr %d: %x ad %x len %x off %x\n",
		       i, (u32) phdr, phdr->p_paddr, phdr->p_filesz,
		       phdr->p_offset);
		offset += phdr->p_filesz;
		if (write_chunk(fd, (void *) phdr, (size_t)
				ehdr->e_phentsize)) {
			free(ehdr);
			return -1;
		}
		phdr->p_filesz = save;
		phdr->p_memsz = save;
	}

	/* write segments into file on sdcard */
	debug("write segments...\n");
	for (i = 0; i < phdr_cnt; i++) {
		phdr = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_ehsize +
				       i * ehdr->e_phentsize);
		if (phdr->p_type > PT_NULL) {
			if (write_big_chunk(fd, (void *) phdr->p_paddr,
							 phdr->p_filesz)) {
				free(ehdr);
				return -1;
			}
		}
	}

	free(ehdr);
	return 0;
}