Example #1
0
void
reader(void *v)
{
	int cfd, tfd, forking = 0, pid, newpid;
	char *ctl, *truss;
	Msg *s;

	pid = (int)(uintptr)v;
	ctl = smprint("/proc/%d/ctl", pid);
	if ((cfd = open(ctl, OWRITE)) < 0)
		die(smprint("%s: %r", ctl));
	truss = smprint("/proc/%d/syscall", pid);
	if ((tfd = open(truss, OREAD)) < 0)
		die(smprint("%s: %r", truss));

	cwrite(cfd, ctl, "stop", 4);
	cwrite(cfd, truss, "startsyscall", 12);

	s = mallocz(sizeof(Msg) + Bufsize, 1);
	s->pid = pid;
	s->buf = (char *)&s[1];
	while(pread(tfd, s->buf, Bufsize - 1, 0) > 0){
		if (forking && s->buf[1] == '=' && s->buf[3] != '-') {
			forking = 0;
			newpid = strtol(&s->buf[3], 0, 0);
			sendp(forkc, (void*)newpid);
			procrfork(reader, (void*)newpid, Stacksize, 0);
		}

		/*
		 * There are three tests here and they (I hope) guarantee
		 * no false positives.
		 */
		if (strstr(s->buf, " Rfork") != nil) {
			char *a[8];
			char *rf;

			rf = strdup(s->buf);
         		if (tokenize(rf, a, 8) == 5) {
				ulong flags;

				flags = strtoul(a[4], 0, 16);
				if (flags & RFPROC)
					forking = 1;
			}
			free(rf);
		}
		sendp(out, s);
		cwrite(cfd, truss, "startsyscall", 12);
		s = mallocz(sizeof(Msg) + Bufsize, 1);
		s->pid = pid;
		s->buf = (char *)&s[1];
	}
	sendp(quit, nil);
	threadexitsall(nil);
}
Example #2
0
void
reader(void *v)
{
	char *ctl, *truss;
	int pid, newpid;
	int cfd, tfd;
	Str *s;
	int forking = 0;

	pid = (int)v;
	ctl = smprint("/proc/%d/ctl", pid);
	if ((cfd = open(ctl, OWRITE)) < 0)
		die(smprint("%s: %r", ctl));
	truss = smprint("/proc/%d/syscall", pid);
	if ((tfd = open(truss, OREAD)) < 0)
		die(smprint("%s: %r", truss));

	cwrite(cfd, ctl, "stop", 4);
	cwrite(cfd, truss, "startsyscall", 12);

	s = mallocz(sizeof(Str) + 8192, 1);
	s->buf = (char *)&s[1];
	/* 8191 is not a typo. It ensures a null-terminated string. The device currently limits to 4096 anyway */
	while((s->len = pread(tfd, s->buf, 8191, 0ULL)) > 0){
		if (forking && (s->buf[1] == '=') && (s->buf[3] != '-')) {
			forking = 0;
			newpid = strtol(&s->buf[3], 0, 0);
			sendp(forkc, (void*)newpid);
			procrfork(reader, (void*)newpid, 8192, 0);
		}

		/* There are three tests here and they (I hope) guarantee no false positives */
		if (strstr(s->buf, " Rfork") != nil) {
			char *a[8];
			char *rf;
			rf = strdup(s->buf);
         		if (tokenize(rf, a, 8) == 5) {
				unsigned long flags;
				flags = strtoul(a[4], 0, 16);
				if (flags & RFPROC)
					forking = 1;
			}
			free(rf);			
		}
		sendp(out, s);			
		cwrite(cfd, truss, "startsyscall", 12);
		s = mallocz(sizeof(Str) + 8192, 1);
		s->buf = (char *)&s[1];

	}
	sendp(quit, nil);
	threadexitsall(nil);
}
Example #3
0
int
elfwritebuildinfo(void)
{
	ElfShdr *sh;

	sh = elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, buildinfolen, ELF_NOTE_BUILDINFO_TAG);
	if(sh == nil)
		return 0;

	cwrite(ELF_NOTE_BUILDINFO_NAME, ELF_NOTE_BUILDINFO_NAMESZ);
	cwrite(buildinfo, buildinfolen);
	cwrite("\0\0\0", rnd(buildinfolen, 4) - buildinfolen);

	return sh->size;
}
Example #4
0
int ArduinoCOIL::readRawSensor (seeyou_sensor packet, byte* buffer, int size)
{
    int numread = 0;
    byte cmd[3];
    cmd[0] = packet;
    cmd[1] = TRAILER;
    cmd[2] = CARRIAGE_RETURN;

    if (cwrite (port, cmd, 3) < 0)
    {
        Debug::error ("[COIL] Could not request sensor");
        return -1;
    }

    SleeperThread::msleep(40); // BUG: Why must we sleep? RTFM...

    numread = cread (port, buffer, size, packet);
    if (numread < 0)
    {
        Debug::error ("[COIL] Could not read sensor");
        return -1;
    }

    return numread;
}
Example #5
0
File: pe.c Project: rosrad/go-rep
void
addpersrc(void)
{
	IMAGE_SECTION_HEADER *h;
	uchar *p;
	uint32 val;
	Reloc *r;

	if(rsrcsym == nil)
		return;
	
	h = addpesection(".rsrc", rsrcsym->size, rsrcsym->size);
	h->Characteristics = IMAGE_SCN_MEM_READ|
		IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA;
	chksectoff(h, cpos());
	// relocation
	for(r=rsrcsym->r; r<rsrcsym->r+rsrcsym->nr; r++) {
		p = rsrcsym->p + r->off;
		val = h->VirtualAddress + r->add;
		// 32-bit little-endian
		p[0] = val;
		p[1] = val>>8;
		p[2] = val>>16;
		p[3] = val>>24;
	}
	cwrite(rsrcsym->p, rsrcsym->size);
	strnput("", h->SizeOfRawData - rsrcsym->size);

	// update data directory
	dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h->VirtualAddress;
	dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h->VirtualSize;
}
Example #6
0
void* mon_net2tap (void* fd)
{

	uint16_t nread, nwrite;
	char buffer[BUFSIZE]; 
	unsigned long int net2tap = 0;
	struct fd *fds = fd;
	socklen_t sin_size;

	while (1) {
		/* data from the network: read it, and write it to the tun/tap interface. 
       	 	* We need to read the length first, and then the packet */

        	/* Read length */
		nread = recvfrom(fds->local_net_fd, buffer, sizeof(buffer), 0, 
						(struct sockaddr*)&fds->local, &sin_size);

      		if(nread == 0) {
        		/* ctrl-c at the other end */
        		break;
      		}
		
		net2tap++;
		/* read packet */
      		do_debug("NET2TAP %lu: Read %d bytes from the network\n", net2tap, nread);

      		/* now buffer[] contains a full packet or frame, write it into the tun/tap interface */
      		nwrite = cwrite(fds->tap_fd, buffer, nread);
      		do_debug("NET2TAP %lu: Written %d bytes to the tap interface\n", net2tap, nwrite);
	}

	exit(1);
}
Example #7
0
int get_ip_from_server(int net_fd, char *devname)
{
	char *buffer;

	// Get IP Address from server
	buffer = malloc(100) ;
	struct ip_header *iphdr = (struct ip_header*)buffer ;
	memset(buffer,0,100) ;
	iphdr->vers = 0x45 ;
	iphdr->ip_header_len = 20 ;
	iphdr->ttl = 64;
	if(cwrite(net_fd, buffer, 20) <= 0)
	{
		printf("error: write failed while getting IP address from server\n");
		exit(1);
	}

	cread(net_fd, buffer, 100) ;
	printf("Got IP response: %08x\n", ntohl(iphdr->dest_ip)) ;

	set_ip(devname, ntohl(iphdr->dest_ip), 0xffff0000);

	// Set the interface address.
	free(buffer) ;

	return 0;
}
Example #8
0
File: pe.c Project: 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]);
}
Example #9
0
int
elfwriteinterp(void)
{
	ElfShdr *sh;
	
	sh = elfshname(".interp");
	cseek(sh->off);
	cwrite(interp, sh->size);
	return sh->size;
}
Example #10
0
int
elfwriteinterp(void)
{
	int n;

	if(interp == nil)
		return 0;

	n = strlen(interp)+1;
	cseek(ELFRESERVE-n);
	cwrite(interp, n);
	return n;
}
Example #11
0
File: thread.c Project: zhyg/mapred
void revent_handler(int fd, short e, void* args)
{
    char*   line = NULL;
    int     len = 0;
    struct  fdev_t* fdev = (struct fdev_t*)args;
    IOstream* b = &fdev->stream;

    if (try_read_more(b) == E_ERROR) {
        if (b->bytes > 0) {
            cwrite(STDOUT_FILENO, b->cur, b->bytes);
        }
        event_del(&fdev->ev);
        return;
    }

    for (; get_line(b, &line, &len) == E_OK; ) {
        if (cwrite(STDOUT_FILENO, line, len) < 0) {
            log("STDOUT write error: %s", strerror(errno));
            event_del(&fdev->ev);
            return;
        }
    }
}
Example #12
0
int ArduinoCOIL::setLEDState ()
{
    byte cmd[3];
    cmd[0] = SENSOR_LED_INDICATOR;
    cmd[1] = TRAILER;
    cmd[2] = CARRIAGE_RETURN;

    if (cwrite (port, cmd, 3) < 0)
    {
        Debug::error ("[ArduinoCOIL] Could not set LED status");
        return -1;
    }
    return 0;
}
Example #13
0
int write_n(int fd, char *buf, int n) {

    int nwrite, left = n;

    while(left > 0) {
        if ((nwrite = cwrite(fd, buf, left)) == 0){
            return 0 ;
        }else {
            left -= nwrite;
            buf += nwrite;
        }
    }
    return n;
}
Example #14
0
void
hang(void)
{
	int me;
	char *myctl;
	static char hang[] = "hang";

	myctl = smprint("/proc/%d/ctl", getpid());
	me = open(myctl, OWRITE);
	if (me < 0)
		sysfatal("can't open %s: %r", myctl);
	cwrite(me, myctl, hang, sizeof hang - 1);
	close(me);
	free(myctl);
}
Example #15
0
int
elfwriteopenbsdsig(void)
{
	ElfShdr *sh;

	// Write Elf_Note header.
	sh = elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG);
	if(sh == nil)
		return 0;

	// Followed by OpenBSD string and version.
	cwrite(ELF_NOTE_OPENBSD_NAME, ELF_NOTE_OPENBSD_NAMESZ);
	LPUT(ELF_NOTE_OPENBSD_VERSION);

	return sh->size;
}
Example #16
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;
}
Example #17
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;
}
void
OpenJournal (void)
{
    DWORD start_seed;

#if CREATE_JOURNAL
    if (create_journal)
    {
        if (journal_fh = copen (journal_buf, MEMORY_STREAM, STREAM_WRITE))
        {
            start_seed = SeedRandomNumbers ();
            cwrite ((PBYTE)&start_seed, sizeof (start_seed), 1, journal_fh);
        }
    }
    else
#endif /* CREATE_JOURNAL */
    {
        uio_Stream *fp;

        if (fp = res_OpenResFile ("starcon.jnl", "rb"))
        {
            ReadResFile (journal_buf, 1, sizeof (journal_buf), fp);
            res_CloseResFile (fp);

            if (journal_fh = copen (journal_buf, MEMORY_STREAM, STREAM_READ))
            {
                OldArrowInput = ArrowInput;
                ArrowInput = DemoInput;
                PlayerInput[0] = PlayerInput[1] = DemoInput;

                FlushInput ();

                cread ((PBYTE)&start_seed, sizeof (start_seed), 1, journal_fh);
                TFB_SeedRandom (start_seed);
            }
        }
    }
}
Example #19
0
int register_static_ip(int net_fd, int ip, char *devname)
{
	char *buffer;
	int nread;

	// Static IP
	buffer = malloc(100);
	struct ip_header *iphdr = (struct ip_header*)buffer;
	memset(buffer,0,100);
	iphdr->vers = 0x45;
	iphdr->ip_header_len = 20;
	iphdr->ttl = 64;
	iphdr->source_ip = ip;
	if(cwrite(net_fd, buffer, 20) <= 0)
	{
		printf("error: write failed while requesting static IP address from server.\n");
		exit(1);
	}

	nread = cread(net_fd, buffer, 100) ;

	if(nread == 0)
	{
		// Connection closed while trying to assign a statick IP. This means that someone else already has that address.
		fprintf(stderr, "ERROR: Requested static IP address already in use.\n");
		exit(0);
	}

	set_ip(devname, ntohl(iphdr->dest_ip), 0xffff0000);
	if(add_host_route(devname, (in_addr_t)ntohl(iphdr->dest_ip)) < 0)
		printf("add_host_route returned\n");

	// Set the interface address.
	free(buffer) ;

	return 0;
}
Example #20
0
static void
fqd_http_jsend(remote_client *client, const char *status, const char *fmt, ...)
{
  char error[1024] = {0};
  char scratch[1024] = {0};
  const char *headers = "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
  va_list argp;

  va_start(argp, fmt);
  vsnprintf(error, sizeof(error), fmt, argp);
  va_end(argp);

  while(write(client->fd, headers, strlen(headers)) == -1 && errno == EINTR);
  cwrite(client, "{\n");
  cwrite(client, scratch);
  cwrite(client,  " \"status\": \"");
  cwrite(client, status);
  cwrite(client,  "\",\n");
  sprintf(scratch, " \"message\": \"%s\"\n", error);
  cwrite(client, scratch);
  cwrite(client, "}\n");
}
Example #21
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();
}
Example #22
0
int main(int argc, char *argv[]) {
  
	int tap_fd, option;
	int flags = IFF_TUN;
	char if_name[IFNAMSIZ] = "";
	int header_len = IP_HDR_LEN;
	int maxfd;
	uint16_t nread, nwrite, plength;
	char buffer[BUFSIZE];
	struct sockaddr_in local, remote;
	char remote_ip[16] = "";
	unsigned short int port = PORT;
	int sock_fd, net_fd, optval = 1;
	socklen_t remotelen;
	int cliserv = -1;    /* must be specified on cmd line */
	unsigned long int tap2net = 0, net2tap = 0;

	int listen_sd;
  	int sd;
  	struct sockaddr_in sa_serv;
	struct sockaddr_in sa_cli;
	size_t client_len;
	int err;
	int yes = 1;

	struct ip *ip_header;            //ip header struct
	struct VPNDataHdr* vpn_header;

	int ptc[2];         //pipe from control process to tunnel process

	progname = argv[0];
  
  /* Check command line options */
  while((option = getopt(argc, argv, "i:sc:p:uahd")) > 0){
    switch(option) {
      case 'd':
        debug = 1;
        break;
      case 'h':
        usage();
        break;
      case 'i':
        strncpy(if_name,optarg,IFNAMSIZ-1);
        break;
      case 's':
        cliserv = SERVER;
        break;
      case 'c':
        cliserv = CLIENT;
        strncpy(remote_ip,optarg,15);
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'u':
        flags = IFF_TUN;
        break;
      case 'a':
        flags = IFF_TAP;
        header_len = ETH_HDR_LEN;
        break;
      default:
        my_err("Unknown option %c\n", option);
        usage();
    }
  }

  argv += optind;
  argc -= optind;

  if(argc > 0){
    my_err("Too many options!\n");
    usage();
  }

  if(*if_name == '\0'){
    my_err("Must specify interface name!\n");
    usage();
  }else if(cliserv < 0){
    my_err("Must specify client or server mode!\n");
    usage();
  }else if((cliserv == CLIENT)&&(*remote_ip == '\0')){
    my_err("Must specify server address!\n");
    usage();
  }

  /* initialize tun/tap interface */
  if ( (tap_fd = tun_alloc(if_name, flags | IFF_NO_PI)) < 0 ) {
    my_err("Error connecting to tun/tap interface %s!\n", if_name);
    exit(1);
  }

  do_debug("Successfully connected to interface %s\n", if_name);
  




 
  	if ( (sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    	 perror("socket()");
   	 exit(1);
 	 }

	/////////////////////////////////////////////////////////


    	memset(&local, 0, sizeof(local));
    	local.sin_family = AF_INET;
    	local.sin_addr.s_addr = htonl(INADDR_ANY);
    	local.sin_port = htons(port);
    	if (bind(sock_fd, (struct sockaddr*) &local, sizeof(local)) < 0){
      	perror("bind()");
      	exit(1);
    	}

	//init remote
	memset(&remote, 0, sizeof(remote));
	remote.sin_family = AF_INET;
	//remote.sin_addr.s_addr = inet_addr(remote_ip);
  	remote.sin_port = htons(port);	



	net_fd = sock_fd;

    	do_debug("SERVER: UDP built\n");
	//////////////////////////////////////////////////////////////////////

///////////ssl tcp control connection////////////////
	loadcert();
	listen_sd = socket (AF_INET, SOCK_STREAM, 0);   
	if(err < 0){
		printf("err tcp listening sock!\n");
		return 0;
	}
   
	if(setsockopt(listen_sd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1){
		perror("Server-socket() error lol!");
		exit(1);
	}  


	memset (&sa_serv, '\0', sizeof(sa_serv));
	sa_serv.sin_family      = AF_INET;
	sa_serv.sin_addr.s_addr = INADDR_ANY;
	sa_serv.sin_port        = htons (TCP_LISTEN_PORT);          /* Server Port number */
  
	err = bind(listen_sd, (struct sockaddr*) &sa_serv,
	sizeof (sa_serv));
	if(err < 0){
		printf("err tcp bind!\n");
		return 0;
	}
	     
  /* Receive a TCP connection. */
	     
	err = listen (listen_sd, 5);
	do_debug("Server start Listen OK\n");                    


	if(err < 0){
		printf("err tcp listening!\n");
		return 0;
	}
  /////

////////////////////////////////////////////////////

  
  /* use select() to handle two descriptors at once */
  maxfd = (tap_fd > net_fd)?tap_fd:net_fd;
  maxfd = (maxfd > listen_sd)?maxfd:listen_sd;

  while(1) {
    int ret;
    fd_set rd_set;

	struct Session *cursess;
	cursess= slisthead;

    FD_ZERO(&rd_set);
    FD_SET(tap_fd, &rd_set); FD_SET(net_fd, &rd_set);
	FD_SET(0, &rd_set);
	FD_SET(listen_sd,&rd_set);

	while(cursess != 0){
		FD_SET(cursess->sd,&rd_set);
		maxfd = (maxfd > cursess->sd)?maxfd:cursess->sd;
		cursess = cursess->next;
	}

	cursess = slisthead;

    ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);

    if (ret < 0 && errno == EINTR){
      continue;
    }

    if (ret < 0) {
      perror("select()");
      exit(1);
    }




	if(FD_ISSET(0, &rd_set)){
		memset(buffer,0,BUFSIZE);
		nread = read(0, buffer, BUFSIZE);
		if(0 == strncmp(buffer,"quit",strlen("quit")))
			break;

	}

	if(FD_ISSET(listen_sd, &rd_set)){
		client_len = sizeof(sa_cli);
		sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
		if(err < 0){
			printf("err accept!\n");
			return 0;
		}
		err = sslinit(sd, &slisthead, &sa_cli, "vpnauth");
		if(err)
			do_debug("Client from %s is connected\n", inet_ntoa(sa_cli.sin_addr));
		//continue;

	}


	if(FD_ISSET(tap_fd, &rd_set)){
      /* data from tun/tap: just read it and write it to the network */
		unsigned char outbuffer[VPN_BUFSIZE];
		struct VPNDataHdr *pvpnh = (struct VPNDataHdr*) outbuffer;
		unsigned long curip;
		cursess = 0;
		nread = cread(tap_fd, buffer, BUFSIZE);
		if(nread <= 0)
			continue;
		
		tap2net++;
		do_debug("TAP2NET %lu: Read %d bytes from the tap interface\n", tap2net, nread);

		ip_header = (struct ip*) buffer;
		memcpy(&curip,&(ip_header->ip_dst),sizeof(long));
		cursess = findsessByDstIP(slisthead,curip);
		//memcpy(&tpaddr,&(destsess->ip),sizeof(unsigned long));
		if(cursess == 0)
			continue;
		remote.sin_addr.s_addr = cursess->ip;
		

      /* write length + packet */

		if(32 != getHMACSHA256(buffer, pvpnh->hmac, nread,cursess->s_key,KEY_LENGTH))
			continue;
		nwrite = crypt(buffer,nread,outbuffer + sizeof(struct VPNDataHdr),cursess->s_key,cursess->iv,1);
		if(0 == nwrite)
			continue;
		pvpnh->plen = htons(nwrite);
		sendto(net_fd,outbuffer, nwrite + sizeof(struct VPNDataHdr),0,(struct sockaddr*) &remote, sizeof(remote));
	
		do_debug("TAP2NET %lu: Written %d bytes to the network %s\n", tap2net,nwrite,inet_ntoa(remote.sin_addr));
		//continue;
    }

    if(FD_ISSET(net_fd, &rd_set)){
      /* data from the network: read it, and write it to the tun/tap interface. 
       * We need to read the length first, and then the packet */
		unsigned char inbuffer[VPN_BUFSIZE];
		unsigned char hmac[32];
		int nwrite;
		struct VPNDataHdr *pvpnh = (struct VPNDataHdr*) inbuffer;
		struct sockaddr_in sa;
		socklen_t fromlen;
		fromlen =sizeof(sa);

		nread = recvfrom(net_fd,inbuffer,VPN_BUFSIZE,0,(struct sockaddr*)&sa,&fromlen);

		if(nread <= 0) {
	        continue;
	      }

		cursess = findsessByVPNHeader(slisthead,pvpnh,sa.sin_addr.s_addr);
		if(cursess == 0)
			continue;
			
		nwrite = crypt(inbuffer + sizeof(struct VPNDataHdr),htons(pvpnh->plen),buffer,cursess->s_key,cursess->iv,0);
		if(0 == nwrite)
			continue;
	
		if(32 != getHMACSHA256(buffer, hmac, nwrite,cursess->s_key,KEY_LENGTH) 
		|| !isequal(hmac,pvpnh->hmac,HMAC_LENGTH))
			continue;
		net2tap++;
		/* read packet */
		do_debug("NET2TAP %lu: Read %d bytes from the network\n", net2tap, nread);
		
		/* now buffer[] contains a full packet or frame, write it into the tun/tap interface */ 
		nwrite = cwrite(tap_fd, buffer, nwrite);
		do_debug("NET2TAP %lu: Written %d bytes to the tap interface\n", net2tap, nwrite);
		//continue;
    }

	cursess = slisthead;
	while(cursess != 0){
		if(FD_ISSET(cursess->sd, &rd_set)){
			struct CliRequest* rst;
			memset(buffer,0,BUFSIZE);
			nread = ssl_read(cursess->ssl,buffer,BUFSIZE);
			rst = (struct CliRequest*)buffer;
			if(nread != sizeof(struct CliRequest)){
				break;
			}
			if(nread == 0 || rst->act == QUIT_REQUEST){
				struct in_addr temp;
				temp.s_addr = cursess->ip;
				do_debug("Client from %s break the connection\n", inet_ntoa(temp));
				cleanupSSL(cursess);
				deletesess(&slisthead,cursess);
				//slisthead = 0;
			}

			if(rst->act == IV_REFRESH_REQUEST){
				RefreshIV(cursess);
				do_debug("IV is refreshed:");
				debugSession(cursess);
			}
			if(rst->act == IV_REFRESH_SET){
				struct ServResponse rsp;
				rsp.act = ACT_ACK;
				if(-1 != ssl_write(cursess->ssl,(char*)&rsp, sizeof(struct ServResponse))){
					memcpy(cursess->iv, rst->iv,KEY_LENGTH);
					do_debug("IV is updated:");
					debugSession(cursess);
				}
			}
			if(rst->act == KEY_REFRESH_REQUEST){
				RefreshKEY(cursess);
				do_debug("Key is refreshed:");
				debugSession(cursess);
			}
			if(rst->act == KEY_REFRESH_SET){
				struct ServResponse rsp;
				rsp.act = ACT_ACK;
				if(-1 != ssl_write(cursess->ssl,(char*)&rsp, sizeof(struct ServResponse))){
					memcpy(cursess->s_key, rst->s_key,KEY_LENGTH);
					do_debug("Key is updated:");
					debugSession(cursess);
				}
			}
			
		}
		cursess = cursess->next;
	}


	
  }

	if(slisthead != 0){
		struct Session* tsess = slisthead;
		while(tsess != 0){
			cleanupSSL(tsess);
			tsess = tsess->next;
		}
	}
	freesess(slisthead);
	close(listen_sd);
	close(net_fd);
	close(tap_fd);
	cleanupCTX();
  	
  return(0);
}
Example #23
0
int main(int argc, char *argv[]) {
  
  int tap_fd, option;
  int flags = IFF_TUN;
  char if_name[IFNAMSIZ] = "";
  int header_len = IP_HDR_LEN;
  int maxfd;
  uint16_t nread, nwrite, plength;
//  uint16_t total_len, ethertype;
  char buffer[BUFSIZE];
  struct sockaddr_in local, remote;
  char remote_ip[16] = "";
  unsigned short int port = PORT;
  int sock_fd, net_fd, optval = 1;
  socklen_t remotelen;
  int cliserv = -1;    /* must be specified on cmd line */
  unsigned long int tap2net = 0, net2tap = 0;

  progname = argv[0];
  
  /* Check command line options */
  while((option = getopt(argc, argv, "i:sc:p:uahd")) > 0){
    switch(option) {
      case 'd':
        debug = 1;
        break;
      case 'h':
        usage();
        break;
      case 'i':
        strncpy(if_name,optarg,IFNAMSIZ-1);
        break;
      case 's':
        cliserv = SERVER;
        break;
      case 'c':
        cliserv = CLIENT;
        strncpy(remote_ip,optarg,15);
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'u':
        flags = IFF_TUN;
        break;
      case 'a':
        flags = IFF_TAP;
        header_len = ETH_HDR_LEN;
        break;
      default:
        my_err("Unknown option %c\n", option);
        usage();
    }
  }

  argv += optind;
  argc -= optind;


  if (argc == 2) {
	  strncpy(if_name,argv[0],IFNAMSIZ-1);
	  port = atoi(argv[1]);
      cliserv = SERVER;
      flags = IFF_TAP;
      header_len = ETH_HDR_LEN;
  } else
  if(argc > 0){
    my_err("Too many options!\n");
    usage();
  }

  if(*if_name == '\0'){
    my_err("Must specify interface name!\n");
    usage();
  }else if(cliserv < 0){
    my_err("Must specify client or server mode!\n");
    usage();
  }else if((cliserv == CLIENT)&&(*remote_ip == '\0')){
    my_err("Must specify server address!\n");
    usage();
  }

  /* initialize tun/tap interface */
  if ( (tap_fd = tun_alloc(if_name, flags | IFF_NO_PI)) < 0 ) {
    my_err("Error connecting to tun/tap interface %s!\n", if_name);
    exit(1);
  }

  do_debug("Successfully connected to interface %s\n", if_name);

  if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    perror("socket()");
    exit(1);
  }

  if(cliserv==CLIENT){
    /* Client, try to connect to server */

    /* assign the destination address */
    memset(&remote, 0, sizeof(remote));
    remote.sin_family = AF_INET;
    remote.sin_addr.s_addr = inet_addr(remote_ip);
    remote.sin_port = htons(port);

    /* connection request */
    if (connect(sock_fd, (struct sockaddr*) &remote, sizeof(remote)) < 0){
      perror("connect()");
      exit(1);
    }

    net_fd = sock_fd;
    do_debug("CLIENT: Connected to server %s\n", inet_ntoa(remote.sin_addr));
    
  } else {
    /* Server, wait for connections */

    /* avoid EADDRINUSE error on bind() */
    if(setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) < 0){
      perror("setsockopt()");
      exit(1);
    }
    
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_addr.s_addr = htonl(INADDR_ANY);
    local.sin_port = htons(port);
    if (bind(sock_fd, (struct sockaddr*) &local, sizeof(local)) < 0){
      perror("bind()");
      exit(1);
    }
    
    if (listen(sock_fd, 5) < 0){
      perror("listen()");
      exit(1);
    }
    
    /* wait for connection request */
    remotelen = sizeof(remote);
    memset(&remote, 0, remotelen);
    if ((net_fd = accept(sock_fd, (struct sockaddr*)&remote, &remotelen)) < 0){
      perror("accept()");
      exit(1);
    }

    do_debug("SERVER: Client connected from %s\n", inet_ntoa(remote.sin_addr));
  }
  
  /* use select() to handle two descriptors at once */
  maxfd = (tap_fd > net_fd)?tap_fd:net_fd;

  while(1) {
    int ret;
    fd_set rd_set;

    FD_ZERO(&rd_set);
    FD_SET(tap_fd, &rd_set); FD_SET(net_fd, &rd_set);

    ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);

    if (ret < 0 && errno == EINTR){
      continue;
    }

    if (ret < 0) {
      perror("select()");
      exit(1);
    }

    if(FD_ISSET(tap_fd, &rd_set)){
      /* data from tun/tap: just read it and write it to the network */
      
      nread = cread(tap_fd, buffer, BUFSIZE);

      tap2net++;
      do_debug("TAP2NET %lu: Read %d bytes from the tap interface\n", tap2net, nread);

      /* write length + packet */
      plength = htons(nread);
      nwrite = cwrite(net_fd, (char *)&plength, sizeof(plength));
      nwrite = cwrite(net_fd, buffer, nread);
      
      do_debug("TAP2NET %lu: Written %d bytes to the network\n", tap2net, nwrite);
    }

    if(FD_ISSET(net_fd, &rd_set)){
      /* data from the network: read it, and write it to the tun/tap interface. 
       * We need to read the length first, and then the packet */

      /* Read length */      
      nread = read_n(net_fd, (char *)&plength, sizeof(plength));
      if(nread == 0) {
        /* ctrl-c at the other end */
        break;
      }

      net2tap++;

      /* read packet */
      nread = read_n(net_fd, buffer, ntohs(plength));
      do_debug("NET2TAP %lu: Read %d bytes from the network\n", net2tap, nread);

      /* now buffer[] contains a full packet or frame, write it into the tun/tap interface */ 
      nwrite = cwrite(tap_fd, buffer, nread);
      do_debug("NET2TAP %lu: Written %d bytes to the tap interface\n", net2tap, nwrite);
    }
  }
  
  return(0);
}
Example #24
0
File: asm.c Project: rosrad/go-rep
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();
}
Example #25
0
File: asm.c Project: timnau/golang
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();
}
Example #26
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;
}
Example #27
0
File: thread.c Project: zhyg/mapred
void event_handler(int fd, short e, void* args)
{
    char*   line =  NULL;
    int     len  =  0; 
    int     size =  0;

    int st              = wet->st;
    IOstream* stream    = &(wet->stream);
    WEVENT_T* ev        = (WEVENT_T*)args;

    if (!isempty_buffer(&ev->buffer)) {
        size = cwrite(fd, ev->buffer.cur, ev->buffer.size);
        if (size < 0) {
            log("write error, %s\n", strerror(errno));
            update_stat(STAT_CLOSE_PIPE);
        } else {
            seek_buffer(&ev->buffer, size);
            return;
        }
    }

    switch (st) {
    case STAT_READ_MORE:
        if (try_read_more(stream) == E_ERROR) {
            update_stat(STAT_LAST_BUF);
        } else {
            update_stat(STAT_WRITE_LINE);
        }
        break;

    case STAT_WRITE_LINE:
        if (get_line(stream, &line, &len) == E_NEED_MORE || len == 0) {
            update_stat(STAT_READ_MORE);
            break;
        }
    
        size = cwrite(fd, line, len);
        if (size < 0) {
            log("write error, %s\n", strerror(errno));
            update_stat(STAT_CLOSE_PIPE);
            break;
        }

        if (size < len) {
            expand_buffer(&ev->buffer, line + size, len - size);
            break;
        }
        break;

    case STAT_LAST_BUF:
        if (stream->bytes <= 0) {
            update_stat(STAT_CLOSE_PIPE);
            break;
        }
        size = cwrite(fd, stream->cur, stream->bytes);
        if (size < 0) {
            log("write error, %s\n", strerror(errno));
            update_stat(STAT_CLOSE_PIPE);
            break;
        }

        if (size == stream->bytes) {
            stream->bytes = 0;
            update_stat(STAT_CLOSE_PIPE);
            break;
        }

        if (size < stream->bytes) {
            expand_buffer(&ev->buffer, stream->cur+size, stream->bytes-size);
            stream->bytes = 0;
            break;
        }
        break;

    case STAT_CLOSE_PIPE:
        close(fd);
        event_del(&ev->e);
        break;
    } 
}
Example #28
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();
}
Example #29
0
void
reader(void *v)
{
	int cfd, tfd, exiting, pid;
	uintptr_t newpid;
	char *ctl, *truss;
	Str *s;
	static char waitstop[] = "waitstop";

	pid = (int)(uintptr)v;
	if (debug)
		fprint(outf, "DEBUG: -------------> reader starts with pid %d\n", pid);
	ctl = smprint("/proc/%d/ctl", pid);
	if ((cfd = open(ctl, OWRITE)) < 0)
		die(smprint("%s: %r", ctl));
	truss = smprint("/proc/%d/syscall", pid);
	if ((tfd = open(truss, OREAD)) < 0)
		die(smprint("%s: %r", truss));
	if (debug)
		fprint(outf, "DEBUG: Send %s to pid %d ...", waitstop, pid);
	/* child was stopped by hang msg earlier */
	cwrite(cfd, ctl, waitstop, sizeof waitstop - 1);
	if (debug)
		fprint(outf, "DEBUG: back for %d\n", pid);

	if (debug)
		fprint(outf, "DEBUG: Send %s to pid %d\n", "startsyscall", pid);
	cwrite(cfd, ctl, "startsyscall", 12);
	if (debug)
		fprint(outf, "DEBUG: back for %d\n", pid);
	s = newstr();
	exiting = 0;
	while((s->len = pread(tfd, s->buf, Bufsize - 1, 0)) >= 0){
		if (s->buf[0] == 'F') {
			char *val = strstr(s->buf, "= ");
			if (val) {
				newpid = strtol(&val[2], 0, 0);
				sendp(forkc, (void*)newpid);
				procrfork(reader, (void*)newpid, Stacksize, 0);
			}
		}

		if (strstr(s->buf, " Exits") != nil)
			exiting = 1;

		sendp(out, s);	/* print line from /proc/$child/syscall */
		if (exiting) {
			s = newstr();
			strcpy(s->buf, "\n");
			sendp(out, s);
			break;
		}

		/* flush syscall trace buffer */
		if (debug)
			fprint(outf, "DEBUG: Send %s to pid %d\n", "startsyscall", pid);
		cwrite(cfd, ctl, "startsyscall", 12);
		if (debug)
			fprint(outf, "DEBUG: back for %d\n", pid);
		s = newstr();
	}

	sendp(quit, nil);
	threadexitsall(nil);
}
Example #30
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();
}