00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <sys/types.h>
00011 #include <libelf.h>
00012 #include <fcntl.h>
00013
00014 #define min(x,y) ((x)<(y)?(x):(y))
00015
00016 extern int errno;
00017
00018
00019 void copy_bytes(infd, outfd, offset, nbytes)
00020 int infd, outfd, offset, nbytes;
00021 { char buf[8192];
00022 int i, s;
00023 lseek(infd, offset, SEEK_SET);
00024 while (nbytes>0) {
00025 s=min(8192, nbytes);
00026 s=read(infd, buf, s);
00027 if (s<=0) {
00028 fprintf(stderr, "cannot read object %d", errno);
00029 return;}
00030 write(outfd, buf, s);
00031 nbytes -= s;}
00032 }
00033
00034 void copy_new_symtab(infd,outfd,symtab)
00035 int infd, outfd;
00036 Elf32_Shdr *symtab;
00037 { register int i;
00038 int s, ss, k;
00039 Elf32_Sym symbuf[16384];
00040 unsigned char info;
00041
00042 s=symtab->sh_size;
00043 if (s>sizeof(symbuf)) { fprintf(stderr, "symtab too big %d\n",s); exit(5);}
00044 lseek(infd, symtab->sh_offset, SEEK_SET);
00045 ss=read(infd, symbuf, s);
00046 if (ss!=s) { fprintf(stderr, "cannt read symtab %d\n", ss); exit(6);}
00047 k=ss/sizeof(Elf32_Sym);
00048 for (i=symtab->sh_info; i<k; i++) {
00049 info=symbuf[i].st_info;
00050 if (ELF32_ST_TYPE(info)==STT_OBJECT) {
00051 fprintf(stderr, "symbol[%d] is OBJECT\n", i);
00052 symbuf[i].st_info += 1;}}
00053 write(outfd, symbuf, ss);}
00054
00055 main(argc,argv)
00056 int argc;
00057 char *argv[];
00058 {
00059 char *fname;
00060 int elfd, outfd;
00061 char outfname[128];
00062 Elf *elf;
00063 Elf32_Ehdr *ehdr, newehdr;
00064 Elf_Scn *scn;
00065 Elf32_Shdr *scnhdr, scntab[40], *symtab;
00066 Elf_Data *data;
00067 int scn_symt[40];
00068 int i, j, scn_num, scn_count, scn_total_size, scn_offset;
00069 char *cp;
00070
00071 fname=argv[1];
00072 sprintf(outfname,"%s.r",fname);
00073 elfd=open(fname, 0);
00074 outfd=open(outfname, O_RDWR | O_CREAT, 0777);
00075 if (elfd<=0) {
00076 fprintf(stderr, "%s cannot open %d\n", fname, errno);
00077 exit(2);}
00078 if (outfd<=0) {
00079 fprintf(stderr, "%s cannot open %d\n", outfname, errno);
00080 exit(2);}
00081 fprintf(stderr, "%s opened\n", outfname);
00082
00083 elf_version(EV_CURRENT);
00084 elf=elf_begin(elfd, ELF_C_READ, 0);
00085 if (elf==0) printf("%s\n", elf_errmsg(elf_errno()));
00086 ehdr=elf32_getehdr(elf);
00087 memcpy(&newehdr, ehdr, sizeof(newehdr));
00088
00089
00090
00091
00092 printf("\ne_type= %d\n", newehdr.e_type);
00093 printf("e_machine= %d\n", newehdr.e_machine);
00094 printf("e_version= %d\n", newehdr.e_version);
00095 printf("e_entry= 0x%x\n", newehdr.e_entry);
00096 printf("e_phoff= 0x%x\n", newehdr.e_phoff);
00097 printf("e_shoff= 0x%x\n", newehdr.e_shoff);
00098 printf("e_flags= 0x%x\n", newehdr.e_flags);
00099 printf("e_ehsize= 0x%x\n", newehdr.e_ehsize);
00100 printf("e_phentsize= %d\n", newehdr.e_phentsize);
00101 printf("e_phnum= %d\n", newehdr.e_phnum);
00102 printf("e_shentsize= %d\n", newehdr.e_shentsize);
00103 printf("e_shnum= %d\n", newehdr.e_shnum);
00104 printf("e_shstrndx= %d\n", newehdr.e_shstrndx);
00105
00106
00107 scn_num=newehdr.e_shnum;
00108 scn_count=0;
00109 scn_total_size=0;
00110 for (i=0; i<scn_num; i++) {
00111 scn=elf_getscn(elf, i);
00112 scnhdr=elf32_getshdr(scn);
00113 memcpy(&scntab[i], scnhdr, sizeof(Elf32_Shdr));
00114
00115 if (scntab[i].sh_flags==0) {
00116 scn_symt[i]=scn_count++;
00117 if (scntab[i].sh_type == SHT_SYMTAB) symtab=&scntab[i];
00118 scn_total_size +=scntab[i].sh_size; } }
00119
00120 printf("ehdrsize=%d; %d sections are needed.\n",
00121 sizeof(Elf32_Ehdr), scn_count);
00122
00123
00124 newehdr.e_type=ET_REL;
00125 newehdr.e_entry=0;
00126 newehdr.e_phoff=0;
00127 newehdr.e_shoff= sizeof(Elf32_Ehdr) + scn_total_size;
00128 newehdr.e_phentsize=0;
00129 newehdr.e_phnum=0;
00130 newehdr.e_shstrndx=scn_symt[newehdr.e_shstrndx];
00131 newehdr.e_shnum=scn_count;
00132
00133 fprintf(stderr, "ehdr updated\n");
00134
00135
00136 write(outfd, &newehdr, sizeof(Elf32_Ehdr));
00137
00138
00139
00140 for (i=1; i<scn_num; i++) {
00141 if (scn_symt[i]!=0 && scntab[i].sh_type != SHT_NOBITS) {
00142 fprintf(stderr, "%d size=%d\n", i, scntab[i].sh_size);
00143 if (scntab[i].sh_type==SHT_SYMTAB) {
00144 copy_new_symtab(elfd, outfd, symtab);}
00145 else
00146 copy_bytes(elfd, outfd, scntab[i].sh_offset, scntab[i].sh_size);
00147 }}
00148
00149
00150
00151 scn_offset=sizeof(Elf32_Ehdr);
00152 write(outfd, scntab[0], sizeof(Elf32_Shdr));
00153 for (i=1; i<scn_num; i++) {
00154 if (scn_symt[i]!=0) {
00155 j=scntab[i].sh_link;
00156 if (j!=0) scntab[i].sh_link=scn_symt[j];
00157 scntab[i].sh_offset=scn_offset;
00158 scn_offset += scntab[i].sh_size;
00159 write(outfd, scntab[i], sizeof(Elf32_Shdr));
00160 } }
00161
00162 elf_end(elf);
00163 close(elfd);
00164 close(outfd);
00165 }
00166
00167