Пример #1
0
Файл: elf.c Проект: BlueYing/go
ElfShdr *
elfwritenotehdr(char *str, uint32 namesz, uint32 descsz, uint32 tag)
{
	ElfShdr *sh;
	
	sh = elfshname(str);

	// Write Elf_Note header.
	cseek(sh->off);
	LPUT(namesz);
	LPUT(descsz);
	LPUT(tag);

	return sh;
}
Пример #2
0
int
elfwriteinterp(vlong stridx)
{
	ElfShdr *sh = nil;
	int i;

	for(i = 0; i < hdr.shnum; i++)
		if(shdr[i]->name == stridx)
			sh = shdr[i];
	if(sh == nil || interp == nil)
		return 0;

	cseek(sh->off);
	cwrite(interp, sh->size);
	return sh->size;
}
Пример #3
0
Файл: pe.c Проект: rosrad/go-rep
static void
pewrite(void)
{
	cseek(0);
	cwrite(dosstub, sizeof dosstub);
	strnput("PE", 4);
	// TODO: This code should not assume that the
	// memory representation is little-endian or
	// that the structs are packed identically to
	// their file representation.
	cwrite(&fh, sizeof fh);
	if(pe64)
		cwrite(&oh64, sizeof oh64);
	else
		cwrite(&oh, sizeof oh);
	cwrite(sh, nsect * sizeof sh[0]);
}
Пример #4
0
int
elfwritenetbsdsig(vlong stridx) {
	ElfShdr *sh = nil;
	int i;

	for(i = 0; i < hdr.shnum; i++)
		if(shdr[i]->name == stridx)
			sh = shdr[i];
	if(sh == nil)
		return 0;

	// Write Elf_Note header followed by NetBSD string.
	cseek(sh->off);
	LPUT(ELF_NOTE_NETBSD_NAMESZ);
	LPUT(ELF_NOTE_NETBSD_DESCSZ);
	LPUT(ELF_NOTE_TYPE_NETBSD_TAG);
	cwrite(ELF_NOTE_NETBSD_NAME, 8);
	LPUT(ELF_NOTE_NETBSD_VERSION);

	return sh->size;
}
Пример #5
0
unsigned int
check_xdelta1_magic(cfile *patchf)
{
	unsigned char buff[XDELTA_MAGIC_LEN];
	cseek(patchf, 0, CSEEK_FSTART);
	if(XDELTA_MAGIC_LEN != cread(patchf, buff, XDELTA_MAGIC_LEN)) {
		return 0;
	}
	if(memcmp(buff, XDELTA_110_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 2;
	} else if (memcmp(buff, XDELTA_104_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	} else if (memcmp(buff, XDELTA_100_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	} else if (memcmp(buff, XDELTA_020_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	} else if (memcmp(buff, XDELTA_018_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	} else if (memcmp(buff, XDELTA_014_MAGIC, XDELTA_MAGIC_LEN)==0) {
		return 1;
	}
	return 0;
}
Пример #6
0
// load into memory and return a pointer to the section of type 'type',
// or NULL if the file doesn't have a section of that type.
uint8_t *SIFLoader::FindSection(int type, int *length_out)
{
	// try and find the section in the index
	for(int i=0;;i++)
	{
		SIFIndexEntry *entry = (SIFIndexEntry *)fIndex.ItemAt(i);
		if (!entry) break;
		
		if (entry->type == type)
		{	// got it!
			
			// haven't loaded it yet? need to fetch it from file?
			if (!entry->data)
			{
				if (!fFP)
				{
					NX_ERR("SIFLoader::FindSection: entry found and need to load it, but file handle closed\n");
					if (length_out) *length_out = 0;
					return NULL;
				}
				
				NX_LOG("Loading SIF section %d from address %04x\n", type, entry->foffset);
				
				entry->data = (uint8_t *)malloc(entry->length);
				cseek(fFP, entry->foffset, SEEK_SET);
				cread(entry->data, entry->length, 1, fFP);
			}
			
			if (length_out) *length_out = entry->length;
			return entry->data;
		}
	}
	
	if (length_out) *length_out = 0;
	return NULL;
}
Пример #7
0
void
asmbelf(vlong symo)
{
	int a, o;
	vlong startva, resoff;
	ElfEhdr *eh;
	ElfPhdr *ph, *pph, *pnote;
	ElfShdr *sh;
	Section *sect;

	eh = getElfEhdr();
	switch(thechar) {
	default:
		diag("unknown architecture in asmbelf");
		errorexit();
	case '5':
		eh->machine = EM_ARM;
		break;
	case '6':
		eh->machine = EM_X86_64;
		break;
	case '8':
		eh->machine = EM_386;
		break;
	}

	startva = INITTEXT - HEADR;
	resoff = ELFRESERVE;
	
	pph = nil;
	if(isobj) {
		/* skip program headers */
		eh->phoff = 0;
		eh->phentsize = 0;
		goto elfobj;
	}

	/* program header info */
	pph = newElfPhdr();
	pph->type = PT_PHDR;
	pph->flags = PF_R + PF_X;
	pph->off = eh->ehsize;
	pph->vaddr = INITTEXT - HEADR + pph->off;
	pph->paddr = INITTEXT - HEADR + pph->off;
	pph->align = INITRND;

	/*
	 * PHDR must be in a loaded segment. Adjust the text
	 * segment boundaries downwards to include it.
	 */
	o = segtext.vaddr - pph->vaddr;
	segtext.vaddr -= o;
	segtext.len += o;
	o = segtext.fileoff - pph->off;
	segtext.fileoff -= o;
	segtext.filelen += o;

	if(!debug['d']) {
		/* interpreter */
		sh = elfshname(".interp");
		sh->type = SHT_PROGBITS;
		sh->flags = SHF_ALLOC;
		sh->addralign = 1;
		if(interpreter == nil) {
			switch(HEADTYPE) {
			case Hlinux:
				interpreter = linuxdynld;
				break;
			case Hfreebsd:
				interpreter = freebsddynld;
				break;
			case Hnetbsd:
				interpreter = netbsddynld;
				break;
			case Hopenbsd:
				interpreter = openbsddynld;
				break;
			}
		}
		resoff -= elfinterp(sh, startva, resoff, interpreter);

		ph = newElfPhdr();
		ph->type = PT_INTERP;
		ph->flags = PF_R;
		phsh(ph, sh);
	}

	pnote = nil;
	if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
		sh = nil;
		switch(HEADTYPE) {
		case Hnetbsd:
			sh = elfshname(".note.netbsd.ident");
			resoff -= elfnetbsdsig(sh, startva, resoff);
			break;
		case Hopenbsd:
			sh = elfshname(".note.openbsd.ident");
			resoff -= elfopenbsdsig(sh, startva, resoff);
			break;
		}

		pnote = newElfPhdr();
		pnote->type = PT_NOTE;
		pnote->flags = PF_R;
		phsh(pnote, sh);
	}

	if(buildinfolen > 0) {
		sh = elfshname(".note.gnu.build-id");
		resoff -= elfbuildinfo(sh, startva, resoff);

		if(pnote == nil) {
			pnote = newElfPhdr();
			pnote->type = PT_NOTE;
			pnote->flags = PF_R;
		}
		phsh(pnote, sh);
	}

	// Additions to the reserved area must be above this line.
	USED(resoff);

	elfphload(&segtext);
	elfphload(&segdata);

	/* Dynamic linking sections */
	if(!debug['d']) {	/* -d suppresses dynamic loader format */
		sh = elfshname(".dynsym");
		sh->type = SHT_DYNSYM;
		sh->flags = SHF_ALLOC;
		if(PtrSize == 8)
			sh->entsize = ELF64SYMSIZE;
		else
			sh->entsize = ELF32SYMSIZE;
		sh->addralign = PtrSize;
		sh->link = elfshname(".dynstr")->shnum;
		// sh->info = index of first non-local symbol (number of local symbols)
		shsym(sh, lookup(".dynsym", 0));

		sh = elfshname(".dynstr");
		sh->type = SHT_STRTAB;
		sh->flags = SHF_ALLOC;
		sh->addralign = 1;
		shsym(sh, lookup(".dynstr", 0));

		if(elfverneed) {
			sh = elfshname(".gnu.version");
			sh->type = SHT_GNU_VERSYM;
			sh->flags = SHF_ALLOC;
			sh->addralign = 2;
			sh->link = elfshname(".dynsym")->shnum;
			sh->entsize = 2;
			shsym(sh, lookup(".gnu.version", 0));
			
			sh = elfshname(".gnu.version_r");
			sh->type = SHT_GNU_VERNEED;
			sh->flags = SHF_ALLOC;
			sh->addralign = PtrSize;
			sh->info = elfverneed;
			sh->link = elfshname(".dynstr")->shnum;
			shsym(sh, lookup(".gnu.version_r", 0));
		}

		switch(eh->machine) {
		case EM_X86_64:
			sh = elfshname(".rela.plt");
			sh->type = SHT_RELA;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF64RELASIZE;
			sh->addralign = PtrSize;
			sh->link = elfshname(".dynsym")->shnum;
			sh->info = elfshname(".plt")->shnum;
			shsym(sh, lookup(".rela.plt", 0));

			sh = elfshname(".rela");
			sh->type = SHT_RELA;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF64RELASIZE;
			sh->addralign = 8;
			sh->link = elfshname(".dynsym")->shnum;
			shsym(sh, lookup(".rela", 0));
			break;
		
		default:
			sh = elfshname(".rel.plt");
			sh->type = SHT_REL;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF32RELSIZE;
			sh->link = elfshname(".dynsym")->shnum;
			shsym(sh, lookup(".rel.plt", 0));

			sh = elfshname(".rel");
			sh->type = SHT_REL;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF32RELSIZE;
			sh->addralign = 4;
			sh->link = elfshname(".dynsym")->shnum;
			shsym(sh, lookup(".rel", 0));
			break;
		}

		sh = elfshname(".plt");
		sh->type = SHT_PROGBITS;
		sh->flags = SHF_ALLOC+SHF_EXECINSTR;
		if(eh->machine == EM_X86_64)
			sh->entsize = 16;
		else
			sh->entsize = 4;
		sh->addralign = 4;
		shsym(sh, lookup(".plt", 0));

		sh = elfshname(".got");
		sh->type = SHT_PROGBITS;
		sh->flags = SHF_ALLOC+SHF_WRITE;
		sh->entsize = PtrSize;
		sh->addralign = PtrSize;
		shsym(sh, lookup(".got", 0));

		sh = elfshname(".got.plt");
		sh->type = SHT_PROGBITS;
		sh->flags = SHF_ALLOC+SHF_WRITE;
		sh->entsize = PtrSize;
		sh->addralign = PtrSize;
		shsym(sh, lookup(".got.plt", 0));
		
		sh = elfshname(".hash");
		sh->type = SHT_HASH;
		sh->flags = SHF_ALLOC;
		sh->entsize = 4;
		sh->addralign = PtrSize;
		sh->link = elfshname(".dynsym")->shnum;
		shsym(sh, lookup(".hash", 0));

		/* sh and PT_DYNAMIC for .dynamic section */
		sh = elfshname(".dynamic");
		sh->type = SHT_DYNAMIC;
		sh->flags = SHF_ALLOC+SHF_WRITE;
		sh->entsize = 2*PtrSize;
		sh->addralign = PtrSize;
		sh->link = elfshname(".dynstr")->shnum;
		shsym(sh, lookup(".dynamic", 0));
		ph = newElfPhdr();
		ph->type = PT_DYNAMIC;
		ph->flags = PF_R + PF_W;
		phsh(ph, sh);
		
		/*
		 * Thread-local storage segment (really just size).
		 */
		// Do not emit PT_TLS for OpenBSD since ld.so(1) does
		// not currently support it. This is handled
		// appropriately in runtime/cgo.
		if(tlsoffset != 0 && HEADTYPE != Hopenbsd) {
			ph = newElfPhdr();
			ph->type = PT_TLS;
			ph->flags = PF_R;
			ph->memsz = -tlsoffset;
			ph->align = PtrSize;
		}
	}

	if(HEADTYPE == Hlinux) {
		ph = newElfPhdr();
		ph->type = PT_GNU_STACK;
		ph->flags = PF_W+PF_R;
		ph->align = PtrSize;
		
		ph = newElfPhdr();
		ph->type = PT_PAX_FLAGS;
		ph->flags = 0x2a00; // mprotect, randexec, emutramp disabled
		ph->align = PtrSize;
	}

elfobj:
	sh = elfshname(".shstrtab");
	sh->type = SHT_STRTAB;
	sh->addralign = 1;
	shsym(sh, lookup(".shstrtab", 0));
	eh->shstrndx = sh->shnum;

	// put these sections early in the list
	if(!debug['s']) {
		elfshname(".symtab");
		elfshname(".strtab");
	}

	for(sect=segtext.sect; sect!=nil; sect=sect->next)
		elfshbits(sect);
	for(sect=segdata.sect; sect!=nil; sect=sect->next)
		elfshbits(sect);

	if(isobj) {
		for(sect=segtext.sect; sect!=nil; sect=sect->next)
			elfshreloc(sect);
		for(sect=segdata.sect; sect!=nil; sect=sect->next)
			elfshreloc(sect);
	}
		
	if(!debug['s']) {
		sh = elfshname(".symtab");
		sh->type = SHT_SYMTAB;
		sh->off = symo;
		sh->size = symsize;
		sh->addralign = PtrSize;
		sh->entsize = 8+2*PtrSize;
		sh->link = elfshname(".strtab")->shnum;
		sh->info = elfglobalsymndx;

		sh = elfshname(".strtab");
		sh->type = SHT_STRTAB;
		sh->off = symo+symsize;
		sh->size = elfstrsize;
		sh->addralign = 1;

		// TODO(rsc): Enable for isobj too, once we know it works.
		if(!isobj)
			dwarfaddelfheaders();
	}

	/* Main header */
	eh->ident[EI_MAG0] = '\177';
	eh->ident[EI_MAG1] = 'E';
	eh->ident[EI_MAG2] = 'L';
	eh->ident[EI_MAG3] = 'F';
	if(HEADTYPE == Hfreebsd)
		eh->ident[EI_OSABI] = ELFOSABI_FREEBSD;
	else if(HEADTYPE == Hnetbsd)
		eh->ident[EI_OSABI] = ELFOSABI_NETBSD;
	else if(HEADTYPE == Hopenbsd)
		eh->ident[EI_OSABI] = ELFOSABI_OPENBSD;
	if(PtrSize == 8)
		eh->ident[EI_CLASS] = ELFCLASS64;
	else
		eh->ident[EI_CLASS] = ELFCLASS32;
	eh->ident[EI_DATA] = ELFDATA2LSB;
	eh->ident[EI_VERSION] = EV_CURRENT;

	if(flag_shared)
		eh->type = ET_DYN;
	else if(isobj)
		eh->type = ET_REL;
	else
		eh->type = ET_EXEC;

	if(!isobj)
		eh->entry = entryvalue();

	eh->version = EV_CURRENT;

	if(pph != nil) {
		pph->filesz = eh->phnum * eh->phentsize;
		pph->memsz = pph->filesz;
	}

	cseek(0);
	a = 0;
	a += elfwritehdr();
	a += elfwritephdrs();
	a += elfwriteshdrs();
	if(!debug['d'])
		a += elfwriteinterp();
	if(!isobj) {
		if(HEADTYPE == Hnetbsd)
			a += elfwritenetbsdsig();
		if(HEADTYPE == Hopenbsd)
			a += elfwriteopenbsdsig();
		if(buildinfolen > 0)
			a += elfwritebuildinfo();
	}
	if(a > ELFRESERVE)	
		diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
}
Пример #8
0
void
asmb(void)
{
    int32 v, magic;
    int a, dynsym;
    uint32 symo, startva, dwarfoff, machlink, resoff;
    ElfEhdr *eh;
    ElfPhdr *ph, *pph, *pnote;
    ElfShdr *sh;
    Section *sect;
    Sym *sym;
    int o;
    int i;

    if(debug['v'])
        Bprint(&bso, "%5.2f asmb\n", cputime());
    Bflush(&bso);

    sect = segtext.sect;
    cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
    codeblk(sect->vaddr, sect->len);

    /* output read-only data in text segment (rodata, gosymtab, pclntab, ...) */
    for(sect = sect->next; sect != nil; sect = sect->next) {
        cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
        datblk(sect->vaddr, sect->len);
    }

    if(debug['v'])
        Bprint(&bso, "%5.2f datblk\n", cputime());
    Bflush(&bso);

    cseek(segdata.fileoff);
    datblk(segdata.vaddr, segdata.filelen);

    machlink = 0;
    if(HEADTYPE == Hdarwin) {
        if(debug['v'])
            Bprint(&bso, "%5.2f dwarf\n", cputime());

        dwarfoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND);
        cseek(dwarfoff);

        segdwarf.fileoff = cpos();
        dwarfemitdebugsections();
        segdwarf.filelen = cpos() - segdwarf.fileoff;

        machlink = domacholink();
    }

    if(iself) {
        /* index of elf text section; needed by asmelfsym, double-checked below */
        /* !debug['d'] causes extra sections before the .text section */
        elftextsh = 2;
        if(!debug['d']) {
            elftextsh += 10;
            if(elfverneed)
                elftextsh += 2;
        }
        if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd)
            elftextsh += 1;
        if(buildinfolen > 0)
            elftextsh += 1;
    }

    symsize = 0;
    spsize = 0;
    lcsize = 0;
    symo = 0;
    if(!debug['s']) {
        // TODO: rationalize
        if(debug['v'])
            Bprint(&bso, "%5.2f sym\n", cputime());
        Bflush(&bso);
        switch(HEADTYPE) {
        default:
            if(iself)
                goto Elfsym;
        case Hgarbunix:
            symo = rnd(HEADR+segtext.filelen, 8192)+segdata.filelen;
            break;
        case Hunixcoff:
            symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
            break;
        case Hplan9x32:
            symo = HEADR+segtext.filelen+segdata.filelen;
            break;
        case Hmsdoscom:
        case Hmsdosexe:
            debug['s'] = 1;
            symo = HEADR+segtext.filelen+segdata.filelen;
            break;
        case Hdarwin:
            symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
            break;
Elfsym:
            symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
            symo = rnd(symo, INITRND);
            break;
        case Hwindows:
            symo = rnd(HEADR+segtext.filelen, PEFILEALIGN)+segdata.filelen;
            symo = rnd(symo, PEFILEALIGN);
            break;
        }
        cseek(symo);
        switch(HEADTYPE) {
        default:
            if(iself) {
                if(debug['v'])
                    Bprint(&bso, "%5.2f elfsym\n", cputime());
                asmelfsym();
                cflush();
                cwrite(elfstrdat, elfstrsize);

                if(debug['v'])
                    Bprint(&bso, "%5.2f dwarf\n", cputime());
                dwarfemitdebugsections();
            }
            break;
        case Hplan9x32:
            asmplan9sym();
            cflush();

            sym = lookup("pclntab", 0);
            if(sym != nil) {
                lcsize = sym->np;
                for(i=0; i < lcsize; i++)
                    cput(sym->p[i]);

                cflush();
            }
            break;
        case Hwindows:
            if(debug['v'])
                Bprint(&bso, "%5.2f dwarf\n", cputime());
            dwarfemitdebugsections();
            break;
        }
    }
    if(debug['v'])
        Bprint(&bso, "%5.2f headr\n", cputime());
    Bflush(&bso);
    cseek(0L);
    switch(HEADTYPE) {
    default:
        if(iself)
            goto Elfput;
    case Hgarbunix:	/* garbage */
        lputb(0x160L<<16);		/* magic and sections */
        lputb(0L);			/* time and date */
        lputb(rnd(HEADR+segtext.filelen, 4096)+segdata.filelen);
        lputb(symsize);			/* nsyms */
        lputb((0x38L<<16)|7L);		/* size of optional hdr and flags */
        lputb((0413<<16)|0437L);		/* magic and version */
        lputb(rnd(HEADR+segtext.filelen, 4096));	/* sizes */
        lputb(segdata.filelen);
        lputb(segdata.len - segdata.filelen);
        lputb(entryvalue());		/* va of entry */
        lputb(INITTEXT-HEADR);		/* va of base of text */
        lputb(segdata.vaddr);			/* va of base of data */
        lputb(segdata.vaddr+segdata.filelen);		/* va of base of bss */
        lputb(~0L);			/* gp reg mask */
        lputb(0L);
        lputb(0L);
        lputb(0L);
        lputb(0L);
        lputb(~0L);			/* gp value ?? */
        break;
    case Hunixcoff:	/* unix coff */
        /*
         * file header
         */
        lputl(0x0004014c);		/* 4 sections, magic */
        lputl(0);			/* unix time stamp */
        lputl(0);			/* symbol table */
        lputl(0);			/* nsyms */
        lputl(0x0003001c);		/* flags, sizeof a.out header */
        /*
         * a.out header
         */
        lputl(0x10b);			/* magic, version stamp */
        lputl(rnd(segtext.filelen, INITRND));	/* text sizes */
        lputl(segdata.filelen);			/* data sizes */
        lputl(segdata.len - segdata.filelen);			/* bss sizes */
        lputb(entryvalue());		/* va of entry */
        lputl(INITTEXT);		/* text start */
        lputl(segdata.vaddr);			/* data start */
        /*
         * text section header
         */
        s8put(".text");
        lputl(HEADR);			/* pa */
        lputl(HEADR);			/* va */
        lputl(segtext.filelen);		/* text size */
        lputl(HEADR);			/* file offset */
        lputl(0);			/* relocation */
        lputl(0);			/* line numbers */
        lputl(0);			/* relocation, line numbers */
        lputl(0x20);			/* flags text only */
        /*
         * data section header
         */
        s8put(".data");
        lputl(segdata.vaddr);			/* pa */
        lputl(segdata.vaddr);			/* va */
        lputl(segdata.filelen);			/* data size */
        lputl(HEADR+segtext.filelen);		/* file offset */
        lputl(0);			/* relocation */
        lputl(0);			/* line numbers */
        lputl(0);			/* relocation, line numbers */
        lputl(0x40);			/* flags data only */
        /*
         * bss section header
         */
        s8put(".bss");
        lputl(segdata.vaddr+segdata.filelen);		/* pa */
        lputl(segdata.vaddr+segdata.filelen);		/* va */
        lputl(segdata.len - segdata.filelen);			/* bss size */
        lputl(0);			/* file offset */
        lputl(0);			/* relocation */
        lputl(0);			/* line numbers */
        lputl(0);			/* relocation, line numbers */
        lputl(0x80);			/* flags bss only */
        /*
         * comment section header
         */
        s8put(".comment");
        lputl(0);			/* pa */
        lputl(0);			/* va */
        lputl(symsize+lcsize);		/* comment size */
        lputl(HEADR+segtext.filelen+segdata.filelen);	/* file offset */
        lputl(HEADR+segtext.filelen+segdata.filelen);	/* offset of syms */
        lputl(HEADR+segtext.filelen+segdata.filelen+symsize);/* offset of line numbers */
        lputl(0);			/* relocation, line numbers */
        lputl(0x200);			/* flags comment only */
        break;
    case Hplan9x32:	/* plan9 */
        magic = 4*11*11+7;
        lputb(magic);		/* magic */
        lputb(segtext.filelen);			/* sizes */
        lputb(segdata.filelen);
        lputb(segdata.len - segdata.filelen);
        lputb(symsize);			/* nsyms */
        lputb(entryvalue());		/* va of entry */
        lputb(spsize);			/* sp offsets */
        lputb(lcsize);			/* line offsets */
        break;
    case Hmsdoscom:
        /* MS-DOS .COM */
        break;
    case Hmsdosexe:
        /* fake MS-DOS .EXE */
        v = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
        wputl(0x5A4D);			/* 'MZ' */
        wputl(v % 512);			/* bytes in last page */
        wputl(rnd(v, 512)/512);		/* total number of pages */
        wputl(0x0000);			/* number of reloc items */
        v = rnd(HEADR-(INITTEXT & 0xFFFF), 16);
        wputl(v/16);			/* size of header */
        wputl(0x0000);			/* minimum allocation */
        wputl(0xFFFF);			/* maximum allocation */
        wputl(0x0000);			/* initial ss value */
        wputl(0x0100);			/* initial sp value */
        wputl(0x0000);			/* complemented checksum */
        v = entryvalue();
        wputl(v);			/* initial ip value (!) */
        wputl(0x0000);			/* initial cs value */
        wputl(0x0000);
        wputl(0x0000);
        wputl(0x003E);			/* reloc table offset */
        wputl(0x0000);			/* overlay number */
        break;

    case Hdarwin:
        asmbmacho();
        break;

Elfput:
        eh = getElfEhdr();
        startva = INITTEXT - HEADR;
        resoff = ELFRESERVE;

        /* This null SHdr must appear before all others */
        newElfShdr(elfstr[ElfStrEmpty]);

        /* program header info */
        pph = newElfPhdr();
        pph->type = PT_PHDR;
        pph->flags = PF_R + PF_X;
        pph->off = eh->ehsize;
        pph->vaddr = INITTEXT - HEADR + pph->off;
        pph->paddr = INITTEXT - HEADR + pph->off;
        pph->align = INITRND;

        /*
         * PHDR must be in a loaded segment. Adjust the text
         * segment boundaries downwards to include it.
         */
        o = segtext.vaddr - pph->vaddr;
        segtext.vaddr -= o;
        segtext.len += o;
        o = segtext.fileoff - pph->off;
        segtext.fileoff -= o;
        segtext.filelen += o;

        if(!debug['d']) {
            /* interpreter */
            sh = newElfShdr(elfstr[ElfStrInterp]);
            sh->type = SHT_PROGBITS;
            sh->flags = SHF_ALLOC;
            sh->addralign = 1;
            if(interpreter == nil) {
                switch(HEADTYPE) {
                case Hlinux:
                    interpreter = linuxdynld;
                    break;
                case Hfreebsd:
                    interpreter = freebsddynld;
                    break;
                case Hnetbsd:
                    interpreter = netbsddynld;
                    break;
                case Hopenbsd:
                    interpreter = openbsddynld;
                    break;
                }
            }
            resoff -= elfinterp(sh, startva, resoff, interpreter);

            ph = newElfPhdr();
            ph->type = PT_INTERP;
            ph->flags = PF_R;
            phsh(ph, sh);
        }

        pnote = nil;
        if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
            sh = nil;
            switch(HEADTYPE) {
            case Hnetbsd:
                sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
                resoff -= elfnetbsdsig(sh, startva, resoff);
                break;
            case Hopenbsd:
                sh = newElfShdr(elfstr[ElfStrNoteOpenbsdIdent]);
                resoff -= elfopenbsdsig(sh, startva, resoff);
                break;
            }

            pnote = newElfPhdr();
            pnote->type = PT_NOTE;
            pnote->flags = PF_R;
            phsh(pnote, sh);
        }

        if(buildinfolen > 0) {
            sh = newElfShdr(elfstr[ElfStrNoteBuildInfo]);
            resoff -= elfbuildinfo(sh, startva, resoff);

            if(pnote == nil) {
                pnote = newElfPhdr();
                pnote->type = PT_NOTE;
                pnote->flags = PF_R;
            }
            phsh(pnote, sh);
        }

        // Additions to the reserved area must be above this line.
        USED(resoff);

        elfphload(&segtext);
        elfphload(&segdata);

        /* Dynamic linking sections */
        if(!debug['d']) {	/* -d suppresses dynamic loader format */
            /* S headers for dynamic linking */
            sh = newElfShdr(elfstr[ElfStrGot]);
            sh->type = SHT_PROGBITS;
            sh->flags = SHF_ALLOC+SHF_WRITE;
            sh->entsize = 4;
            sh->addralign = 4;
            shsym(sh, lookup(".got", 0));

            sh = newElfShdr(elfstr[ElfStrGotPlt]);
            sh->type = SHT_PROGBITS;
            sh->flags = SHF_ALLOC+SHF_WRITE;
            sh->entsize = 4;
            sh->addralign = 4;
            shsym(sh, lookup(".got.plt", 0));

            dynsym = eh->shnum;
            sh = newElfShdr(elfstr[ElfStrDynsym]);
            sh->type = SHT_DYNSYM;
            sh->flags = SHF_ALLOC;
            sh->entsize = ELF32SYMSIZE;
            sh->addralign = 4;
            sh->link = dynsym+1;	// dynstr
            // sh->info = index of first non-local symbol (number of local symbols)
            shsym(sh, lookup(".dynsym", 0));

            sh = newElfShdr(elfstr[ElfStrDynstr]);
            sh->type = SHT_STRTAB;
            sh->flags = SHF_ALLOC;
            sh->addralign = 1;
            shsym(sh, lookup(".dynstr", 0));

            if(elfverneed) {
                sh = newElfShdr(elfstr[ElfStrGnuVersion]);
                sh->type = SHT_GNU_VERSYM;
                sh->flags = SHF_ALLOC;
                sh->addralign = 2;
                sh->link = dynsym;
                sh->entsize = 2;
                shsym(sh, lookup(".gnu.version", 0));

                sh = newElfShdr(elfstr[ElfStrGnuVersionR]);
                sh->type = SHT_GNU_VERNEED;
                sh->flags = SHF_ALLOC;
                sh->addralign = 4;
                sh->info = elfverneed;
                sh->link = dynsym+1;  // dynstr
                shsym(sh, lookup(".gnu.version_r", 0));
            }

            sh = newElfShdr(elfstr[ElfStrRelPlt]);
            sh->type = SHT_REL;
            sh->flags = SHF_ALLOC;
            sh->entsize = ELF32RELSIZE;
            sh->addralign = 4;
            sh->link = dynsym;
            sh->info = eh->shnum;	// .plt
            shsym(sh, lookup(".rel.plt", 0));

            sh = newElfShdr(elfstr[ElfStrPlt]);
            sh->type = SHT_PROGBITS;
            sh->flags = SHF_ALLOC+SHF_EXECINSTR;
            sh->entsize = 4;
            sh->addralign = 4;
            shsym(sh, lookup(".plt", 0));

            sh = newElfShdr(elfstr[ElfStrHash]);
            sh->type = SHT_HASH;
            sh->flags = SHF_ALLOC;
            sh->entsize = 4;
            sh->addralign = 4;
            sh->link = dynsym;
            shsym(sh, lookup(".hash", 0));

            sh = newElfShdr(elfstr[ElfStrRel]);
            sh->type = SHT_REL;
            sh->flags = SHF_ALLOC;
            sh->entsize = ELF32RELSIZE;
            sh->addralign = 4;
            sh->link = dynsym;
            shsym(sh, lookup(".rel", 0));

            /* sh and PT_DYNAMIC for .dynamic section */
            sh = newElfShdr(elfstr[ElfStrDynamic]);
            sh->type = SHT_DYNAMIC;
            sh->flags = SHF_ALLOC+SHF_WRITE;
            sh->entsize = 8;
            sh->addralign = 4;
            sh->link = dynsym+1;	// dynstr
            shsym(sh, lookup(".dynamic", 0));
            ph = newElfPhdr();
            ph->type = PT_DYNAMIC;
            ph->flags = PF_R + PF_W;
            phsh(ph, sh);

            /*
             * Thread-local storage segment (really just size).
             */
            // Do not emit PT_TLS for OpenBSD since ld.so(1) does
            // not currently support it. This is handled
            // appropriately in runtime/cgo.
            if(tlsoffset != 0 && HEADTYPE != Hopenbsd) {
                ph = newElfPhdr();
                ph->type = PT_TLS;
                ph->flags = PF_R;
                ph->memsz = -tlsoffset;
                ph->align = 4;
            }
        }

        ph = newElfPhdr();
        ph->type = PT_GNU_STACK;
        ph->flags = PF_W+PF_R;
        ph->align = 4;

        ph = newElfPhdr();
        ph->type = PT_PAX_FLAGS;
        ph->flags = 0x2a00; // mprotect, randexec, emutramp disabled
        ph->align = 4;

        sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
        sh->type = SHT_STRTAB;
        sh->addralign = 1;
        shsym(sh, lookup(".shstrtab", 0));

        if(elftextsh != eh->shnum)
            diag("elftextsh = %d, want %d", elftextsh, eh->shnum);
        for(sect=segtext.sect; sect!=nil; sect=sect->next)
            elfshbits(sect);
        for(sect=segdata.sect; sect!=nil; sect=sect->next)
            elfshbits(sect);

        if(!debug['s']) {
            sh = newElfShdr(elfstr[ElfStrSymtab]);
            sh->type = SHT_SYMTAB;
            sh->off = symo;
            sh->size = symsize;
            sh->addralign = 4;
            sh->entsize = 16;
            sh->link = eh->shnum;	// link to strtab

            sh = newElfShdr(elfstr[ElfStrStrtab]);
            sh->type = SHT_STRTAB;
            sh->off = symo+symsize;
            sh->size = elfstrsize;
            sh->addralign = 1;

            dwarfaddelfheaders();
        }

        /* Main header */
        eh->ident[EI_MAG0] = '\177';
        eh->ident[EI_MAG1] = 'E';
        eh->ident[EI_MAG2] = 'L';
        eh->ident[EI_MAG3] = 'F';
        eh->ident[EI_CLASS] = ELFCLASS32;
        eh->ident[EI_DATA] = ELFDATA2LSB;
        eh->ident[EI_VERSION] = EV_CURRENT;
        switch(HEADTYPE) {
        case Hfreebsd:
            eh->ident[EI_OSABI] = ELFOSABI_FREEBSD;
            break;
        case Hnetbsd:
            eh->ident[EI_OSABI] = ELFOSABI_NETBSD;
            break;
        case Hopenbsd:
            eh->ident[EI_OSABI] = ELFOSABI_OPENBSD;
            break;
        }

        eh->type = ET_EXEC;
        eh->machine = EM_386;
        eh->version = EV_CURRENT;
        eh->entry = entryvalue();

        if(pph != nil) {
            pph->filesz = eh->phnum * eh->phentsize;
            pph->memsz = pph->filesz;
        }

        cseek(0);
        a = 0;
        a += elfwritehdr();
        a += elfwritephdrs();
        a += elfwriteshdrs();
        a += elfwriteinterp(elfstr[ElfStrInterp]);
        if(HEADTYPE == Hnetbsd)
            a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
        if(HEADTYPE == Hopenbsd)
            a += elfwriteopenbsdsig(elfstr[ElfStrNoteOpenbsdIdent]);
        if(buildinfolen > 0)
            a += elfwritebuildinfo(elfstr[ElfStrNoteBuildInfo]);
        if(a > ELFRESERVE)
            diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
        break;

    case Hwindows:
        asmbpe();
        break;
    }
    cflush();
}
Пример #9
0
int
read_seq_write_rand(command_list *cl, DCB_registered_src *r_src, unsigned char is_overlay, cfile *out_cfh, unsigned long buf_size)
{
	unsigned char *buf;
	unsigned char *p;
	unsigned long x, start=0, end=0, len=0;
	unsigned long max_pos = 0, pos = 0;
	unsigned long offset;
	signed long tmp_len;
	dcb_src_read_func read_func;
	cfile_window *cfw;
	u_dcb_src u_src;
	
	#define END_POS(x) ((x).src_pos + (x).len)
	pos = 0;
	max_pos = 0;

	if(is_overlay) {
		read_func = r_src->mask_read_func;
	} else {
		read_func = r_src->read_func;
	}
	assert(read_func != NULL);
	u_src = r_src->src_ptr;
	if(0 != cseek(u_src.cfh, 0, CSEEK_FSTART)) {
		ap_printf("cseeked failed: bailing, io_error 0\n");
		return IO_ERROR;
	}

	if((buf = (unsigned char *)malloc(buf_size)) == NULL) {
		return MEM_ERROR;
	}

	// we should *never* go backwards
	u_src.cfh->state_flags |= CFILE_FLAG_BACKWARD_SEEKS;		

	while(start < cl->com_count) {
		if(pos < cl->full_command[start].src_pos) {
			pos = cl->full_command[start].src_pos;
			max_pos = END_POS(cl->full_command[start]);
		} else {
			while(start < cl->com_count && pos > cl->full_command[start].src_pos) {
				start++;
			}
			if(start == cl->com_count)
				continue;
			pos = cl->full_command[start].src_pos;
			max_pos = MAX(max_pos, END_POS(cl->full_command[start]));
		}
		if(end < start) {
			end = start;
		}
		while(end < cl->com_count && cl->full_command[end].src_pos < max_pos) {
			max_pos = MAX(max_pos, END_POS(cl->full_command[end]));
			end++;
		}
		if(pos == max_pos) {
			continue;
		}
		while(pos < max_pos) {
			len = MIN(max_pos - pos, buf_size);
			x = read_func(u_src, pos, buf, len);
//			if(len < max_pos - pos)
//				v0printf("buffered %lu, max was %lu\n", len, max_pos - pos);
			if(len != x){
				ap_printf("x=%lu, pos=%lu, len=%lu\n", x, pos, len);
				ap_printf("bailing, io_error 2\n");
				free(buf);
				return IO_ERROR;
			}
			for(x=start; x < end; x++) {
				offset = MAX(cl->full_command[x].src_pos, pos);
				tmp_len = MIN(END_POS(cl->full_command[x]), pos + len) - offset;
					
				if(tmp_len > 0) { 
					if(cl->full_command[x].ver_pos + (offset - cl->full_command[x].src_pos) !=
						cseek(out_cfh, cl->full_command[x].ver_pos + (offset - cl->full_command[x].src_pos),
						CSEEK_FSTART)) {
						ap_printf("bailing, io_error 3\n");
						free(buf);
						return IO_ERROR;
					}
					if(is_overlay) {
						p = buf + offset - pos;
						cfw = expose_page(out_cfh);
						if(cfw->write_end == 0) {
							cfw->write_start = cfw->pos;
						}
						while(buf + offset - pos + tmp_len > p) {
							if(cfw->pos == cfw->end) {
								cfw->write_end = cfw->end;
								cfw = next_page(out_cfh);
								if(cfw->end == 0) {
									ap_printf("bailing from applying overlay mask in read_seq_writ_rand\n");
									free(buf);
									return IO_ERROR;
								}
							}
							cfw->buff[cfw->pos] += *p;
							p++;
							cfw->pos++;
						}
						cfw->write_end = cfw->pos;
					} else {
						if(tmp_len != cwrite(out_cfh, buf + offset - pos, tmp_len)) {
							ap_printf("bailing, io_error 4\n");
							free(buf);
							return IO_ERROR;
						}
					}
				}
			}
			pos += len;
		}
	}
	u_src.cfh->state_flags &= ~CFILE_FLAG_BACKWARD_SEEKS;
	free(buf);
	return 0;
}
Пример #10
0
void
asmb(void)
{
	int32 magic;
	int i;
	vlong vl, symo, dwarfoff, machlink;
	Section *sect;
	Sym *sym;

	if(debug['v'])
		Bprint(&bso, "%5.2f asmb\n", cputime());
	Bflush(&bso);

	if(debug['v'])
		Bprint(&bso, "%5.2f codeblk\n", cputime());
	Bflush(&bso);

	if(iself)
		asmbelfsetup();

	sect = segtext.sect;
	cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
	codeblk(sect->vaddr, sect->len);

	/* output read-only data in text segment (rodata, gosymtab, pclntab, ...) */
	for(sect = sect->next; sect != nil; sect = sect->next) {
		cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
		datblk(sect->vaddr, sect->len);
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f datblk\n", cputime());
	Bflush(&bso);

	cseek(segdata.fileoff);
	datblk(segdata.vaddr, segdata.filelen);

	machlink = 0;
	if(HEADTYPE == Hdarwin) {
		if(debug['v'])
			Bprint(&bso, "%5.2f dwarf\n", cputime());

		dwarfoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND);
		cseek(dwarfoff);

		segdwarf.fileoff = cpos();
		dwarfemitdebugsections();
		segdwarf.filelen = cpos() - segdwarf.fileoff;

		machlink = domacholink();
	}

	switch(HEADTYPE) {
	default:
		diag("unknown header type %d", HEADTYPE);
	case Hplan9x32:
	case Hplan9x64:
	case Helf:
		break;
	case Hdarwin:
		debug['8'] = 1;	/* 64-bit addresses */
		break;
	case Hlinux:
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
		debug['8'] = 1;	/* 64-bit addresses */
		break;
	case Hwindows:
		break;
	}

	symsize = 0;
	spsize = 0;
	lcsize = 0;
	symo = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		default:
		case Hplan9x64:
		case Helf:
			debug['s'] = 1;
			symo = HEADR+segtext.len+segdata.filelen;
			break;
		case Hdarwin:
			symo = rnd(HEADR+segtext.len, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
			break;
		case Hlinux:
		case Hfreebsd:
		case Hnetbsd:
		case Hopenbsd:
			symo = rnd(HEADR+segtext.len, INITRND)+segdata.filelen;
			symo = rnd(symo, INITRND);
			break;
		case Hwindows:
			symo = rnd(HEADR+segtext.filelen, PEFILEALIGN)+segdata.filelen;
			symo = rnd(symo, PEFILEALIGN);
			break;
		}
		cseek(symo);
		switch(HEADTYPE) {
		default:
			if(iself) {
				cseek(symo);
				asmelfsym();
				cflush();
				cwrite(elfstrdat, elfstrsize);

				if(debug['v'])
				       Bprint(&bso, "%5.2f dwarf\n", cputime());

				dwarfemitdebugsections();
				
				if(isobj)
					elfemitreloc();
			}
			break;
		case Hplan9x64:
			asmplan9sym();
			cflush();

			sym = lookup("pclntab", 0);
			if(sym != nil) {
				lcsize = sym->np;
				for(i=0; i < lcsize; i++)
					cput(sym->p[i]);
				
				cflush();
			}
			break;
		case Hwindows:
			if(debug['v'])
			       Bprint(&bso, "%5.2f dwarf\n", cputime());

			dwarfemitdebugsections();
			break;
		}
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f headr\n", cputime());
	Bflush(&bso);
	cseek(0L);
	switch(HEADTYPE) {
	default:
	case Hplan9x64:	/* plan9 */
		magic = 4*26*26+7;
		magic |= 0x00008000;		/* fat header */
		lputb(magic);			/* magic */
		lputb(segtext.filelen);			/* sizes */
		lputb(segdata.filelen);
		lputb(segdata.len - segdata.filelen);
		lputb(symsize);			/* nsyms */
		vl = entryvalue();
		lputb(PADDR(vl));		/* va of entry */
		lputb(spsize);			/* sp offsets */
		lputb(lcsize);			/* line offsets */
		vputb(vl);			/* va of entry */
		break;
	case Hplan9x32:	/* plan9 */
		magic = 4*26*26+7;
		lputb(magic);			/* magic */
		lputb(segtext.filelen);		/* sizes */
		lputb(segdata.filelen);
		lputb(segdata.len - segdata.filelen);
		lputb(symsize);			/* nsyms */
		lputb(entryvalue());		/* va of entry */
		lputb(spsize);			/* sp offsets */
		lputb(lcsize);			/* line offsets */
		break;
	case Hdarwin:
		asmbmacho();
		break;
	case Hlinux:
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
		asmbelf(symo);
		break;
	case Hwindows:
		asmbpe();
		break;
	}
	cflush();
}
Пример #11
0
void
asmb(void)
{
	int32 magic;
	int a, dynsym;
	vlong vl, startva, symo, dwarfoff, machlink, resoff;
	ElfEhdr *eh;
	ElfPhdr *ph, *pph;
	ElfShdr *sh;
	Section *sect;
	Sym *sym;
	int i, o;

	if(debug['v'])
		Bprint(&bso, "%5.2f asmb\n", cputime());
	Bflush(&bso);

	elftextsh = 0;
	
	if(debug['v'])
		Bprint(&bso, "%5.2f codeblk\n", cputime());
	Bflush(&bso);

	sect = segtext.sect;
	cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
	codeblk(sect->vaddr, sect->len);

	/* output read-only data in text segment (rodata, gosymtab and pclntab) */
	for(sect = sect->next; sect != nil; sect = sect->next) {
		cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
		datblk(sect->vaddr, sect->len);
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f datblk\n", cputime());
	Bflush(&bso);

	cseek(segdata.fileoff);
	datblk(segdata.vaddr, segdata.filelen);

	machlink = 0;
	if(HEADTYPE == Hdarwin) {
		if(debug['v'])
			Bprint(&bso, "%5.2f dwarf\n", cputime());

		dwarfoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND);
		cseek(dwarfoff);

		segdwarf.fileoff = cpos();
		dwarfemitdebugsections();
		segdwarf.filelen = cpos() - segdwarf.fileoff;

		machlink = domacholink();
	}

	switch(HEADTYPE) {
	default:
		diag("unknown header type %d", HEADTYPE);
	case Hplan9x32:
	case Hplan9x64:
	case Helf:
		break;
	case Hdarwin:
		debug['8'] = 1;	/* 64-bit addresses */
		break;
	case Hlinux:
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
		debug['8'] = 1;	/* 64-bit addresses */
		/* index of elf text section; needed by asmelfsym, double-checked below */
		/* !debug['d'] causes extra sections before the .text section */
		elftextsh = 2;
		if(!debug['d']) {
			elftextsh += 10;
			if(elfverneed)
				elftextsh += 2;
		}
		if(HEADTYPE == Hnetbsd)
			elftextsh += 1;
		break;
	case Hwindows:
		break;
	}

	symsize = 0;
	spsize = 0;
	lcsize = 0;
	symo = 0;
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		default:
		case Hplan9x64:
		case Helf:
			debug['s'] = 1;
			symo = HEADR+segtext.len+segdata.filelen;
			break;
		case Hdarwin:
			symo = rnd(HEADR+segtext.len, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
			break;
		case Hlinux:
		case Hfreebsd:
		case Hnetbsd:
		case Hopenbsd:
			symo = rnd(HEADR+segtext.len, INITRND)+segdata.filelen;
			symo = rnd(symo, INITRND);
			break;
		case Hwindows:
			symo = rnd(HEADR+segtext.filelen, PEFILEALIGN)+segdata.filelen;
			symo = rnd(symo, PEFILEALIGN);
			break;
		}
		cseek(symo);
		switch(HEADTYPE) {
		default:
			if(iself) {
				cseek(symo);
				asmelfsym();
				cflush();
				cwrite(elfstrdat, elfstrsize);

				if(debug['v'])
				       Bprint(&bso, "%5.2f dwarf\n", cputime());

				dwarfemitdebugsections();
			}
			break;
		case Hplan9x64:
			asmplan9sym();
			cflush();

			sym = lookup("pclntab", 0);
			if(sym != nil) {
				lcsize = sym->np;
				for(i=0; i < lcsize; i++)
					cput(sym->p[i]);
				
				cflush();
			}
			break;
		case Hwindows:
			if(debug['v'])
			       Bprint(&bso, "%5.2f dwarf\n", cputime());

			dwarfemitdebugsections();
			break;
		}
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f headr\n", cputime());
	Bflush(&bso);
	cseek(0L);
	switch(HEADTYPE) {
	default:
	case Hplan9x64:	/* plan9 */
		magic = 4*26*26+7;
		magic |= 0x00008000;		/* fat header */
		lputb(magic);			/* magic */
		lputb(segtext.filelen);			/* sizes */
		lputb(segdata.filelen);
		lputb(segdata.len - segdata.filelen);
		lputb(symsize);			/* nsyms */
		vl = entryvalue();
		lputb(PADDR(vl));		/* va of entry */
		lputb(spsize);			/* sp offsets */
		lputb(lcsize);			/* line offsets */
		vputb(vl);			/* va of entry */
		break;
	case Hplan9x32:	/* plan9 */
		magic = 4*26*26+7;
		lputb(magic);			/* magic */
		lputb(segtext.filelen);		/* sizes */
		lputb(segdata.filelen);
		lputb(segdata.len - segdata.filelen);
		lputb(symsize);			/* nsyms */
		lputb(entryvalue());		/* va of entry */
		lputb(spsize);			/* sp offsets */
		lputb(lcsize);			/* line offsets */
		break;
	case Hdarwin:
		asmbmacho();
		break;
	case Hlinux:
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
		/* elf amd-64 */

		eh = getElfEhdr();
		startva = INITTEXT - HEADR;
		resoff = ELFRESERVE;

		/* This null SHdr must appear before all others */
		newElfShdr(elfstr[ElfStrEmpty]);

		/* program header info */
		pph = newElfPhdr();
		pph->type = PT_PHDR;
		pph->flags = PF_R + PF_X;
		pph->off = eh->ehsize;
		pph->vaddr = INITTEXT - HEADR + pph->off;
		pph->paddr = INITTEXT - HEADR + pph->off;
		pph->align = INITRND;

		/*
		 * PHDR must be in a loaded segment. Adjust the text
		 * segment boundaries downwards to include it.
		 */
		o = segtext.vaddr - pph->vaddr;
		segtext.vaddr -= o;
		segtext.len += o;
		o = segtext.fileoff - pph->off;
		segtext.fileoff -= o;
		segtext.filelen += o;

		if(!debug['d']) {
			/* interpreter */
			sh = newElfShdr(elfstr[ElfStrInterp]);
			sh->type = SHT_PROGBITS;
			sh->flags = SHF_ALLOC;
			sh->addralign = 1;
			if(interpreter == nil) {
				switch(HEADTYPE) {
				case Hlinux:
					interpreter = linuxdynld;
					break;
				case Hfreebsd:
					interpreter = freebsddynld;
					break;
				case Hnetbsd:
					interpreter = netbsddynld;
					break;
				case Hopenbsd:
					interpreter = openbsddynld;
					break;
				}
			}
			resoff -= elfinterp(sh, startva, resoff, interpreter);

			ph = newElfPhdr();
			ph->type = PT_INTERP;
			ph->flags = PF_R;
			phsh(ph, sh);
		}

		if(HEADTYPE == Hnetbsd) {
			sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
			sh->type = SHT_NOTE;
			sh->flags = SHF_ALLOC;
			sh->addralign = 4;
			resoff -= elfnetbsdsig(sh, startva, resoff);

			ph = newElfPhdr();
			ph->type = PT_NOTE;
			ph->flags = PF_R;
			phsh(ph, sh);
		}

		elfphload(&segtext);
		elfphload(&segdata);

		/* Dynamic linking sections */
		if(!debug['d']) {	/* -d suppresses dynamic loader format */
			/* S headers for dynamic linking */
			sh = newElfShdr(elfstr[ElfStrGot]);
			sh->type = SHT_PROGBITS;
			sh->flags = SHF_ALLOC+SHF_WRITE;
			sh->entsize = 8;
			sh->addralign = 8;
			shsym(sh, lookup(".got", 0));

			sh = newElfShdr(elfstr[ElfStrGotPlt]);
			sh->type = SHT_PROGBITS;
			sh->flags = SHF_ALLOC+SHF_WRITE;
			sh->entsize = 8;
			sh->addralign = 8;
			shsym(sh, lookup(".got.plt", 0));
			
			dynsym = eh->shnum;
			sh = newElfShdr(elfstr[ElfStrDynsym]);
			sh->type = SHT_DYNSYM;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF64SYMSIZE;
			sh->addralign = 8;
			sh->link = dynsym+1;	// dynstr
			// sh->info = index of first non-local symbol (number of local symbols)
			shsym(sh, lookup(".dynsym", 0));

			sh = newElfShdr(elfstr[ElfStrDynstr]);
			sh->type = SHT_STRTAB;
			sh->flags = SHF_ALLOC;
			sh->addralign = 1;
			shsym(sh, lookup(".dynstr", 0));

			if(elfverneed) {
				sh = newElfShdr(elfstr[ElfStrGnuVersion]);
				sh->type = SHT_GNU_VERSYM;
				sh->flags = SHF_ALLOC;
				sh->addralign = 2;
				sh->link = dynsym;
				sh->entsize = 2;
				shsym(sh, lookup(".gnu.version", 0));
				
				sh = newElfShdr(elfstr[ElfStrGnuVersionR]);
				sh->type = SHT_GNU_VERNEED;
				sh->flags = SHF_ALLOC;
				sh->addralign = 8;
				sh->info = elfverneed;
				sh->link = dynsym+1;  // dynstr
				shsym(sh, lookup(".gnu.version_r", 0));
			}

			sh = newElfShdr(elfstr[ElfStrRelaPlt]);
			sh->type = SHT_RELA;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF64RELASIZE;
			sh->addralign = 8;
			sh->link = dynsym;
			sh->info = eh->shnum;	// .plt
			shsym(sh, lookup(".rela.plt", 0));

			sh = newElfShdr(elfstr[ElfStrPlt]);
			sh->type = SHT_PROGBITS;
			sh->flags = SHF_ALLOC+SHF_EXECINSTR;
			sh->entsize = 16;
			sh->addralign = 4;
			shsym(sh, lookup(".plt", 0));

			sh = newElfShdr(elfstr[ElfStrHash]);
			sh->type = SHT_HASH;
			sh->flags = SHF_ALLOC;
			sh->entsize = 4;
			sh->addralign = 8;
			sh->link = dynsym;
			shsym(sh, lookup(".hash", 0));

			sh = newElfShdr(elfstr[ElfStrRela]);
			sh->type = SHT_RELA;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF64RELASIZE;
			sh->addralign = 8;
			sh->link = dynsym;
			shsym(sh, lookup(".rela", 0));

			/* sh and PT_DYNAMIC for .dynamic section */
			sh = newElfShdr(elfstr[ElfStrDynamic]);
			sh->type = SHT_DYNAMIC;
			sh->flags = SHF_ALLOC+SHF_WRITE;
			sh->entsize = 16;
			sh->addralign = 8;
			sh->link = dynsym+1;	// dynstr
			shsym(sh, lookup(".dynamic", 0));
			ph = newElfPhdr();
			ph->type = PT_DYNAMIC;
			ph->flags = PF_R + PF_W;
			phsh(ph, sh);
			
			/*
			 * Thread-local storage segment (really just size).
			 */
			if(tlsoffset != 0) {
				ph = newElfPhdr();
				ph->type = PT_TLS;
				ph->flags = PF_R;
				ph->memsz = -tlsoffset;
				ph->align = 8;
			}
		}

		ph = newElfPhdr();
		ph->type = PT_GNU_STACK;
		ph->flags = PF_W+PF_R;
		ph->align = 8;
		
		ph = newElfPhdr();
		ph->type = PT_PAX_FLAGS;
		ph->flags = 0x2a00; // mprotect, randexec, emutramp disabled
		ph->align = 8;

		sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
		sh->type = SHT_STRTAB;
		sh->addralign = 1;
		shsym(sh, lookup(".shstrtab", 0));

		if(elftextsh != eh->shnum)
			diag("elftextsh = %d, want %d", elftextsh, eh->shnum);
		for(sect=segtext.sect; sect!=nil; sect=sect->next)
			elfshbits(sect);
		for(sect=segdata.sect; sect!=nil; sect=sect->next)
			elfshbits(sect);

		if(!debug['s']) {
			sh = newElfShdr(elfstr[ElfStrSymtab]);
			sh->type = SHT_SYMTAB;
			sh->off = symo;
			sh->size = symsize;
			sh->addralign = 8;
			sh->entsize = 24;
			sh->link = eh->shnum;	// link to strtab

			sh = newElfShdr(elfstr[ElfStrStrtab]);
			sh->type = SHT_STRTAB;
			sh->off = symo+symsize;
			sh->size = elfstrsize;
			sh->addralign = 1;

			dwarfaddelfheaders();
		}

		/* Main header */
		eh->ident[EI_MAG0] = '\177';
		eh->ident[EI_MAG1] = 'E';
		eh->ident[EI_MAG2] = 'L';
		eh->ident[EI_MAG3] = 'F';
		if(HEADTYPE == Hfreebsd)
			eh->ident[EI_OSABI] = ELFOSABI_FREEBSD;
		else if(HEADTYPE == Hnetbsd)
			eh->ident[EI_OSABI] = ELFOSABI_NETBSD;
		else if(HEADTYPE == Hopenbsd)
			eh->ident[EI_OSABI] = ELFOSABI_OPENBSD;
		eh->ident[EI_CLASS] = ELFCLASS64;
		eh->ident[EI_DATA] = ELFDATA2LSB;
		eh->ident[EI_VERSION] = EV_CURRENT;

		eh->type = ET_EXEC;
		eh->machine = EM_X86_64;
		eh->version = EV_CURRENT;
		eh->entry = entryvalue();

		pph->filesz = eh->phnum * eh->phentsize;
		pph->memsz = pph->filesz;

		cseek(0);
		a = 0;
		a += elfwritehdr();
		a += elfwritephdrs();
		a += elfwriteshdrs();
		a += elfwriteinterp(elfstr[ElfStrInterp]);
		if(HEADTYPE == Hnetbsd)
			a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
		if(a > ELFRESERVE)	
			diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
		break;
	case Hwindows:
		asmbpe();
		break;
	}
	cflush();
}
Пример #12
0
Файл: pe.c Проект: rosrad/go-rep
void
asmbpe(void)
{
	IMAGE_SECTION_HEADER *t, *d;

	switch(thechar) {
	default:
		diag("unknown PE architecture");
		errorexit();
	case '6':
		fh.Machine = IMAGE_FILE_MACHINE_AMD64;
		break;
	case '8':
		fh.Machine = IMAGE_FILE_MACHINE_I386;
		break;
	}

	t = addpesection(".text", segtext.len, segtext.len);
	t->Characteristics = IMAGE_SCN_CNT_CODE|
		IMAGE_SCN_CNT_INITIALIZED_DATA|
		IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ;
	chksectseg(t, &segtext);
	textsect = nsect;

	d = addpesection(".data", segdata.len, segdata.filelen);
	d->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
		IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
	chksectseg(d, &segdata);

	if(!debug['s'])
		dwarfaddpeheaders();

	cseek(nextfileoff);
	addimports(d);
	addexports();
	addsymtable();
	addpersrc();

	fh.NumberOfSections = nsect;
	fh.TimeDateStamp = time(0);
	fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED|
		IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_DEBUG_STRIPPED;
	if (pe64) {
		fh.SizeOfOptionalHeader = sizeof(oh64);
		fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
		set(Magic, 0x20b);	// PE32+
	} else {
		fh.SizeOfOptionalHeader = sizeof(oh);
		fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE;
		set(Magic, 0x10b);	// PE32
		oh.BaseOfData = d->VirtualAddress;
	}
	set(MajorLinkerVersion, 3);
	set(MinorLinkerVersion, 0);
	set(SizeOfCode, t->SizeOfRawData);
	set(SizeOfInitializedData, d->SizeOfRawData);
	set(SizeOfUninitializedData, 0);
	set(AddressOfEntryPoint, entryvalue()-PEBASE);
	set(BaseOfCode, t->VirtualAddress);
	set(ImageBase, PEBASE);
	set(SectionAlignment, PESECTALIGN);
	set(FileAlignment, PEFILEALIGN);
	set(MajorOperatingSystemVersion, 4);
	set(MinorOperatingSystemVersion, 0);
	set(MajorImageVersion, 1);
	set(MinorImageVersion, 0);
	set(MajorSubsystemVersion, 4);
	set(MinorSubsystemVersion, 0);
	set(SizeOfImage, nextsectoff);
	set(SizeOfHeaders, PEFILEHEADR);
	if(strcmp(headstring, "windowsgui") == 0)
		set(Subsystem, IMAGE_SUBSYSTEM_WINDOWS_GUI);
	else
		set(Subsystem, IMAGE_SUBSYSTEM_WINDOWS_CUI);

	// Disable stack growth as we don't want Windows to
	// fiddle with the thread stack limits, which we set
	// ourselves to circumvent the stack checks in the
	// Windows exception dispatcher.
	// Commit size must be strictly less than reserve
	// size otherwise reserve will be rounded up to a
	// larger size, as verified with VMMap.

	// Go code would be OK with 64k stacks, but we need larger stacks for cgo.
	// That default stack reserve size affects only the main thread,
	// for other threads we specify stack size in runtime explicitly
	// (runtime knows whether cgo is enabled or not).
	// If you change stack reserve sizes here,
	// change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.
	if(!iscgo) {
		set(SizeOfStackReserve, 0x00010000);
		set(SizeOfStackCommit, 0x0000ffff);
	} else {
		set(SizeOfStackReserve, pe64 ? 0x00200000 : 0x00100000);
		// account for 2 guard pages
		set(SizeOfStackCommit, (pe64 ? 0x00200000 : 0x00100000) - 0x2000);
	}
	set(SizeOfHeapReserve, 0x00100000);
	set(SizeOfHeapCommit, 0x00001000);
	set(NumberOfRvaAndSizes, 16);

	pewrite();
}
Пример #13
0
void
asmb(void)
{
	int32 magic;
	uint32 symo, dwarfoff, machlink;
	Section *sect;
	LSym *sym;
	int i;

	if(debug['v'])
		Bprint(&bso, "%5.2f asmb\n", cputime());
	Bflush(&bso);

	if(iself)
		asmbelfsetup();

	sect = segtext.sect;
	cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
	codeblk(sect->vaddr, sect->len);
	for(sect = sect->next; sect != nil; sect = sect->next) {
		cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
		datblk(sect->vaddr, sect->len);
	}
	
	if(segrodata.filelen > 0) {
		if(debug['v'])
			Bprint(&bso, "%5.2f rodatblk\n", cputime());
		Bflush(&bso);

		cseek(segrodata.fileoff);
		datblk(segrodata.vaddr, segrodata.filelen);
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f datblk\n", cputime());
	Bflush(&bso);

	cseek(segdata.fileoff);
	datblk(segdata.vaddr, segdata.filelen);

	machlink = 0;
	if(HEADTYPE == Hdarwin) {
		if(debug['v'])
			Bprint(&bso, "%5.2f dwarf\n", cputime());

		dwarfoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND);
		cseek(dwarfoff);

		segdwarf.fileoff = cpos();
		dwarfemitdebugsections();
		segdwarf.filelen = cpos() - segdwarf.fileoff;

		machlink = domacholink();
	}

	symsize = 0;
	spsize = 0;
	lcsize = 0;
	symo = 0;
	if(!debug['s']) {
		// TODO: rationalize
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		default:
			if(iself)
				goto Elfsym;
		case Hplan9:
			symo = HEADR+segtext.filelen+segdata.filelen;
			break;
		case Hdarwin:
			symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
			break;
		Elfsym:
			symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(HEADR+segrodata.filelen, INITRND)+segdata.filelen;
			symo = rnd(symo, INITRND);
			break;
		case Hwindows:
			symo = rnd(HEADR+segtext.filelen, PEFILEALIGN)+segdata.filelen;
			symo = rnd(symo, PEFILEALIGN);
			break;
		}
		cseek(symo);
		switch(HEADTYPE) {
		default:
			if(iself) {
				if(debug['v'])
					Bprint(&bso, "%5.2f elfsym\n", cputime());
				asmelfsym();
				cflush();
				cwrite(elfstrdat, elfstrsize);

				if(debug['v'])
					Bprint(&bso, "%5.2f dwarf\n", cputime());
				dwarfemitdebugsections();
				
				if(linkmode == LinkExternal)
					elfemitreloc();
			}
			break;
		case Hplan9:
			asmplan9sym();
			cflush();

			sym = linklookup(ctxt, "pclntab", 0);
			if(sym != nil) {
				lcsize = sym->np;
				for(i=0; i < lcsize; i++)
					cput(sym->p[i]);
				
				cflush();
			}
			break;
		case Hwindows:
			if(debug['v'])
				Bprint(&bso, "%5.2f dwarf\n", cputime());
			dwarfemitdebugsections();
			break;
		case Hdarwin:
			if(linkmode == LinkExternal)
				machoemitreloc();
			break;
		}
	}
	if(debug['v'])
		Bprint(&bso, "%5.2f headr\n", cputime());
	Bflush(&bso);
	cseek(0L);
	switch(HEADTYPE) {
	default:
	case Hplan9:	/* plan9 */
		magic = 4*11*11+7;
		lputb(magic);		/* magic */
		lputb(segtext.filelen);			/* sizes */
		lputb(segdata.filelen);
		lputb(segdata.len - segdata.filelen);
		lputb(symsize);			/* nsyms */
		lputb(entryvalue());		/* va of entry */
		lputb(spsize);			/* sp offsets */
		lputb(lcsize);			/* line offsets */
		break;
	case Hdarwin:
		asmbmacho();
		break;
	case Hlinux:
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
	case Hdragonfly:
	case Hnacl:
		asmbelf(symo);
		break;
	case Hwindows:
		asmbpe();
		break;
	}
	cflush();
}
Пример #14
0
void
asmb(void)
{
	int32 t;
	int a, dynsym;
	uint32 fo, symo, startva, resoff;
	ElfEhdr *eh;
	ElfPhdr *ph, *pph;
	ElfShdr *sh;
	Section *sect;
	int o;

	if(debug['v'])
		Bprint(&bso, "%5.2f asmb\n", cputime());
	Bflush(&bso);

	sect = segtext.sect;
	cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
	codeblk(sect->vaddr, sect->len);

	/* output read-only data in text segment (rodata, gosymtab and pclntab) */
	for(sect = sect->next; sect != nil; sect = sect->next) {
		cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
		datblk(sect->vaddr, sect->len);
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f datblk\n", cputime());
	Bflush(&bso);

	cseek(segdata.fileoff);
	datblk(segdata.vaddr, segdata.filelen);

	if(iself) {
		/* index of elf text section; needed by asmelfsym, double-checked below */
		/* !debug['d'] causes extra sections before the .text section */
		elftextsh = 2;
		if(!debug['d']) {
			elftextsh += 10;
			if(elfverneed)
				elftextsh += 2;
		}
		if(HEADTYPE == Hnetbsd)
			elftextsh += 1;
	}

	/* output symbol table */
	symsize = 0;
	lcsize = 0;
	symo = 0;
	if(!debug['s']) {
		// TODO: rationalize
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		default:
			if(iself)
				goto ElfSym;
		case Hnoheader:
		case Hrisc:
		case Hixp1200:
		case Hipaq:
			debug['s'] = 1;
			break;
		case Hplan9x32:
			symo = HEADR+segtext.len+segdata.filelen;
			break;
		case Hnetbsd:
			symo = rnd(segdata.filelen, 4096);
			break;
		ElfSym:
			symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
			symo = rnd(symo, INITRND);
			break;
		}
		cseek(symo);
		if(iself) {
			if(debug['v'])
				Bprint(&bso, "%5.2f elfsym\n", cputime());
			asmelfsym();
			cflush();
			cwrite(elfstrdat, elfstrsize);

			// if(debug['v'])
			// 	Bprint(&bso, "%5.2f dwarf\n", cputime());
			// dwarfemitdebugsections();
		}
		cflush();
		
	}

	cursym = nil;
	if(debug['v'])
		Bprint(&bso, "%5.2f header\n", cputime());
	Bflush(&bso);
	cseek(0L);
	switch(HEADTYPE) {
	case Hnoheader:	/* no header */
		break;
	case Hrisc:	/* aif for risc os */
		lputl(0xe1a00000);		/* NOP - decompress code */
		lputl(0xe1a00000);		/* NOP - relocation code */
		lputl(0xeb000000 + 12);		/* BL - zero init code */
		lputl(0xeb000000 +
			(entryvalue()
			 - INITTEXT
			 + HEADR
			 - 12
			 - 8) / 4);		/* BL - entry code */

		lputl(0xef000011);		/* SWI - exit code */
		lputl(textsize+HEADR);		/* text size */
		lputl(segdata.filelen);			/* data size */
		lputl(0);			/* sym size */

		lputl(segdata.len - segdata.filelen);			/* bss size */
		lputl(0);			/* sym type */
		lputl(INITTEXT-HEADR);		/* text addr */
		lputl(0);			/* workspace - ignored */

		lputl(32);			/* addr mode / data addr flag */
		lputl(0);			/* data addr */
		for(t=0; t<2; t++)
			lputl(0);		/* reserved */

		for(t=0; t<15; t++)
			lputl(0xe1a00000);	/* NOP - zero init code */
		lputl(0xe1a0f00e);		/* B (R14) - zero init return */
		break;
	case Hplan9x32:	/* plan 9 */
		lput(0x647);			/* magic */
		lput(textsize);			/* sizes */
		lput(segdata.filelen);
		lput(segdata.len - segdata.filelen);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(0L);
		lput(lcsize);
		break;
	case Hnetbsd:	/* boot for NetBSD */
		lput((143<<16)|0413);		/* magic */
		lputl(rnd(HEADR+textsize, 4096));
		lputl(rnd(segdata.filelen, 4096));
		lputl(segdata.len - segdata.filelen);
		lputl(symsize);			/* nsyms */
		lputl(entryvalue());		/* va of entry */
		lputl(0L);
		lputl(0L);
		break;
	case Hixp1200: /* boot for IXP1200 */
		break;
	case Hipaq: /* boot for ipaq */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		lputl(0xe3300000);		/* nop */
		break;
	case Hlinux:
		/* elf arm */
		eh = getElfEhdr();
		fo = HEADR;
		startva = INITTEXT - fo;	/* va of byte 0 of file */
		resoff = ELFRESERVE;
		
		/* This null SHdr must appear before all others */
		newElfShdr(elfstr[ElfStrEmpty]);

		/* program header info */
		pph = newElfPhdr();
		pph->type = PT_PHDR;
		pph->flags = PF_R + PF_X;
		pph->off = eh->ehsize;
		pph->vaddr = INITTEXT - HEADR + pph->off;
		pph->paddr = INITTEXT - HEADR + pph->off;
		pph->align = INITRND;

		/*
		 * PHDR must be in a loaded segment. Adjust the text
		 * segment boundaries downwards to include it.
		 */
		o = segtext.vaddr - pph->vaddr;
		segtext.vaddr -= o;
		segtext.len += o;
		o = segtext.fileoff - pph->off;
		segtext.fileoff -= o;
		segtext.filelen += o;

		if(!debug['d']) {
			/* interpreter for dynamic linking */
			sh = newElfShdr(elfstr[ElfStrInterp]);
			sh->type = SHT_PROGBITS;
			sh->flags = SHF_ALLOC;
			sh->addralign = 1;
			if(interpreter == nil)
				interpreter = linuxdynld;
			resoff -= elfinterp(sh, startva, resoff, interpreter);

			ph = newElfPhdr();
			ph->type = PT_INTERP;
			ph->flags = PF_R;
			phsh(ph, sh);
		}

		if(HEADTYPE == Hnetbsd) {
			sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
			sh->type = SHT_NOTE;
			sh->flags = SHF_ALLOC;
			sh->addralign = 4;
			resoff -= elfnetbsdsig(sh, startva, resoff);

			ph = newElfPhdr();
			ph->type = PT_NOTE;
			ph->flags = PF_R;
			phsh(ph, sh);
		}

		elfphload(&segtext);
		elfphload(&segdata);

		/* Dynamic linking sections */
		if(!debug['d']) {	/* -d suppresses dynamic loader format */
			/* S headers for dynamic linking */
			sh = newElfShdr(elfstr[ElfStrGot]);
			sh->type = SHT_PROGBITS;
			sh->flags = SHF_ALLOC+SHF_WRITE;
			sh->entsize = 4;
			sh->addralign = 4;
			shsym(sh, lookup(".got", 0));

			sh = newElfShdr(elfstr[ElfStrGotPlt]);
			sh->type = SHT_PROGBITS;
			sh->flags = SHF_ALLOC+SHF_WRITE;
			sh->entsize = 4;
			sh->addralign = 4;
			shsym(sh, lookup(".got.plt", 0));

			dynsym = eh->shnum;
			sh = newElfShdr(elfstr[ElfStrDynsym]);
			sh->type = SHT_DYNSYM;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF32SYMSIZE;
			sh->addralign = 4;
			sh->link = dynsym+1;	// dynstr
			// sh->info = index of first non-local symbol (number of local symbols)
			shsym(sh, lookup(".dynsym", 0));

			sh = newElfShdr(elfstr[ElfStrDynstr]);
			sh->type = SHT_STRTAB;
			sh->flags = SHF_ALLOC;
			sh->addralign = 1;
			shsym(sh, lookup(".dynstr", 0));

			sh = newElfShdr(elfstr[ElfStrHash]);
			sh->type = SHT_HASH;
			sh->flags = SHF_ALLOC;
			sh->entsize = 4;
			sh->addralign = 4;
			sh->link = dynsym;
			shsym(sh, lookup(".hash", 0));

			sh = newElfShdr(elfstr[ElfStrRel]);
			sh->type = SHT_REL;
			sh->flags = SHF_ALLOC;
			sh->entsize = ELF32RELSIZE;
			sh->addralign = 4;
			sh->link = dynsym;
			shsym(sh, lookup(".rel", 0));

			/* sh and PT_DYNAMIC for .dynamic section */
			sh = newElfShdr(elfstr[ElfStrDynamic]);
			sh->type = SHT_DYNAMIC;
			sh->flags = SHF_ALLOC+SHF_WRITE;
			sh->entsize = 8;
			sh->addralign = 4;
			sh->link = dynsym+1;	// dynstr
			shsym(sh, lookup(".dynamic", 0));

			ph = newElfPhdr();
			ph->type = PT_DYNAMIC;
			ph->flags = PF_R + PF_W;
			phsh(ph, sh);

			/*
			 * Thread-local storage segment (really just size).
			if(tlsoffset != 0) {
				ph = newElfPhdr();
				ph->type = PT_TLS;
				ph->flags = PF_R;
				ph->memsz = -tlsoffset;
				ph->align = 4;
			}
			 */
		}

		ph = newElfPhdr();
		ph->type = PT_GNU_STACK;
		ph->flags = PF_W+PF_R;
		ph->align = 4;

		sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
		sh->type = SHT_STRTAB;
		sh->addralign = 1;
		shsym(sh, lookup(".shstrtab", 0));

		if(elftextsh != eh->shnum)
			diag("elftextsh = %d, want %d", elftextsh, eh->shnum);
		for(sect=segtext.sect; sect!=nil; sect=sect->next)
			elfshbits(sect);
		for(sect=segdata.sect; sect!=nil; sect=sect->next)
			elfshbits(sect);

		if(!debug['s']) {
			sh = newElfShdr(elfstr[ElfStrSymtab]);
			sh->type = SHT_SYMTAB;
			sh->off = symo;
			sh->size = symsize;
			sh->addralign = 4;
			sh->entsize = 16;
			sh->link = eh->shnum;	// link to strtab

			sh = newElfShdr(elfstr[ElfStrStrtab]);
			sh->type = SHT_STRTAB;
			sh->off = symo+symsize;
			sh->size = elfstrsize;
			sh->addralign = 1;

			// dwarfaddelfheaders();
		}

		/* Main header */
		eh->ident[EI_MAG0] = '\177';
		eh->ident[EI_MAG1] = 'E';
		eh->ident[EI_MAG2] = 'L';
		eh->ident[EI_MAG3] = 'F';
		eh->ident[EI_CLASS] = ELFCLASS32;
		eh->ident[EI_DATA] = ELFDATA2LSB;
		eh->ident[EI_VERSION] = EV_CURRENT;

		eh->type = ET_EXEC;
		eh->machine = EM_ARM;
		eh->version = EV_CURRENT;
		eh->entry = entryvalue();

		if(pph != nil) {
			pph->filesz = eh->phnum * eh->phentsize;
			pph->memsz = pph->filesz;
		}

		cseek(0);
		a = 0;
		a += elfwritehdr();
		a += elfwritephdrs();
		a += elfwriteshdrs();
		a += elfwriteinterp(elfstr[ElfStrInterp]);
		if(HEADTYPE == Hnetbsd)
			a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
		if(a > ELFRESERVE)	
			diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
		break;
	}
	cflush();
	if(debug['c']){
		print("textsize=%d\n", textsize);
		print("datsize=%ulld\n", segdata.filelen);
		print("bsssize=%ulld\n", segdata.len - segdata.filelen);
		print("symsize=%d\n", symsize);
		print("lcsize=%d\n", lcsize);
		print("total=%lld\n", textsize+segdata.len+symsize+lcsize);
	}
}
Пример #15
0
signed int 
xdelta1ReconstructDCBuff(DCB_SRC_ID src_id, cfile *patchf, CommandBuffer *dcbuff, 
	unsigned int version)
{
	cfile *add_cfh, *ctrl_cfh;
	unsigned long control_offset, control_end, flags;
	unsigned long len, offset, x, count, proc_count;
	unsigned long add_start, add_pos;
	unsigned char buff[32];
	EDCB_SRC_ID ref_id, add_id;
	unsigned char add_is_sequential, copy_is_sequential;
	cseek(patchf, XDELTA_MAGIC_LEN, CSEEK_FSTART);
	cread(patchf, buff, 4);
	flags = readUBytesBE(buff, 4);
	cread(patchf, buff, 4);

	dcbuff->ver_size = 0;
	
	// the header is 32 bytes, then 2 word's, each the length of the 
	// src/trg file name.
	add_start = 32 + readUBytesBE(buff, 2) + readUBytesBE(buff + 2, 2);
	cseek(patchf, -12, CSEEK_END);
	control_end = ctell(patchf, CSEEK_FSTART);
	cread(patchf, buff, 4);
	control_offset = readUBytesBE(buff,4);

	cseek(patchf, control_offset, CSEEK_FSTART);

	if(flags & XD_COMPRESSED_FLAG) {
		v2printf("compressed segments detected\n");
		if((ctrl_cfh = (cfile *)malloc(sizeof(cfile)))==NULL) {
			return MEM_ERROR;
		}
		copen_child_cfh(ctrl_cfh, patchf, control_offset, control_end, 
			GZIP_COMPRESSOR, CFILE_RONLY);
	} else {
		ctrl_cfh = patchf;
	}

	/* kludge. skipping 8 byte unknown, and to_file md5.*/
	cseek(ctrl_cfh, 24, CSEEK_CUR);

	/* read the frigging to length, since it's variable */
	x = readXDInt(ctrl_cfh, buff);
		v2printf("to_len(%lu)\n", x);

	/* two bytes here I don't know about... */
	cseek(ctrl_cfh, 2, CSEEK_CUR);
	/* get and skip the segment name's len and md5 */
	x = readXDInt(ctrl_cfh, buff);

	cseek(ctrl_cfh, x + 16, CSEEK_CUR);

	/* read the damned segment patch len. */
	x = readXDInt(ctrl_cfh, buff);

	/* skip the seq/has data bytes */
	/* handle sequential/has_data info */
	cread(ctrl_cfh, buff, 2);
	add_is_sequential = buff[1];

	v2printf("patch sequential? (%u)\n", add_is_sequential);

	/* get and skip the next segment name len and md5. */
	x = readXDInt(ctrl_cfh, buff);
	cseek(ctrl_cfh, x + 16, CSEEK_CUR);

	/* read the damned segment patch len. */
	x = readXDInt(ctrl_cfh, buff);
	v2printf("seg2_len(%lu)\n", x);

	/* handle sequential/has_data */
	cread(ctrl_cfh, buff, 2);
	copy_is_sequential = buff[1];
	v2printf("copy is sequential? (%u)\n", copy_is_sequential);
	/* next get the number of instructions (eg copy | adds) */
	count = readXDInt(ctrl_cfh, buff);
	proc_count=0;
	/* so starts the commands... */
	v2printf("supposedly %lu commands...\nstarting command processing at %zi\n",
		count, ctell(ctrl_cfh, CSEEK_FSTART));
	if(flags & XD_COMPRESSED_FLAG) {
		add_pos = 0;
		if((add_cfh = (cfile *)malloc(sizeof(cfile)))==NULL) {
			return MEM_ERROR;
		}
		copen_child_cfh(add_cfh, patchf, add_start, control_offset, 
			GZIP_COMPRESSOR, CFILE_RONLY);
		add_id = DCB_REGISTER_ADD_SRC(dcbuff, add_cfh, NULL, 1);
	} else {
		add_pos = add_start;
		add_id = DCB_REGISTER_VOLATILE_ADD_SRC(dcbuff, patchf, NULL, 0);
	}
	ref_id = src_id;
	while(proc_count++ != count) {
		x = readXDInt(ctrl_cfh, buff);
		offset = readXDInt(ctrl_cfh, buff);
		len = readXDInt(ctrl_cfh, buff);
		if(x==XD_INDEX_COPY) {
			DCB_add_copy(dcbuff, offset, 0, len, ref_id);
		} else {
			if(add_is_sequential != 0) {
				offset += add_pos; 
				add_pos += len;
			} else {
				offset += add_pos;
			}
			DCB_add_add(dcbuff, offset, len, add_id);
		}
	}
	v2printf("finishing position was %zi\n", ctell(ctrl_cfh, CSEEK_FSTART));
	v2printf("processed %lu of %lu commands\n", proc_count, count);
	dcbuff->ver_size = dcbuff->reconstruct_pos;
	if(flags & XD_COMPRESSED_FLAG) {
		cclose(ctrl_cfh);
		free(ctrl_cfh);
	}
	return 0;
}
Пример #16
0
void
asmb(void)
{
	int32 v, magic;
	uint32 symo, dwarfoff, machlink;
	Section *sect;
	Sym *sym;
	int i;

	if(debug['v'])
		Bprint(&bso, "%5.2f asmb\n", cputime());
	Bflush(&bso);

	if(iself)
		asmbelfsetup();

	sect = segtext.sect;
	cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
	codeblk(sect->vaddr, sect->len);
	for(sect = sect->next; sect != nil; sect = sect->next) {
		cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
		datblk(sect->vaddr, sect->len);
	}
	
	if(segrodata.filelen > 0) {
		if(debug['v'])
			Bprint(&bso, "%5.2f rodatblk\n", cputime());
		Bflush(&bso);

		cseek(segrodata.fileoff);
		datblk(segrodata.vaddr, segrodata.filelen);
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f datblk\n", cputime());
	Bflush(&bso);

	cseek(segdata.fileoff);
	datblk(segdata.vaddr, segdata.filelen);

	machlink = 0;
	if(HEADTYPE == Hdarwin) {
		if(debug['v'])
			Bprint(&bso, "%5.2f dwarf\n", cputime());

		dwarfoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND);
		cseek(dwarfoff);

		segdwarf.fileoff = cpos();
		dwarfemitdebugsections();
		segdwarf.filelen = cpos() - segdwarf.fileoff;

		machlink = domacholink();
	}

	symsize = 0;
	spsize = 0;
	lcsize = 0;
	symo = 0;
	if(!debug['s']) {
		// TODO: rationalize
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		Bflush(&bso);
		switch(HEADTYPE) {
		default:
			if(iself)
				goto Elfsym;
		case Hgarbunix:
			symo = rnd(HEADR+segtext.filelen, 8192)+segdata.filelen;
			break;
		case Hunixcoff:
			symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
			break;
		case Hplan9x32:
			symo = HEADR+segtext.filelen+segdata.filelen;
			break;
		case Hmsdoscom:
		case Hmsdosexe:
			debug['s'] = 1;
			symo = HEADR+segtext.filelen+segdata.filelen;
			break;
		case Hdarwin:
			symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
			break;
		Elfsym:
			symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(HEADR+segrodata.filelen, INITRND)+segdata.filelen;
			symo = rnd(symo, INITRND);
			break;
		case Hwindows:
			symo = rnd(HEADR+segtext.filelen, PEFILEALIGN)+segdata.filelen;
			symo = rnd(symo, PEFILEALIGN);
			break;
		}
		cseek(symo);
		switch(HEADTYPE) {
		default:
			if(iself) {
				if(debug['v'])
					Bprint(&bso, "%5.2f elfsym\n", cputime());
				asmelfsym();
				cflush();
				cwrite(elfstrdat, elfstrsize);

				if(debug['v'])
					Bprint(&bso, "%5.2f dwarf\n", cputime());
				dwarfemitdebugsections();
				
				if(linkmode == LinkExternal)
					elfemitreloc();
			}
			break;
		case Hplan9x32:
			asmplan9sym();
			cflush();

			sym = lookup("pclntab", 0);
			if(sym != nil) {
				lcsize = sym->np;
				for(i=0; i < lcsize; i++)
					cput(sym->p[i]);
				
				cflush();
			}
			break;
		case Hwindows:
			if(debug['v'])
				Bprint(&bso, "%5.2f dwarf\n", cputime());
			dwarfemitdebugsections();
			break;
		case Hdarwin:
			if(linkmode == LinkExternal)
				machoemitreloc();
			break;
		}
	}
	if(debug['v'])
		Bprint(&bso, "%5.2f headr\n", cputime());
	Bflush(&bso);
	cseek(0L);
	switch(HEADTYPE) {
	default:
	case Hgarbunix:	/* garbage */
		lputb(0x160L<<16);		/* magic and sections */
		lputb(0L);			/* time and date */
		lputb(rnd(HEADR+segtext.filelen, 4096)+segdata.filelen);
		lputb(symsize);			/* nsyms */
		lputb((0x38L<<16)|7L);		/* size of optional hdr and flags */
		lputb((0413<<16)|0437L);		/* magic and version */
		lputb(rnd(HEADR+segtext.filelen, 4096));	/* sizes */
		lputb(segdata.filelen);
		lputb(segdata.len - segdata.filelen);
		lputb(entryvalue());		/* va of entry */
		lputb(INITTEXT-HEADR);		/* va of base of text */
		lputb(segdata.vaddr);			/* va of base of data */
		lputb(segdata.vaddr+segdata.filelen);		/* va of base of bss */
		lputb(~0L);			/* gp reg mask */
		lputb(0L);
		lputb(0L);
		lputb(0L);
		lputb(0L);
		lputb(~0L);			/* gp value ?? */
		break;
	case Hunixcoff:	/* unix coff */
		/*
		 * file header
		 */
		lputl(0x0004014c);		/* 4 sections, magic */
		lputl(0);			/* unix time stamp */
		lputl(0);			/* symbol table */
		lputl(0);			/* nsyms */
		lputl(0x0003001c);		/* flags, sizeof a.out header */
		/*
		 * a.out header
		 */
		lputl(0x10b);			/* magic, version stamp */
		lputl(rnd(segtext.filelen, INITRND));	/* text sizes */
		lputl(segdata.filelen);			/* data sizes */
		lputl(segdata.len - segdata.filelen);			/* bss sizes */
		lputb(entryvalue());		/* va of entry */
		lputl(INITTEXT);		/* text start */
		lputl(segdata.vaddr);			/* data start */
		/*
		 * text section header
		 */
		s8put(".text");
		lputl(HEADR);			/* pa */
		lputl(HEADR);			/* va */
		lputl(segtext.filelen);		/* text size */
		lputl(HEADR);			/* file offset */
		lputl(0);			/* relocation */
		lputl(0);			/* line numbers */
		lputl(0);			/* relocation, line numbers */
		lputl(0x20);			/* flags text only */
		/*
		 * data section header
		 */
		s8put(".data");
		lputl(segdata.vaddr);			/* pa */
		lputl(segdata.vaddr);			/* va */
		lputl(segdata.filelen);			/* data size */
		lputl(HEADR+segtext.filelen);		/* file offset */
		lputl(0);			/* relocation */
		lputl(0);			/* line numbers */
		lputl(0);			/* relocation, line numbers */
		lputl(0x40);			/* flags data only */
		/*
		 * bss section header
		 */
		s8put(".bss");
		lputl(segdata.vaddr+segdata.filelen);		/* pa */
		lputl(segdata.vaddr+segdata.filelen);		/* va */
		lputl(segdata.len - segdata.filelen);			/* bss size */
		lputl(0);			/* file offset */
		lputl(0);			/* relocation */
		lputl(0);			/* line numbers */
		lputl(0);			/* relocation, line numbers */
		lputl(0x80);			/* flags bss only */
		/*
		 * comment section header
		 */
		s8put(".comment");
		lputl(0);			/* pa */
		lputl(0);			/* va */
		lputl(symsize+lcsize);		/* comment size */
		lputl(HEADR+segtext.filelen+segdata.filelen);	/* file offset */
		lputl(HEADR+segtext.filelen+segdata.filelen);	/* offset of syms */
		lputl(HEADR+segtext.filelen+segdata.filelen+symsize);/* offset of line numbers */
		lputl(0);			/* relocation, line numbers */
		lputl(0x200);			/* flags comment only */
		break;
	case Hplan9x32:	/* plan9 */
		magic = 4*11*11+7;
		lputb(magic);		/* magic */
		lputb(segtext.filelen);			/* sizes */
		lputb(segdata.filelen);
		lputb(segdata.len - segdata.filelen);
		lputb(symsize);			/* nsyms */
		lputb(entryvalue());		/* va of entry */
		lputb(spsize);			/* sp offsets */
		lputb(lcsize);			/* line offsets */
		break;
	case Hmsdoscom:
		/* MS-DOS .COM */
		break;
	case Hmsdosexe:
		/* fake MS-DOS .EXE */
		v = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
		wputl(0x5A4D);			/* 'MZ' */
		wputl(v % 512);			/* bytes in last page */
		wputl(rnd(v, 512)/512);		/* total number of pages */
		wputl(0x0000);			/* number of reloc items */
		v = rnd(HEADR-(INITTEXT & 0xFFFF), 16);
		wputl(v/16);			/* size of header */
		wputl(0x0000);			/* minimum allocation */
		wputl(0xFFFF);			/* maximum allocation */
		wputl(0x0000);			/* initial ss value */
		wputl(0x0100);			/* initial sp value */
		wputl(0x0000);			/* complemented checksum */
		v = entryvalue();
		wputl(v);			/* initial ip value (!) */
		wputl(0x0000);			/* initial cs value */
		wputl(0x0000);
		wputl(0x0000);
		wputl(0x003E);			/* reloc table offset */
		wputl(0x0000);			/* overlay number */
		break;
	case Hdarwin:
		asmbmacho();
		break;
	case Hlinux:
	case Hfreebsd:
	case Hnetbsd:
	case Hopenbsd:
	case Hdragonfly:
	case Hhaiku:
		asmbelf(symo);
		break;
	case Hwindows:
		asmbpe();
		break;
	}
	cflush();
}
Пример #17
0
Файл: pe.c Проект: rosrad/go-rep
static void
addimports(IMAGE_SECTION_HEADER *datsect)
{
	IMAGE_SECTION_HEADER *isect;
	uvlong n, oftbase, ftbase;
	vlong startoff, endoff;
	Imp *m;
	Dll *d;
	LSym* dynamic;
	
	startoff = cpos();
	dynamic = linklookup(ctxt, ".windynamic", 0);

	// skip import descriptor table (will write it later)
	n = 0;
	for(d = dr; d != nil; d = d->next)
		n++;
	cseek(startoff + sizeof(IMAGE_IMPORT_DESCRIPTOR) * (n + 1));

	// write dll names
	for(d = dr; d != nil; d = d->next) {
		d->nameoff = cpos() - startoff;
		strput(d->name);
	}

	// write function names
	for(d = dr; d != nil; d = d->next) {
		for(m = d->ms; m != nil; m = m->next) {
			m->off = nextsectoff + cpos() - startoff;
			wputl(0); // hint
			strput(m->s->extname);
		}
	}
	
	// write OriginalFirstThunks
	oftbase = cpos() - startoff;
	n = cpos();
	for(d = dr; d != nil; d = d->next) {
		d->thunkoff = cpos() - n;
		for(m = d->ms; m != nil; m = m->next)
			put(m->off);
		put(0);
	}

	// add pe section and pad it at the end
	n = cpos() - startoff;
	isect = addpesection(".idata", n, n);
	isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
		IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
	chksectoff(isect, startoff);
	strnput("", isect->SizeOfRawData - n);
	endoff = cpos();

	// write FirstThunks (allocated in .data section)
	ftbase = dynamic->value - datsect->VirtualAddress - PEBASE;
	cseek(datsect->PointerToRawData + ftbase);
	for(d = dr; d != nil; d = d->next) {
		for(m = d->ms; m != nil; m = m->next)
			put(m->off);
		put(0);
	}
	
	// finally write import descriptor table
	cseek(startoff);
	for(d = dr; d != nil; d = d->next) {
		lputl(isect->VirtualAddress + oftbase + d->thunkoff);
		lputl(0);
		lputl(0);
		lputl(isect->VirtualAddress + d->nameoff);
		lputl(datsect->VirtualAddress + ftbase + d->thunkoff);
	}
	lputl(0); //end
	lputl(0);
	lputl(0);
	lputl(0);
	lputl(0);
	
	// update data directory
	dd[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress;
	dd[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
	dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE;
	dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;

	cseek(endoff);
}
Пример #18
0
int
read_entry(cfile *src_cfh, off_u64 start, tar_entry *entry)
{
	unsigned char block[512];
	unsigned int read_bytes;
	unsigned int name_len, prefix_len;

	if(start != cseek(src_cfh, start, CSEEK_FSTART)) {
			return IO_ERROR;
	}
	if((read_bytes=cread(src_cfh, block, 512))!=512) {
			return IO_ERROR;
	}
	entry->start = start;
	entry->end = 512 + start;
	if(strnlen((const char *)block, 512)==0)  {
		return TAR_EMPTY_ENTRY;
	}
	if (! check_str_chksum(block)) {
		v0printf("checksum failed on a tarfile, bailing\n");
		return IO_ERROR;
	}
	if('L'==block[TAR_TYPEFLAG_LOC]) {
		v2printf("handling longlink at %llu eg(%llu)\n", (act_off_u64)start, (act_off_u64)(start * 512));
		name_len = octal_str2long(block + TAR_SIZE_LOC, TAR_SIZE_LEN);
		if((read_bytes=cread(src_cfh, block, 512))!=512) {
			v0printf("unexpected EOF on tarfile, bailing\n");
			return EOF_ERROR;
		}
		if((entry->fullname = 
			(unsigned char *)malloc(name_len + 1))==NULL){
			v0printf("unable to allocate memory for name_len, bailing\n");
			return EOF_ERROR;
		}
		memcpy(entry->fullname, block, name_len);
		if((read_bytes=cread(src_cfh, block, 512))!=512){
			v0printf("unable to allocate memory for fullname, bailing\n");
			return EOF_ERROR;
		}
		if(! check_str_chksum(block)) {
			v0printf("tar checksum failed for tar entry at %llu, bailing\n", (act_off_u64)start);
			// IO_ERROR? please.  add data_error.
			return IO_ERROR;
		}
		entry->fullname[name_len] = '\0';
		entry->end += octal_str2long(block + TAR_SIZE_LOC, TAR_SIZE_LEN) + 1024;
	} else {
		name_len = strnlen((char *)block + TAR_NAME_LOC, TAR_NAME_LEN);
		prefix_len = strnlen((char *)block + TAR_PREFIX_LOC, TAR_PREFIX_LEN);

		// check if space will be needed for the slash
		prefix_len += (prefix_len==0 ? 0 : 1);
		if((entry->fullname = 
			(unsigned char *)malloc(name_len + prefix_len + 1))==NULL){
			v0printf("unable to allocate needed memory, bailing\n");
			return MEM_ERROR;
		}
		if(prefix_len) {
			memcpy(entry->fullname, block + TAR_PREFIX_LOC, prefix_len -1);
			entry->fullname[prefix_len] = '/';
			memcpy(entry->fullname + prefix_len, block + TAR_NAME_LOC, name_len);
			entry->fullname[prefix_len + name_len ] = '\0';
		} else {
			memcpy(entry->fullname, block + TAR_NAME_LOC, name_len);
			entry->fullname[name_len] = '\0';
		}
		entry->end += octal_str2long(block + TAR_SIZE_LOC, TAR_SIZE_LEN);
	}
	if(entry->end % 512)
		entry->end += 512 - (entry->end % 512);
	return 0;
}