Mercurial > hg > chrpath
comparison elf.c @ 1:bbbfb3f97919
implement 32 and 64 bit support
| author | Peter Meerwald <p.meerwald@bct-electronic.com> | 
|---|---|
| date | Fri, 20 Jul 2012 11:26:24 +0200 | 
| parents | b8f7423e385c | 
| children | 
   comparison
  equal
  deleted
  inserted
  replaced
| 0:b8f7423e385c | 1:bbbfb3f97919 | 
|---|---|
| 15 #include <errno.h> | 15 #include <errno.h> | 
| 16 #include <fcntl.h> | 16 #include <fcntl.h> | 
| 17 #include "protos.h" | 17 #include "protos.h" | 
| 18 | 18 | 
| 19 int | 19 int | 
| 20 elf_open(const char *filename, int flags, Elf_Ehdr *ehdr) | 20 elf32_open(const char *filename, int flags, Elf32_Ehdr *ehdr) | 
| 21 { | 21 { | 
| 22 int fd; | 22 int fd; | 
| 23 | 23 | 
| 24 fd = open(filename, flags); | 24 fd = open(filename, flags); | 
| 25 if (fd == -1) | 25 if (fd == -1) | 
| 34 close(fd); | 34 close(fd); | 
| 35 return -1; | 35 return -1; | 
| 36 } | 36 } | 
| 37 | 37 | 
| 38 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || | 38 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || | 
| 39 ehdr->e_ident[EI_CLASS] != ELFCLASS || | 39 ehdr->e_ident[EI_CLASS] != ELFCLASS32 || | 
| 40 ehdr->e_ident[EI_DATA] != ELFDATA2 || | 40 ehdr->e_ident[EI_DATA] != ELFDATA2 || | 
| 41 ehdr->e_ident[EI_VERSION] != EV_CURRENT) | 41 ehdr->e_ident[EI_VERSION] != EV_CURRENT) | 
| 42 { | 42 { | 
| 43 fprintf(stderr, | 43 fprintf(stderr, | 
| 44 #ifdef WORDS_BIGENDIAN | 44 #ifdef WORDS_BIGENDIAN | 
| 45 "`%s' probably isn't a %d-bit MSB-first ELF file.\n", | 45 "`%s' probably isn't a %d-bit MSB-first ELF file.\n", | 
| 46 #else /* not WORD_BIGENDIAN */ | 46 #else /* not WORD_BIGENDIAN */ | 
| 47 "`%s' probably isn't a %d-bit LSB-first ELF file.\n", | 47 "`%s' probably isn't a %d-bit LSB-first ELF file.\n", | 
| 48 #endif /* not WORD_BIGENDIAN */ | 48 #endif /* not WORD_BIGENDIAN */ | 
| 49 filename, SIZEOF_VOID_P * 8); | 49 filename, 32); | 
| 50 close(fd); | 50 close(fd); | 
| 51 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ | 51 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ | 
| 52 return -1; | 52 return -1; | 
| 53 } | 53 } | 
| 54 | 54 | 
| 55 if (ehdr->e_phentsize != sizeof(Elf_Phdr)) | 55 printf("32-bit ELF file\n"); | 
| 56 { | 56 | 
| 57 fprintf(stderr, "section size was read as %d, not %d!\n", | 57 if (ehdr->e_phentsize != sizeof(Elf32_Phdr)) | 
| 58 ehdr->e_phentsize, sizeof(Elf_Phdr)); | 58 { | 
| 59 fprintf(stderr, "section size was read as %d, not %lu!\n", | |
| 60 ehdr->e_phentsize, sizeof(Elf32_Phdr)); | |
| 59 close(fd); | 61 close(fd); | 
| 60 return -1; | 62 return -1; | 
| 61 } | 63 } | 
| 62 return fd; | 64 return fd; | 
| 63 } | 65 } | 
| 64 | 66 | 
| 65 int | 67 int | 
| 66 elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr) | 68 elf64_open(const char *filename, int flags, Elf64_Ehdr *ehdr) | 
| 69 { | |
| 70 int fd; | |
| 71 | |
| 72 fd = open(filename, flags); | |
| 73 if (fd == -1) | |
| 74 { | |
| 75 perror ("open"); | |
| 76 return -1; | |
| 77 } | |
| 78 | |
| 79 if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr)) | |
| 80 { | |
| 81 perror ("reading header"); | |
| 82 close(fd); | |
| 83 return -1; | |
| 84 } | |
| 85 | |
| 86 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || | |
| 87 ehdr->e_ident[EI_CLASS] != ELFCLASS64 || | |
| 88 ehdr->e_ident[EI_DATA] != ELFDATA2 || | |
| 89 ehdr->e_ident[EI_VERSION] != EV_CURRENT) | |
| 90 { | |
| 91 fprintf(stderr, | |
| 92 #ifdef WORDS_BIGENDIAN | |
| 93 "`%s' probably isn't a %d-bit MSB-first ELF file.\n", | |
| 94 #else /* not WORD_BIGENDIAN */ | |
| 95 "`%s' probably isn't a %d-bit LSB-first ELF file.\n", | |
| 96 #endif /* not WORD_BIGENDIAN */ | |
| 97 filename, 64); | |
| 98 close(fd); | |
| 99 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ | |
| 100 return -1; | |
| 101 } | |
| 102 | |
| 103 printf("64-bit ELF file\n"); | |
| 104 | |
| 105 if (ehdr->e_phentsize != sizeof(Elf64_Phdr)) | |
| 106 { | |
| 107 fprintf(stderr, "section size was read as %d, not %lu!\n", | |
| 108 ehdr->e_phentsize, sizeof(Elf64_Phdr)); | |
| 109 close(fd); | |
| 110 return -1; | |
| 111 } | |
| 112 return fd; | |
| 113 } | |
| 114 | |
| 115 int | |
| 116 elf32_find_dynamic_section(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr) | |
| 117 { | |
| 118 int i; | |
| 119 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) | |
| 120 { | |
| 121 perror ("positioning for sections"); | |
| 122 return 1; | |
| 123 } | |
| 124 | |
| 125 for (i = 0; i < ehdr->e_phnum; i++) | |
| 126 { | |
| 127 if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) | |
| 128 { | |
| 129 perror ("reading section header"); | |
| 130 return 1; | |
| 131 } | |
| 132 if (phdr->p_type == PT_DYNAMIC) | |
| 133 break; | |
| 134 } | |
| 135 if (i == ehdr->e_phnum) | |
| 136 { | |
| 137 fprintf (stderr, "No dynamic section found.\n"); | |
| 138 return 2; | |
| 139 } | |
| 140 | |
| 141 if (0 == phdr->p_filesz) | |
| 142 { | |
| 143 fprintf (stderr, "Length of dynamic section is zero.\n"); | |
| 144 return 3; | |
| 145 } | |
| 146 | |
| 147 return 0; | |
| 148 } | |
| 149 | |
| 150 int | |
| 151 elf64_find_dynamic_section(int fd, Elf64_Ehdr *ehdr, Elf64_Phdr *phdr) | |
| 67 { | 152 { | 
| 68 int i; | 153 int i; | 
| 69 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) | 154 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) | 
| 70 { | 155 { | 
| 71 perror ("positioning for sections"); | 156 perror ("positioning for sections"); | 
