Print this page
10476 file(1) could be smatch clean
10366 ld(1) should support GNU-style linker sets
10581 ld(1) should know kernel modules are a thing

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/file/elf_read.c
          +++ new/usr/src/cmd/file/elf_read.c
↓ open down ↓ 11 lines elided ↑ open up ↑
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  22      -/*        All Rights Reserved   */
       22 +/*        All Rights Reserved   */
  23   23  
  24   24  
  25   25  /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  26   26  /*        All Rights Reserved   */
  27   27  
  28   28  /*
  29   29   * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  30   30   * Use is subject to license terms.
  31   31   */
  32   32  
↓ open down ↓ 39 lines elided ↑ open up ↑
  72   72  #include <stdlib.h>
  73   73  #include <limits.h>
  74   74  #include <locale.h>
  75   75  #include <string.h>
  76   76  #include <errno.h>
  77   77  #include <procfs.h>
  78   78  #include <sys/param.h>
  79   79  #include <sys/types.h>
  80   80  #include <sys/stat.h>
  81   81  #include <sys/elf.h>
       82 +#include <sys/link.h>
  82   83  #include <elfcap.h>
  83   84  #include "file.h"
  84   85  #include "elf_read.h"
  85   86  
  86   87  extern const char *File;
  87   88  
  88   89  static int get_class(void);
  89   90  static int get_version(void);
  90   91  static int get_format(void);
  91   92  static int process_shdr(Elf_Info *);
↓ open down ↓ 26 lines elided ↑ open up ↑
 118  119  }
 119  120  
 120  121  static int
 121  122  get_format(void)
 122  123  {
 123  124          return (EI_Ehdr.e_ident[EI_DATA]);
 124  125  }
 125  126  
 126  127  /*
 127  128   * file_xlatetom:       translate different headers from file
 128      - *                      representation to memory representaion.
      129 + *                      representation to memory representaion.
 129  130   */
 130  131  #define HDRSZ 512
 131  132  static int
 132  133  file_xlatetom(Elf_Type type, char *hdr)
 133  134  {
 134  135          Elf_Data src, dst;
 135  136          char *hbuf[HDRSZ];
 136  137          int version, format;
 137  138  
 138  139          version = get_version();
 139  140          format = get_format();
 140  141  
 141  142          /* will convert only these types */
 142  143          if (type != ELF_T_EHDR && type != ELF_T_PHDR &&
 143  144              type != ELF_T_SHDR && type != ELF_T_WORD &&
 144      -            type != ELF_T_CAP)
      145 +            type != ELF_T_CAP && type != ELF_T_DYN)
 145  146                  return (ELF_READ_FAIL);
 146  147  
 147  148          src.d_buf = (Elf_Void *)hdr;
 148  149          src.d_type = type;
 149  150          src.d_version = version;
 150  151  
 151  152          dst.d_buf = (Elf_Void *)&hbuf;
 152  153          dst.d_version = EV_CURRENT;
 153  154  
 154  155          src.d_size = elf_fsize(type, 1, version);
 155  156          dst.d_size = elf_fsize(type, 1, EV_CURRENT);
 156  157          if (elf_xlatetom(&dst, &src, format) == NULL)
 157  158                  return (ELF_READ_FAIL);
 158  159  
 159  160          (void) memcpy(hdr, &hbuf, dst.d_size);
 160  161          return (ELF_READ_OKAY);
 161  162  }
 162  163  
 163  164  /*
 164  165   * xlatetom_nhdr:       There is no routine to convert Note header
 165      - *                      so we convert each field of this header.
      166 + *                      so we convert each field of this header.
 166  167   */
 167  168  static int
 168  169  xlatetom_nhdr(Elf_Nhdr *nhdr)
 169  170  {
 170  171          int r = ELF_READ_FAIL;
 171  172  
 172  173          r |= file_xlatetom(ELF_T_WORD, (char *)&nhdr->n_namesz);
 173  174          r |= file_xlatetom(ELF_T_WORD, (char *)&nhdr->n_descsz);
 174  175          r |= file_xlatetom(ELF_T_WORD, (char *)&nhdr->n_type);
 175  176          return (r);
 176  177  }
 177  178  
 178  179  /*
 179  180   * elf_read:    reads elf header, program, section headers to
 180      - *              collect all information needed for file(1)
      181 + *              collect all information needed for file(1)
 181  182   *              output and stores them in Elf_Info.
 182  183   */
 183  184  int
 184  185  elf_read(int fd, Elf_Info *EI)
 185  186  {
 186  187          FILE_ELF_SIZE_T size;
 187  188          int             ret = 1;
 188  189  
 189  190          Elf_Ehdr *ehdr = &EI_Ehdr;
 190  191  
↓ open down ↓ 102 lines elided ↑ open up ↑
 293  294  
 294  295          if (file_xlatetom(ELF_T_SHDR, (char *)&EI_Shdr) == ELF_READ_FAIL)
 295  296                  return (ELF_READ_FAIL);
 296  297  
 297  298          return (ELF_READ_OKAY);
 298  299  }
 299  300  
 300  301  /*
 301  302   * process_phdr:        Read Program Headers and see if it is a core
 302  303   *                      file of either new or (pre-restructured /proc)
 303      - *                      type, read the name of the file that dumped this
      304 + *                      type, read the name of the file that dumped this
 304  305   *                      core, else see if this is a dynamically linked.
 305  306   */
 306  307  static int
 307  308  process_phdr(Elf_Info *EI)
 308  309  {
 309  310          register int inx;
 310  311  
 311  312          Elf_Nhdr        Nhdr, *nhdr;    /* note header just read */
 312  313          Elf_Phdr        *phdr = &EI_Phdr;
 313  314  
↓ open down ↓ 94 lines elided ↑ open up ↑
 408  409   * process_shdr:        Read Section Headers to attempt to get HW/SW
 409  410   *                      capabilities by looking at the SUNW_cap
 410  411   *                      section and set string in Elf_Info.
 411  412   *                      Also look for symbol tables and debug
 412  413   *                      information sections. Set the "stripped" field
 413  414   *                      in Elf_Info with corresponding flags.
 414  415   */
 415  416  static int
 416  417  process_shdr(Elf_Info *EI)
 417  418  {
 418      -        int             capn, mac;
 419      -        int             i, j, idx;
 420      -        FILE_ELF_OFF_T  cap_off;
 421      -        FILE_ELF_SIZE_T csize;
      419 +        int             mac;
      420 +        int             i, idx;
 422  421          char            *strtab;
 423  422          size_t          strtab_sz;
 424      -        Elf_Cap         Chdr;
      423 +        uint64_t        j;
 425  424          Elf_Shdr        *shdr = &EI_Shdr;
 426  425  
 427      -
 428      -        csize = sizeof (Elf_Cap);
 429  426          mac = EI_Ehdr.e_machine;
 430  427  
 431  428          /* if there are no sections, return success anyway */
 432  429          if (EI_Ehdr.e_shoff == 0 && EI_Ehdr_shnum == 0)
 433  430                  return (ELF_READ_OKAY);
 434  431  
 435  432          /* read section names from String Section */
 436  433          if (get_shdr(EI, EI_Ehdr_shstrndx) == ELF_READ_FAIL)
 437  434                  return (ELF_READ_FAIL);
 438  435  
↓ open down ↓ 11 lines elided ↑ open up ↑
 450  447                  char *shnam;
 451  448  
 452  449                  if (get_shdr(EI, i) == ELF_READ_FAIL)
 453  450                          return (ELF_READ_FAIL);
 454  451  
 455  452                  if (shdr->sh_type == SHT_NULL) {
 456  453                          idx--;
 457  454                          continue;
 458  455                  }
 459  456  
 460      -                cap_off = shdr->sh_offset;
 461  457                  if (shdr->sh_type == SHT_SUNW_cap) {
 462      -                        char capstr[128];
      458 +                        char            capstr[128];
      459 +                        Elf_Cap         Chdr;
      460 +                        FILE_ELF_OFF_T  cap_off;
      461 +                        FILE_ELF_SIZE_T csize;
      462 +                        uint64_t capn;
      463 +
      464 +                        cap_off = shdr->sh_offset;
      465 +                        csize = sizeof (Elf_Cap);
 463  466  
 464  467                          if (shdr->sh_size == 0 || shdr->sh_entsize == 0) {
 465  468                                  (void) fprintf(stderr, ELF_ERR_ELFCAP1,
 466  469                                      File, EI->file);
 467  470                                  return (ELF_READ_FAIL);
 468  471                          }
 469  472                          capn = (shdr->sh_size / shdr->sh_entsize);
 470  473                          for (j = 0; j < capn; j++) {
 471  474                                  /*
 472  475                                   * read cap and xlate the values
 473  476                                   */
 474      -                                if (pread64(EI->elffd, &Chdr, csize, cap_off)
 475      -                                    != csize ||
      477 +                                if ((pread64(EI->elffd, &Chdr, csize, cap_off)
      478 +                                    != csize) ||
 476  479                                      file_xlatetom(ELF_T_CAP, (char *)&Chdr)
 477  480                                      == 0) {
 478  481                                          (void) fprintf(stderr, ELF_ERR_ELFCAP2,
 479  482                                              File, EI->file);
 480  483                                          return (ELF_READ_FAIL);
 481  484                                  }
 482  485  
 483  486                                  cap_off += csize;
 484  487  
 485  488                                  /*
↓ open down ↓ 9 lines elided ↑ open up ↑
 495  498                                      Chdr.c_tag, Chdr.c_un.c_val, capstr,
 496  499                                      sizeof (capstr), ELFCAP_FMT_SNGSPACE,
 497  500                                      mac);
 498  501  
 499  502                                  if ((*EI->cap_str != '\0') && (*capstr != '\0'))
 500  503                                          (void) strlcat(EI->cap_str, " ",
 501  504                                              sizeof (EI->cap_str));
 502  505  
 503  506                                  (void) strlcat(EI->cap_str, capstr,
 504  507                                      sizeof (EI->cap_str));
      508 +                        }
      509 +                } else if (shdr->sh_type == SHT_DYNAMIC) {
      510 +                        Elf_Dyn dyn;
      511 +                        FILE_ELF_SIZE_T dsize;
      512 +                        FILE_ELF_OFF_T doff;
      513 +                        uint64_t dynn;
      514 +
      515 +                        doff = shdr->sh_offset;
      516 +                        dsize = sizeof (Elf_Dyn);
      517 +
      518 +                        if (shdr->sh_size == 0 || shdr->sh_entsize == 0) {
      519 +                                (void) fprintf(stderr, ELF_ERR_DYNAMIC1,
      520 +                                    File, EI->file);
      521 +                                return (ELF_READ_FAIL);
      522 +                        }
      523 +
      524 +                        dynn = (shdr->sh_size / shdr->sh_entsize);
      525 +                        for (j = 0; j < dynn; j++) {
      526 +                                if (pread64(EI->elffd, &dyn, dsize, doff)
      527 +                                    != dsize ||
      528 +                                    file_xlatetom(ELF_T_DYN, (char *)&dyn)
      529 +                                    == 0) {
      530 +                                        (void) fprintf(stderr, ELF_ERR_DYNAMIC2,
      531 +                                            File, EI->file);
      532 +                                        return (ELF_READ_FAIL);
      533 +                                }
      534 +
      535 +                                doff += dsize;
      536 +
      537 +                                if ((dyn.d_tag == DT_SUNW_KMOD) &&
      538 +                                    (dyn.d_un.d_val == 1)) {
      539 +                                        EI->kmod = B_TRUE;
      540 +                                }
 505  541                          }
 506  542                  }
 507  543  
 508  544                  /*
 509  545                   * Definition time:
 510  546                   *      - "not stripped" means that an executable file
 511  547                   *      contains a Symbol Table (.symtab)
 512  548                   *      - "stripped" means that an executable file
 513  549                   *      does not contain a Symbol Table.
 514  550                   * When strip -l or strip -x is run, it strips the
↓ open down ↓ 45 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX