Hosted by the courtesy of  
 GitHub 
The stars ASAP english francais spanish arab
Durée du voyage intersidéral francais
Résolutions de l'ONU en HTML francais
Bussard Ramjet english francais
DWARF : dwarf2xml english
ELF : libelf examples english
Code presentation : ctoohtml english

Elf sample home

File Index

All Tags

Tags by File

Tags referrers

file: elf_copy.c


  1 /*
  2 * Copy an elf to an ELF object.
  3 * This is a demo program for libraries libelf and gelf. The resulting elf file
  4 * may not be loadable due to offset changes.
  5 * 2007.11.10 19:52:23 Emmanuel AZENCOT
  6 *   Creation
  7 * Sun Nov 22 20:33:20 CET 2009
  8 *   bug fix in error message \%s\"
  9 *
 10 * build : gcc -Wall -g -o elf_copy -lelf elf_copy.c
 11 * TODO
 12 *  output a working binary
 13 */

 14 #include <string.h>
 15 #include <stdio.h>
 16 #include <stdlib.h>
 17 #include <sysexits.h>
 18 #include <unistd.h>
 19 #include <fcntl.h>
 20 #include <errno.h>
 21
 22 #include <err.h>
 23 #include <gelf.h>
 24
 25 #define /*X*/ errx(code, fmt, args...) { \
 26   fprintf(stderr,#code ": error in file %s at line %d in function %s:", __FILE__,__LINE__,__FUNCTION__); \
 27   fprintf(stderr,fmt "\n", ##args); \
 28   exit(1); \
 29 }

 30 #define /*X*/ merrx(code, fmt, args...) { \
 31   fprintf(stderr,#code ": error in file %s at line %d in function %s:", __FILE__,__LINE__,__FUNCTION__); \
 32   fprintf(stderr,fmt "\n", ##args); \
 33   return 0; \
 34 }

 35
 36 int /*X*/ melf_cpy_scn (Elf *elf_out, Elf_Scn  *scn_out, Elf *elf_in, Elf_Scn *scn_in) {
 37   Elf_Data *data_in, *data_out;
 38   GElf_Shdr shdr_in, shdr_out;
 39   size_t n;
 40
 41   if (gelf_getshdr(scn_in, &shdr_in) != &shdr_in)
 42      merrx(EX_SOFTWARE, "getshdr() failed: %s.", elf_errmsg(-1));
 43
 44   data_in = NULL; n = 0;
 45   while (n < shdr_in.sh_size && (data_in = elf_getdata(scn_in, data_in)) != NULL) {
 46      if ((data_out = elf_newdata(scn_out)) == NULL)
 47         merrx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1));
 48      *data_out = *data_in;
 49   }
 50
 51   if ( gelf_getshdr(scn_out, &shdr_out) != &shdr_out)
 52      merrx(EX_SOFTWARE, "gelf_getshdr() failed: %s.", elf_errmsg(-1));
 53
 54   shdr_out = shdr_in;
 55
 56   if ( gelf_update_shdr (scn_out, &shdr_out) == 0)
 57      merrx(EX_SOFTWARE, "gelf_update_shdr() failed: %s.", elf_errmsg(-1));
 58
 59   return 1;
 60 }
 61 int /*X*/ main(int argc, char *argv[]) {
 62   int fd_in = -1, fd_out = -1;
 63   Elf *elf_in = 0, *elf_out = 0;
 64
 65   Elf_Scn *scn_in, *scn_out;
 66   GElf_Ehdr ehdr_in, ehdr_out;
 67
 68   size_t shstrndx;
 69
 70   int scn_index = 0;
 71
 72   if (argc != 3)
 73      errx(EX_USAGE, "USAGE: %s in-file-name out-file-name", argv[0]);
 74
 75   if (elf_version(EV_CURRENT) == EV_NONE)
 76      errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1));
 77
 78   if ((fd_in = open(argv[1], O_RDONLY, 0)) < 0)
 79      err(EX_NOINPUT, "open \"%s\" failed", argv[1]);
 80
 81   if ((elf_in = elf_begin(fd_in, ELF_C_READ, NULL)) == NULL)
 82      errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1));
 83
 84   if (gelf_getehdr(elf_in, &ehdr_in) != &ehdr_in)
 85      errx(EX_SOFTWARE, "gelf_getehdr() failed: %s.", elf_errmsg(-1));
 86
 87   /* get string section index for section names */
 88   if (elf_getshstrndx(elf_in, &shstrndx) != 0)
 89       errx(EX_SOFTWARE, "getshstrndx() failed: %s, %d.", elf_errmsg(-1), shstrndx);
 90
 91   /* Checks and warns */
 92   if ( elf_kind(elf_in) != ELF_K_ELF ) {
 93      fprintf(stderr, "%s : %s must be an ELF file.\n", argv[0], argv[1]);
 94      exit(1);
 95   }
 96
 97   printf("Elf %s have %d sections\n", argv[1], ehdr_in.e_shnum);
 98   /* opent output elf */
 99   if ((fd_out = open(argv[2], O_WRONLY|O_CREAT, 0777)) < 0)
100      errx(EX_OSERR, "open \"%s\" failed", argv[2]);
101
102   if ((elf_out = elf_begin(fd_out, ELF_C_WRITE, NULL)) == NULL)
103      errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1));
104
105   /* create new elf header */
106   if ( gelf_newehdr(elf_out, ehdr_in.e_ident[EI_CLASS]) == 0)
107      errx(EX_SOFTWARE, "gelf_newehdr() failed: %s.", elf_errmsg(-1));
108   if ( gelf_getehdr(elf_out, &ehdr_out) != &ehdr_out)
109      errx(EX_SOFTWARE, "gelf_getehdr() failed: %s.", elf_errmsg(-1));
110   ehdr_out = ehdr_in;
111   ehdr_out.e_ehsize = 0;
112   ehdr_out.e_phentsize = 0;
113   ehdr_out.e_phnum = 0;
114   ehdr_out.e_shentsize = 0;
115   ehdr_out.e_shnum = 0;
116   if ( gelf_update_ehdr (elf_out, &ehdr_out) == 0)
117      errx(EX_SOFTWARE, "gelf_update_ehdr() failed: %s.", elf_errmsg(-1));
118
119   {
120      GElf_Phdr phdr_in, phdr_out;
121      int ph_ndx;
122
123      if ( ehdr_in.e_phnum && gelf_newphdr (elf_out, ehdr_in.e_phnum) == 0 )
124         errx(EX_SOFTWARE, "gelf_newphdr() failed: %s.", elf_errmsg(-1));
125
126      for ( ph_ndx = 0; ph_ndx < ehdr_in.e_phnum; ++ph_ndx ) {
127         printf("Copying prog header %d\n", ph_ndx);
128
129         if ( gelf_getphdr (elf_in, ph_ndx, &phdr_in) != &phdr_in )
130            errx(EX_SOFTWARE, "gelf_getphdr() failed: %s.", elf_errmsg(-1));
131
132         if ( gelf_getphdr (elf_out, ph_ndx, &phdr_out) != &phdr_out )
133            errx(EX_SOFTWARE, "gelf_getphdr() failed: %s.", elf_errmsg(-1));
134         phdr_out = phdr_in;
135
136         if ( gelf_update_phdr (elf_out, ph_ndx, &phdr_out) == 0)
137            errx(EX_SOFTWARE, "gelf_update_phdr() failed: %s.", elf_errmsg(-1));
138      }
139   }
140   /* copy sections to new elf */
141   for ( scn_index = 1; scn_index < ehdr_in.e_shnum; scn_index++ ) {
142      if ( (scn_in = elf_getscn(elf_in, scn_index)) == NULL)
143         errx(EX_SOFTWARE, "getshdr() failed: %s.", elf_errmsg(-1));
144      if ((scn_out = elf_newscn(elf_out)) == NULL)
145         errx(EX_SOFTWARE, "elf_newscn() failed: %s.", elf_errmsg(-1));
146      if ( melf_cpy_scn (elf_out, scn_out, elf_in, scn_in) == 0 )
147         errx(EX_SOFTWARE, "melf_cpy_scn() failed: %s.", elf_errmsg(-1));
148   }
149   /* Adjust section offset in Phrs */
150   {
151      GElf_Phdr phdr_in, phdr_out;
152      int ph_ndx;
153
154      if ( ehdr_in.e_phnum && gelf_newphdr (elf_out, ehdr_in.e_phnum) == 0 )
155         errx(EX_SOFTWARE, "gelf_newphdr() failed: %s.", elf_errmsg(-1));
156
157      for ( ph_ndx = 0; ph_ndx < ehdr_in.e_phnum; ++ph_ndx ) {
158         GElf_Shdr shdr_out;
159         if ( gelf_getphdr (elf_in, ph_ndx, &phdr_in) != &phdr_in )
160            errx(EX_SOFTWARE, "gelf_getphdr() failed: %s.", elf_errmsg(-1));
161
162         if ( gelf_getphdr (elf_out, ph_ndx, &phdr_out) != &phdr_out )
163            errx(EX_SOFTWARE, "gelf_getphdr() failed: %s.", elf_errmsg(-1));
164
165         if ( !phdr_in.p_offset || phdr_in.p_type == PT_PHDR ) continue;
166         /* Get section offset from input phdr */
167         if ( (scn_in = gelf_offscn (elf_in, phdr_in.p_offset )) == NULL)
168            errx(EX_SOFTWARE, "gelf_offscn() failed: %s.", elf_errmsg(-1));
169         /* Convert to section index */
170         if ( (scn_index = elf_ndxscn (scn_in)) == 0)
171            fprintf(stderr, "elf_ndxscn() failed for phdr %d : %s.", ph_ndx, elf_errmsg(-1));
172         /* get out section at same index from out elf */
173         if ( (scn_out   = elf_getscn(elf_out, scn_index)) == NULL)
174            errx(EX_SOFTWARE, "getshdr() failed: %s.", elf_errmsg(-1));
175         /* get out section offset from section header */
176         if ( gelf_getshdr(scn_out, &shdr_out) != &shdr_out)
177            merrx(EX_SOFTWARE, "gelf_getshdr() failed: %s.", elf_errmsg(-1));
178
179         phdr_out.p_offset = shdr_out.sh_offset;
180
181         if ( gelf_update_phdr (elf_out, ph_ndx, &phdr_out) == 0)
182            errx(EX_SOFTWARE, "gelf_update_phdr() failed: %s.", elf_errmsg(-1));
183      }
184   }
185   if (elf_update(elf_out, ELF_C_WRITE) < 0)
186      errx(EX_SOFTWARE, "elf_update() failed: %s.", elf_errmsg(-1));
187
188   elf_end(elf_out);
189   close(fd_out);
190   elf_end(elf_in);
191   close(fd_in);
192
193   exit(EX_OK);
194 }
195


Elf sample home

File Index

All Tags

Tags by File

Tags referrers

C to HTML Conversion by ctoohtml

Hosted by the courtesy of  
 GitHub 
The stars ASAP english francais spanish
Durée du voyage intersidéral francais
Résolutions de l'ONU en HTML francais
Bussard Ramjet english francais
DWARF : dwarf2xml english
ELF : libelf examples english
Code presentation : ctoohtml english