[BACK]Return to elf.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / nm

Diff for /src/usr.bin/nm/elf.c between version 1.9 and 1.10

version 1.9, 2004/10/09 20:17:52 version 1.10, 2004/10/09 20:26:57
Line 26 
Line 26 
  * THE POSSIBILITY OF SUCH DAMAGE.   * THE POSSIBILITY OF SUCH DAMAGE.
  */   */
   
 #if ELF_TARG_CLASS == ELFCLASS32  #include <sys/param.h>
   #include <sys/mman.h>
   #include <unistd.h>
   #include <a.out.h>
   #include <elf_abi.h>
   #include <errno.h>
   #include <err.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <ctype.h>
   #include "elfuncs.h"
   #include "util.h"
   
   #if ELFSIZE == 32
 #define swap_addr       swap32  #define swap_addr       swap32
 #define swap_off        swap32  #define swap_off        swap32
 #define swap_sword      swap32  #define swap_sword      swap32
Line 35 
Line 49 
 #define swap_xword      swap32  #define swap_xword      swap32
 #define swap_half       swap16  #define swap_half       swap16
 #define swap_quarter    swap16  #define swap_quarter    swap16
 #elif ELF_TARG_CLASS == ELFCLASS64  #define elf_fix_header  elf32_fix_header
   #define elf_load_shdrs  elf32_load_shdrs
   #define elf_fix_shdrs   elf32_fix_shdrs
   #define elf_fix_phdrs   elf32_fix_phdrs
   #define elf_fix_sym     elf32_fix_sym
   #define elf_size        elf32_size
   #define elf_symload     elf32_symload
   #define elf2nlist       elf32_2nlist
   #define elf_shn2type    elf32_shn2type
   #elif ELFSIZE == 64
 #define swap_addr       swap64  #define swap_addr       swap64
 #define swap_off        swap64  #define swap_off        swap64
 #ifdef __alpha__  #ifdef __alpha__
Line 49 
Line 72 
 #define swap_xword      swap64  #define swap_xword      swap64
 #define swap_half       swap64  #define swap_half       swap64
 #define swap_quarter    swap16  #define swap_quarter    swap16
   #define elf_fix_header  elf64_fix_header
   #define elf_load_shdrs  elf64_load_shdrs
   #define elf_fix_shdrs   elf64_fix_shdrs
   #define elf_fix_phdrs   elf64_fix_phdrs
   #define elf_fix_sym     elf64_fix_sym
   #define elf_size        elf64_size
   #define elf_symload     elf64_symload
   #define elf2nlist       elf64_2nlist
   #define elf_shn2type    elf64_shn2type
 #else  #else
 #error "Unsupported ELF class"  #error "Unsupported ELF class"
 #endif  #endif
Line 81 
Line 113 
         return (1);          return (1);
 }  }
   
   Elf_Shdr *
   elf_load_shdrs(const char *name, FILE *fp, off_t foff, Elf_Ehdr *head)
   {
           Elf_Shdr *shdr;
   
           elf_fix_header(head);
   
           if ((shdr = malloc(head->e_shentsize * head->e_shnum)) == NULL) {
                   warn("%s: malloc shdr", name);
                   return (NULL);
           }
   
           if (fseeko(fp, foff + head->e_shoff, SEEK_SET)) {
                   warn("%s: fseeko", name);
                   free(shdr);
                   return (NULL);
           }
   
           if (fread(shdr, head->e_shentsize, head->e_shnum, fp) != head->e_shnum) {
                   warnx("%s: premature EOF", name);
                   free(shdr);
                   return (NULL);
           }
   
           elf_fix_shdrs(head, shdr);
           return (shdr);
   }
   
 int  int
 elf_fix_shdrs(Elf_Ehdr *eh, Elf_Shdr *shdr)  elf_fix_shdrs(Elf_Ehdr *eh, Elf_Shdr *shdr)
 {  {
Line 276 
Line 336 
                 np->n_type |= N_EXT;                  np->n_type |= N_EXT;
                 if (np->n_other)                  if (np->n_other)
                         np->n_other = toupper(np->n_other);                          np->n_other = toupper(np->n_other);
           }
   
           return (0);
   }
   
   int
   elf_size(Elf_Ehdr *head, Elf_Shdr *shdr,
       u_long *ptext, u_long *pdata, u_long *pbss)
   {
           int i;
   
           *ptext = *pdata = *pbss = 0;
   
           for (i = 0; i < head->e_shnum; i++) {
                   if (!(shdr[i].sh_flags & SHF_ALLOC))
                           ;
                   else if (shdr[i].sh_flags & SHF_EXECINSTR ||
                       !(shdr[i].sh_flags & SHF_WRITE))
                           *ptext += shdr[i].sh_size;
                   else if (shdr[i].sh_type == SHT_NOBITS)
                           *pbss += shdr[i].sh_size;
                   else
                           *pdata += shdr[i].sh_size;
           }
   
           return (0);
   }
   
   int
   elf_symload(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh,
       Elf_Shdr *shdr, struct nlist **pnames, struct nlist ***psnames,
       size_t *pstabsize, int *pnrawnames)
   {
           long symsize, shstrsize;
           struct nlist *np;
           Elf_Sym sbuf;
           char *shstr;
           int i;
   
           shstrsize = shdr[eh->e_shstrndx].sh_size;
           if ((shstr = malloc(shstrsize)) == NULL) {
                   warn("%s: malloc shsrt", name);
                   return (1);
           }
   
           if (fseeko(fp, foff + shdr[eh->e_shstrndx].sh_offset, SEEK_SET)) {
                   warn("%s: fseeko", name);
                   free(shstr);
                   return (1);
           }
   
           if (fread(shstr, 1, shstrsize, fp) != shstrsize) {
                   warnx("%s: premature EOF", name);
                   free(shstr);
                   return(1);
           }
   
           stab = NULL;
           *pnames = NULL; *psnames = NULL;
           for (i = 0; i < eh->e_shnum; i++) {
                   if (!strcmp(shstr + shdr[i].sh_name, ELF_STRTAB)) {
                           *pstabsize = shdr[i].sh_size;
                           if (*pstabsize > SIZE_T_MAX) {
                                   warnx("%s: corrupt file", name);
                                   free(shstr);
                                   return (1);
                           }
   
                           MMAP(stab, *pstabsize, PROT_READ, MAP_PRIVATE|MAP_FILE,
                               fileno(fp), foff + shdr[i].sh_offset);
                           if (stab == MAP_FAILED) {
                                   free(shstr);
                                   return (1);
                           }
                   }
           }
           for (i = 0; i < eh->e_shnum; i++) {
                   if (!strcmp(shstr + shdr[i].sh_name, ELF_SYMTAB)) {
                           symsize = shdr[i].sh_size;
                           if (fseeko(fp, foff + shdr[i].sh_offset, SEEK_SET)) {
                                   warn("%s: fseeko", name);
                                   if (stab)
                                           MUNMAP(stab, *pstabsize);
                                   free(shstr);
                                   return (1);
                           }
   
                           *pnrawnames = symsize / sizeof(sbuf);
                           if ((*pnames = calloc(*pnrawnames, sizeof(*np))) == NULL) {
                                   warn("%s: malloc names", name);
                                   if (stab)
                                           MUNMAP(stab, *pstabsize);
                                   free(*pnames);
                                   free(shstr);
                                   return (1);
                           }
                           if ((*psnames = malloc(*pnrawnames * sizeof(np))) == NULL) {
                                   warn("%s: malloc snames", name);
                                   if (stab)
                                           MUNMAP(stab, *pstabsize);
                                   free(shstr);
                                   free(*pnames);
                                   free(*psnames);
                                   return (1);
                           }
   
                           for (np = *pnames; symsize > 0; symsize -= sizeof(sbuf)) {
                                   if (fread(&sbuf, 1, sizeof(sbuf),
                                       fp) != sizeof(sbuf)) {
                                           warn("%s: read symbol", name);
                                           if (stab)
                                                   MUNMAP(stab, *pstabsize);
                                           free(shstr);
                                           free(*pnames);
                                           free(*psnames);
                                           return (1);
                                   }
   
                                   elf_fix_sym(eh, &sbuf);
   
                                   if (!sbuf.st_name)
                                           continue;
   
                                   elf2nlist(&sbuf, eh, shdr, shstr, np);
                                   np->n_value = sbuf.st_value;
                                   np->n_un.n_strx = sbuf.st_name;
                                   np++;
                           }
                           *pnrawnames = np - *pnames;
                   }
           }
   
           free(shstr);
           if (stab == NULL) {
                   warnx("%s: no name list", name);
                   if (*pnames)
                           free(*pnames);
                   if (*psnames)
                           free(*psnames);
                   return (1);
         }          }
   
         return (0);          return (0);

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10