/* 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; }
/* 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; }