Exemplo n.º 1
0
Arquivo: mkboot.c Projeto: jimix/k42
/* we have put in extra space in the last section in the text segment
 * we not need to go through the rest of the section headers and indicate
 * this by pushing back where they start
 * we also need to increase the size of the last section in the text segment
 */
adj_shdr(Elf32_Ehdr *eh32)
{
    Elf32_Shdr *shdr;
    Elf32_Shdr *last_shdr_before_data;
    int i;

    shdr = (Elf32_Shdr *)((eh32->e_shoff+kern_file));
    last_shdr_before_data = NULL;

    if (debug_level == 2) {
        printf("Dumping shdr information\n");
    }
    for (i=0; i<eh32->e_shnum; i++,shdr++) {
        if (debug_level == 2) {
	    dump_shdr(shdr);
	}
        if (shdr->sh_offset >= old_data_file_offset) {
	    shdr->sh_offset += amount_push_back;
	}
	else if (shdr->sh_offset > text_file_offset) {
	    if (last_shdr_before_data == NULL) {
	        last_shdr_before_data = shdr;
	    }
	    else if (shdr->sh_addr > last_shdr_before_data->sh_addr) {
	        last_shdr_before_data = shdr;
	    }
	}
    }
    if (debug_level == 2) {
        printf("\n\n");
    }
    last_shdr_before_data->sh_size = data_file_offset - last_shdr_before_data->sh_offset;

}
Exemplo n.º 2
0
/* Main program. */
int main(int argc, char **argv)
{
	struct nucs_exec ahdr;   // minix aout header
	struct nucs_exec_elf32 input_exec_elf32;
	struct stat st_input;
	elf32_ehdr_t ehdr;
	elf32_phdr_t* phdrs = 0;
	elf32_shdr_t* shdrs = 0;
	int fd_in;
	int fd_out;
	int fd_aout;
	char* input = 0;
	char* output = 0;
	char* faout = 0;
	char strnum[MAX_DIGITS]; 
	char* strflags[MAX_TOKENS]; 
	unsigned int flags = A_EXEC;
	unsigned char cpu = A_I80386;
	int stackheap = -1;
	int hdrlen = HDRLEN;
	int opt;
	int i=0;
	int n=0;

	memset(strflags, 0, sizeof(strflags));
	memset(strnum, 0, sizeof(strnum));

	while ((opt = getopt(argc, argv,"c:d:f:hi:l:o:s:")) != -1) {
		switch (opt) {
		case 'c': /* cpu type */
			if(!strncmp(optarg,"i386",4))
				cpu = A_I80386;

			if(!strncmp(optarg,"i8086",5))
				cpu = A_I8086;
			break;

		case 'd': /* dump aout header */
			faout = optarg;
			break;

		case 'f': /* flags */
			memset(strflags,0,MAX_TOKENS);
			flags = 0x00;

			/* get the first token */
			strflags[0] = strtok(optarg," ,");

			/* parse the rest of string */
			while ((++i <= MAX_TOKENS) && ((strflags[i] = strtok (0," ,")) != 0));

			n=i;
			unsigned int flag = 0x00;

			for(i=0; i<n; i++) {
				if(strlen(strflags[i]) > 2 && strflags[i][0] == '0' &&
					strflags[i][1] == 'x')
					sscanf(strflags[i],"%x",&flag);
				else
					flag = atoi(strflags[i]);

				flags |= flag;
			}
			break;

		case 'h':
			usage();
			exit(0);

		case 'i': /* input */
			input = optarg;
			break;

		case 'l': /* header length (default 0x20) */
			memset(strnum,0,MAX_DIGITS);
			if(strlen(optarg) > 2 && optarg[0] == '0' && optarg[1] == 'x')
				sscanf(optarg,"%x",&hdrlen);
			else
				hdrlen = atoi(optarg);

			break;

		case 'o': /* output */
			output = optarg;
			break;

		case 's': /* stack + heap size */
		{
			char * mulstr;
			stackheap = strtoul(optarg, &mulstr, 0);

			if (mulstr[0] != 0) {
				switch (mulstr[0]) {
				case 'k':
					stackheap <<= 10;
					break;
				case 'M':
					stackheap <<= 20;
					break;
				default:
					goto wrong_size;
				}

				if (mulstr[1] != 0) {
					switch(mulstr[1]) {
					case 'w':
						stackheap *= 4; /* assuming 32bits */
						break;
					case 'b':
						break;
					default:
						goto wrong_size;
					}
				}
			}
			break;
wrong_size:
			fprintf(stderr, "Unrecognized size modifier\n");
			usage();
			exit(1);
		}
		break;

		default: /* '?' */
			usage();
			exit(1);
		}
	}

	if(faout) {
		if((fd_aout = open(faout, O_RDONLY))<0) {
			perror("open");
			exit(1);
		}

		if ((n = read(fd_aout, &ahdr, sizeof(ahdr))) < 0) {
			perror("read");
		}

		close(fd_aout);

		if (n != sizeof(ahdr)) {
			fprintf(stderr,"Wrong header size (want %d got %d\n",sizeof(ahdr),n);
		}

		dump_aout(&ahdr);

		return 0;
	}

	if(!input || !output || stackheap<0) {
		usage();
		exit(1);
	}

	if (stat(input, &st_input) != 0) {
		perror("stat");
		exit(1);
	}

	if((fd_in = open(input, O_RDONLY))<0) {
		report(input,"Couldn't open input file");
		exit(1);
	}

	if((fd_out = open(output, O_CREAT|O_RDWR|O_TRUNC, S_IFREG|S_IRUSR|S_IWUSR|S_IWUSR))<0) {
		report(output,"Couldn't open output file");
		exit(1);
	}

	read_elf32_ehdr(input, &ehdr);

#if DO_TRACE == 1
	printf("---[ELF header]---\n");
	dump_ehdr(&ehdr);
#endif

	phdrs = read_elf32_phdrs(input, &ehdr, phdrs);

#if DO_TRACE == 1
	for(i=0; i<ehdr.e_phnum; i++) {
		printf("---[%d. program header]---\n",i);
		dump_phdr(&phdrs[i]);
	}
#endif

	shdrs = read_elf32_shdrs(input, &ehdr, shdrs);

#if DO_TRACE == 1
	for(i=0; i<ehdr.e_shnum; i++) {
		printf("---[%d. section header]---\n",i);
		dump_shdr(&shdrs[i]);
	}
#endif

	create_exec_elf32(&ehdr, phdrs, shdrs, &input_exec_elf32);

#if DO_TRACE == 1
	dump_exec_elf32(&input_exec_elf32);
#endif

	/* Build a.out header and write to output */
	memset(&ahdr, 0, sizeof(ahdr));
	ahdr.a_magic[0] = A_MAGIC0;
	ahdr.a_magic[1] = A_MAGIC1;
	ahdr.a_flags    = flags;
	ahdr.a_cpu      = cpu;
	ahdr.a_hdrlen   = hdrlen;
	ahdr.a_text     = input_exec_elf32.text_size;
	ahdr.a_data     = input_exec_elf32.data_size;
	ahdr.a_bss      = input_exec_elf32.bss_size;

	ahdr.a_total = ahdr.a_text + ahdr.a_data + ahdr.a_bss + stackheap;
	ahdr.a_entry = input_exec_elf32.initial_ip;

	if (flags & A_NSYM) {
		ahdr.a_syms = input_exec_elf32.symtab_size;
	} else {
		ahdr.a_syms = 0;
	}

	write(fd_out, &ahdr, hdrlen);
	close(fd_in);
	close(fd_out);

	return 0;
}