static int bootread (int fd, void *addr, int size) { int i; if (bootseg++ > 0) fprintf (stderr, "\b + "); fprintf (stderr, "0x%x/%d ", addr + dl_offset, size); if (!dl_checksetloadaddr (addr + dl_offset, size, 1)) return (-1); #if NGZIP > 0 if(myflags&ZFLAG){ if(myflags&OFLAG){ if(lastaddr)dl_loffset +=(unsigned long long)(addr-lastaddr); lastaddr=addr; i=0; while(i<size) { int i1; int len=min(0x1000,size-i); i1=gz_read (fd,dl_Oloadbuffer,len); if(i1<0)break; highmemcpy(dl_loffset+i,dl_Oloadbuffer,i1); i+=i1; if(i1<len)break; } } else i = gz_read (fd, addr + dl_offset, size); }else #endif /* NGZIP */ { if(myflags&OFLAG){ if(lastaddr)dl_loffset +=(unsigned long long)(addr-lastaddr); lastaddr=addr; i=0; while(i<size) { int i1; int len=min(0x1000,size-i); i1=read (fd,dl_Oloadbuffer,len); if(i1<0)break; highmemcpy(dl_loffset+i,dl_Oloadbuffer,i1); i+=i1; if(i1<len)break; } } else i = read (fd, addr + dl_offset, size); } if (i < size) { if (i >= 0) fprintf (stderr, "\nread failed (corrupt object file?)"); else perror ("\nsegment read"); return (-1); } return size; }
static Elf32_Shdr * elfgetshdr (int fd, Elf32_Ehdr *ep) { Elf32_Shdr *shtab; unsigned size = ep->e_shnum * sizeof(Elf32_Shdr); shtab = (Elf32_Shdr *) malloc (size); if (!shtab) { fprintf (stderr,"\nnot enough memory to read section headers"); return (0); } #if NGZIP > 0 if(myflags&ZFLAG){ if (gz_lseek (fd, ep->e_shoff, SEEK_SET) != ep->e_shoff || gz_read (fd, shtab, size) != size) { perror ("\nsection headers"); free (shtab); return (0); } }else #endif /* NGZIP */ if (lseek (fd, ep->e_shoff, SEEK_SET) != ep->e_shoff || read (fd, shtab, size) != size) { perror ("\nsection headers"); free (shtab); return (0); } return (shtab); }
static void * readtable (int fd, int offs, void *base, int size, char *name, int flags) { #if NGZIP > 0 if(myflags&ZFLAG){ if (gz_lseek (fd, offs, SEEK_SET) != offs || gz_read (fd, base, size) != size) { fprintf (stderr, "\ncannot read %s table", name); return 0; } }else #endif /* NGZIP */ if (lseek (fd, offs, SEEK_SET) != offs || read (fd, base, size) != size) { fprintf (stderr, "\ncannot read %s table", name); return 0; } return (void *) base; }
static int devcp(int argc, char **argv) { char *buf; int fp0, fp1; int n, i; int bs = 0x20000; int seek = 0, skip = 0; char *fsrc = 0, *fdst = 0; unsigned int count = -1, nowcount = 0; char pstr[80] = ""; int quiet = 0; yaf_use = 0; //lxy yaf_w = 1; #if NGZIP > 0 int unzip=0; #endif if (argc < 3) return -1; fsrc = argv[1]; fdst = argv[2]; if (!fsrc||!fdst) return -1; fp0 = open(fsrc, O_RDONLY); fp1 = open(fdst, O_RDWR|O_CREAT|O_TRUNC); if (!strncmp(_file[fp1].fs->devname, "mtd", 3)) { mtdpriv *priv; mtdfile *p; priv = (mtdpriv *)_file[fp1].data; p = priv->file; if (p->mtd->type == MTD_NANDFLASH) { bs = p->mtd->erasesize; } } for (i=3; i<argc; i++) { if(!strncmp(argv[i],"bs=",3)) bs=strtoul(&argv[i][3],0,0); else if(!strncmp(argv[i],"count=",6)) count=strtoul(&argv[i][6],0,0); else if(!strncmp(argv[i],"skip=",5)) skip=strtoul(&argv[i][5],0,0); else if(!strncmp(argv[i],"seek=",5)) seek=strtoul(&argv[i][5],0,0); else if(!strncmp(argv[i],"quiet=",6)) quiet=strtoul(&argv[i][6],0,0); #if NGZIP > 0 else if(!strcmp(argv[i],"unzip=1")) unzip=1; #endif else if (!strcmp(argv[i], "yaf")) //lxy { yaf_use = 1; bs += (4 * 1024); } else if (!strcmp(argv[i], "nw")) //lxy yaf_w = 0; } buf = malloc(bs); // buf = (char *)(((long)malloc(bs + 32) + 32) & ~(32-1) | 0xa0000000); // buf = 0xa1000000; if (!buf) { printf("malloc failed!,please set heaptop bigger\n"); return -1; } if (!fp0||!fp1) { printf("open file error!\n"); free(buf); return -1; } lseek(fp0, skip*bs, SEEK_SET); lseek(fp1, seek*bs, SEEK_SET); #if NGZIP > 0 if (unzip) if (gz_open(fp0) == -1) unzip = 0; #endif while(count--) { int rcount=0; char *pnow=buf; #if NGZIP > 0 if (unzip) while (rcount<bs) { n = gz_read(fp0, pnow, bs); if (n <= 0) break; rcount += n; pnow += n; } else #endif while (rcount<bs) { n = read(fp0, pnow, bs-rcount); if (n <= 0) break; rcount += n; pnow += n; } nowcount += rcount; if (!(strstr(argv[1],"/dev/tty") || strstr(argv[2],"/dev/tty") || quiet)) { int i; for (i=0; i<strlen(pstr); i++) printf("\b \b"); sprintf(pstr, "%d", nowcount); printf("%s", pstr); } if (write(fp1, buf, rcount) < rcount || rcount <bs) break; } free(buf); #if NGZIP > 0 if (unzip) gz_close(fp0); #endif close(fp0); close(fp1); if (nowcount == 0) //lxy return -1; return 0; }
long load_elf (int fd, char *buf, int *n, int flags) { Elf32_Ehdr *ep; Elf32_Phdr *phtab = 0; Elf32_Shdr *shtab = 0; unsigned int nbytes; int i; Elf32_Off highest_load = 0; bootseg = 0; myflags=flags; #ifdef __mips__ tablebase = PHYS_TO_CACHED(memorysize); #else tablebase = memorysize; #endif #if NGZIP > 0 lseek(fd,*n,0); read(fd,buf,2); if(((unsigned char)buf[0]==0x1f) && ((unsigned char)buf[1]==0x8b))flags |=ZFLAG; else flags &=~ZFLAG; myflags=flags; lseek(fd,*n,0); if(myflags&ZFLAG){ gz_open(fd); *n = 0; gz_lseek (fd, 0, SEEK_SET); } #endif /* NGZIP */ ep = (Elf32_Ehdr *)buf; if (sizeof(*ep) > *n) { #if NGZIP > 0 if(myflags&ZFLAG) *n += gz_read (fd, buf+*n, sizeof(*ep)-*n); else #endif /* NGZIP */ { lseek(fd,*n,0); *n += read (fd, buf+*n, sizeof(*ep)-*n); } if (*n < sizeof(*ep)) { #if NGZIP > 0 if(myflags&ZFLAG) gz_close(fd); #endif /* NGZIP */ return -1; } } /* check header validity */ if (ep->e_ident[EI_MAG0] != ELFMAG0 || ep->e_ident[EI_MAG1] != ELFMAG1 || ep->e_ident[EI_MAG2] != ELFMAG2 || ep->e_ident[EI_MAG3] != ELFMAG3) { #if NGZIP > 0 if(myflags&ZFLAG) gz_close(fd); #endif /* NGZIP */ return (-1); } fprintf (stderr, "(elf)\n"); { char *nogood = (char *)0; if (ep->e_ident[EI_CLASS] == ELFCLASS64) return load_elf64(fd, buf, n, flags); if (ep->e_ident[EI_CLASS] != ELFCLASS32) nogood = "not 32-bit"; else if ( #if BYTE_ORDER == BIG_ENDIAN ep->e_ident[EI_DATA] != ELFDATA2MSB #endif #if BYTE_ORDER == LITTLE_ENDIAN ep->e_ident[EI_DATA] != ELFDATA2LSB #endif ) nogood = "incorrect endianess"; else if (ep->e_ident[EI_VERSION] != EV_CURRENT) nogood = "version not current"; else if ( #ifdef powerpc ep->e_machine != EM_PPC #else /* default is MIPS */ #define GREENHILLS_HACK #ifdef GREENHILLS_HACK ep->e_machine != 10 && #endif ep->e_machine != EM_MIPS #endif ) nogood = "incorrect machine type"; if (nogood) { fprintf (stderr, "Invalid ELF: %s\n", nogood); #if NGZIP > 0 if(myflags&ZFLAG) gz_close(fd); #endif /* NGZIP */ return -2; } } /* Is there a program header? */ if (ep->e_phoff == 0 || ep->e_phnum == 0 || ep->e_phentsize != sizeof(Elf32_Phdr)) { fprintf (stderr, "missing program header (not executable)\n"); #if NGZIP > 0 if(myflags&ZFLAG) gz_close(fd); #endif /* NGZIP */ return (-2); } /* Load program header */ #if _ORIG_CODE_ nbytes = ep->e_phnum * sizeof(Elf32_Phdr); #else /* XXX: We need to figure out why it works by adding 32!!!! */ nbytes = ep->e_phnum * sizeof(Elf32_Phdr)+32; #endif phtab = (Elf32_Phdr *) malloc (nbytes); if (!phtab) { fprintf (stderr,"\nnot enough memory to read program headers"); #if NGZIP > 0 if(myflags&ZFLAG) gz_close(fd); #endif /* NGZIP */ return (-2); } #if NGZIP > 0 if(myflags&ZFLAG){ if (gz_lseek (fd, ep->e_phoff, SEEK_SET) != ep->e_phoff || gz_read (fd, (void *)phtab, nbytes) != nbytes) { perror ("program header"); free (phtab); gz_close(fd); return (-2); } }else #endif /* NGZIP */ if (lseek (fd, ep->e_phoff, SEEK_SET) != ep->e_phoff || read (fd, (void *)phtab, nbytes) != nbytes) { perror ("program header"); free (phtab); return (-2); } /* * From now on we've got no guarantee about the file order, * even where the section header is. Hopefully most linkers * will put the section header after the program header, when * they know that the executable is not demand paged. We assume * that the symbol and string tables always follow the program * segments. */ /* read section table (if before first program segment) */ if (!(flags & NFLAG) && ep->e_shoff < phtab[0].p_offset) shtab = elfgetshdr (fd, ep); /* load program segments */ if (!(flags & YFLAG)) { /* We cope with a badly sorted program header, as produced by * older versions of the GNU linker, by loading the segments * in file offset order, not in program header order. */ while (1) { Elf32_Off lowest_offset = ~0; Elf32_Phdr *ph = 0; /* find nearest loadable segment */ for (i = 0; i < ep->e_phnum; i++) if (phtab[i].p_type == PT_LOAD && phtab[i].p_offset < lowest_offset) { ph = &phtab[i]; lowest_offset = ph->p_offset; } if (!ph) break; /* none found, finished */ /* load the segment */ if (ph->p_filesz) { #if NGZIP > 0 if(myflags&ZFLAG){ if (gz_lseek (fd, ph->p_offset, SEEK_SET) != ph->p_offset) { fprintf (stderr, "seek failed (corrupt object file?)\n"); if (shtab) free (shtab); free (phtab); gz_close(fd); return (-2); } }else #endif /* NGZIP */ if (lseek (fd, ph->p_offset, SEEK_SET) != ph->p_offset) { fprintf (stderr, "seek failed (corrupt object file?)\n"); if (shtab) free (shtab); free (phtab); return (-2); } if (bootread (fd, (void *)ph->p_vaddr, ph->p_filesz) != ph->p_filesz) { if (shtab) free (shtab); free (phtab); #if NGZIP > 0 if(myflags&ZFLAG) gz_close(fd); #endif /* NGZIP */ return (-2); } } if((ph->p_vaddr + ph->p_memsz) > highest_load) { highest_load = ph->p_vaddr + ph->p_memsz; } if (ph->p_filesz < ph->p_memsz) bootclear (fd, (void *)ph->p_vaddr + ph->p_filesz, ph->p_memsz - ph->p_filesz); ph->p_type = PT_NULL; /* remove from consideration */ } } if (flags & KFLAG) { highest_load = roundup(highest_load, sizeof(long)); tablebase = highest_load; } if (!(flags & NFLAG)) { /* read section table (if after last program segment) */ if (!shtab) shtab = elfgetshdr (fd, ep); if (shtab) { elfreadsyms (fd, ep, shtab, flags); free (shtab); } } free (phtab); #if NGZIP > 0 if(myflags&ZFLAG) gz_close(fd); #endif /* NGZIP */ return (ep->e_entry + dl_offset); }