Print this page
6375 Add native name demangling support
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/nm/common/nm.c
          +++ new/usr/src/cmd/sgs/nm/common/nm.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1988 AT&T
  24   24   * Copyright (c) 1989 AT&T
  25   25   * All Rights Reserved
  26   26   *
  27   27   * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
       28 + * Copyright 2018 Jason King
  28   29   */
  29   30  
  30   31  #include <stdio.h>
  31   32  #include <stdlib.h>
  32   33  #include <unistd.h>
  33   34  #include <ctype.h>
  34   35  #include <locale.h>
  35   36  #include <libelf.h>
  36   37  #include <sys/elf_SPARC.h>
  37   38  
↓ open down ↓ 215 lines elided ↑ open up ↑
 253  254                                              "%s: -u or -g set, -e ignored\n"),
 254  255                                              prog_name);
 255  256                                  break;
 256  257                  case 'g':       if (!u_flag && !e_flag)
 257  258                                          g_flag = 1;
 258  259                                  else
 259  260                                          (void) fprintf(stderr, gettext(
 260  261                                              "%s: -u or -e set, -g ignored\n"),
 261  262                                              prog_name);
 262  263                                  break;
 263      -                case 'r':       if (R_flag) {
      264 +                case 'r':       if (R_flag) {
 264  265                                          R_flag = 0;
 265  266                                          (void) fprintf(stderr, gettext(
 266  267                                              "%s: -r set, -R ignored\n"),
 267  268                                              prog_name);
 268  269                                  }
 269  270                                  r_flag = 1;
 270  271                                  break;
 271  272                  case 's':       s_flag = 1;
 272  273                                  break;
 273  274                  case 'p':       if (P_flag == 1) {
↓ open down ↓ 385 lines elided ↑ open up ↑
 659  660   * set, if any.  Input is an opened ELF file, the section name,
 660  661   * the section header, the section descriptor, and the filename.
 661  662   * First get the symbol table with a call to elf_getdata.
 662  663   * Then translate the symbol table data in memory by calling
 663  664   * readsyms().  This avoids duplication of function calls
 664  665   * and improves sorting efficiency.  qsort is used when sorting
 665  666   * is requested.
 666  667   */
 667  668  static void
 668  669  print_symtab(Elf *elf_file, unsigned int shstrndx,
 669      -        Elf_Scn *p_sd, GElf_Shdr *shdr, char *filename)
      670 +    Elf_Scn *p_sd, GElf_Shdr *shdr, char *filename)
 670  671  {
 671  672  
 672  673          Elf_Data * sd;
 673  674          SYM     *sym_data;
 674  675          SYM     *s;
 675  676          GElf_Sxword     count = 0;
 676  677          const int ndigits_arr[] = {
 677  678                  10,             /* FMT_T_DEC */
 678  679                  8,              /* FMT_T_HEX */
 679  680                  11,             /* FMT_T_OCT */
↓ open down ↓ 94 lines elided ↑ open up ↑
 774  775          return (0);
 775  776  }
 776  777  
 777  778  /*
 778  779   * Translate symbol table data particularly for sorting.
 779  780   * Input is the symbol table data structure, number of symbols,
 780  781   * opened ELF file, and the string table link offset.
 781  782   */
 782  783  static SYM *
 783  784  readsyms(Elf_Data * data, GElf_Sxword num, Elf *elf,
 784      -        unsigned int link, unsigned int symscnndx)
      785 +    unsigned int link, unsigned int symscnndx)
 785  786  {
 786  787          SYM             *s, *buf;
 787  788          GElf_Sym        sym;
 788  789          Elf32_Word      *symshndx = 0;
 789  790          unsigned int    nosymshndx = 0;
 790  791          int             i;
 791  792  
 792  793          if ((buf = calloc(num, sizeof (SYM))) == NULL) {
 793  794                  (void) fprintf(stderr, gettext("%s: cannot allocate memory\n"),
 794  795                      prog_name);
↓ open down ↓ 3 lines elided ↑ open up ↑
 798  799          s = buf;        /* save pointer to head of array */
 799  800  
 800  801          for (i = 1; i < num; i++, buf++) {
 801  802                  (void) gelf_getsym(data, i, &sym);
 802  803  
 803  804                  buf->indx = i;
 804  805                  /* allow to work on machines where NULL-derefs dump core */
 805  806                  if (sym.st_name == 0)
 806  807                          buf->name = "";
 807  808                  else if (C_flag) {
 808      -                        const char *dn;
      809 +                        const char *dn = NULL;
 809  810                          char *name = (char *)elf_strptr(elf, link, sym.st_name);
      811 +
 810  812                          dn = conv_demangle_name(name);
 811      -                        if (strcmp(dn, name) == 0) {    /* Not demangled */
 812      -                                if (exotic(name)) {
 813      -                                        name = FormatName(name, d_buf);
 814      -                                }
 815      -                        } else {  /* name demangled */
      813 +                        if (dn != name) {
 816  814                                  name = FormatName(name, dn);
      815 +                                free((void *)dn);
      816 +                        } else if (exotic(name)) {
      817 +                                name = FormatName(name, d_buf);
 817  818                          }
 818  819                          buf->name = name;
 819  820                  }
 820  821                  else
 821  822                          buf->name = (char *)elf_strptr(elf, link, sym.st_name);
 822  823  
 823  824                  buf->value      = sym.st_value;
 824  825                  buf->size       = sym.st_size;
 825  826                  buf->type       = GELF_ST_TYPE(sym.st_info);
 826  827                  buf->bind       = GELF_ST_BIND(sym.st_info);
↓ open down ↓ 180 lines elided ↑ open up ↑
1007 1008           *      (So basically, -f is no-op.)
1008 1009           */
1009 1010          return (1);
1010 1011  }
1011 1012  
1012 1013  #ifndef XPG4
1013 1014  /*
1014 1015   * -u flag specified
1015 1016   */
1016 1017  static void
1017      -print_with_uflag(
1018      -        SYM *sym_data,
1019      -        char *filename
1020      -)
     1018 +print_with_uflag(SYM *sym_data, char *filename)
1021 1019  {
1022 1020          if ((sym_data->shndx == SHN_UNDEF) && (strlen(sym_data->name))) {
1023 1021                  if (!r_flag) {
1024 1022                          if (R_flag) {
1025 1023                                  if (archive_name != (char *)0)
1026 1024                                          (void) printf("   %s:%s:%s\n",
1027 1025                                              archive_name, filename,
1028 1026                                              sym_data->name);
1029 1027                                  else
1030 1028                                          (void) printf("    %s:%s\n",
↓ open down ↓ 56 lines elided ↑ open up ↑
1087 1085                          (void) printf("%-2d", sym_data->type);
1088 1086                  else
1089 1087                          (void) printf("%-3d", sym_data->type);
1090 1088          }
1091 1089  }
1092 1090  
1093 1091  /*
1094 1092   * -p flag specified
1095 1093   */
1096 1094  static void
1097      -print_with_pflag(
1098      -        int ndigits,
1099      -        Elf *elf_file,
1100      -        unsigned int shstrndx,
1101      -        SYM *sym_data,
1102      -        char *filename
1103      -)
     1095 +print_with_pflag(int ndigits, Elf *elf_file, unsigned int shstrndx,
     1096 +    SYM *sym_data, char *filename)
1104 1097  {
1105 1098          const char * const fmt[] = {
1106      -                "%.*llu ",      /* FMT_T_DEC */
1107      -                "0x%.*llx ",    /* FMT_T_HEX */
1108      -                "0%.*llo "      /* FMT_T_OCT */
     1099 +            "%.*llu ",  /* FMT_T_DEC */
     1100 +            "0x%.*llx ",        /* FMT_T_HEX */
     1101 +            "0%.*llo "  /* FMT_T_OCT */
1109 1102          };
1110 1103  
1111 1104          if (is_sym_print(sym_data) != 1)
1112 1105                  return;
1113 1106          /*
1114 1107           * -A header
1115 1108           */
1116 1109          if (A_flag != 0)
1117 1110                  (void) printf("%s", A_header);
1118 1111  
↓ open down ↓ 22 lines elided ↑ open up ↑
1141 1134                          (void) printf("%s\n", sym_data->name);
1142 1135          }
1143 1136          else
1144 1137                  (void) printf("%s:%s\n", filename, sym_data->name);
1145 1138  }
1146 1139  
1147 1140  /*
1148 1141   * -P flag specified
1149 1142   */
1150 1143  static void
1151      -print_with_Pflag(
1152      -        int ndigits,
1153      -        Elf *elf_file,
1154      -        unsigned int shstrndx,
1155      -        SYM *sym_data
1156      -)
     1144 +print_with_Pflag(int ndigits, Elf *elf_file, unsigned int shstrndx,
     1145 +    SYM *sym_data)
1157 1146  {
1158 1147  #define SYM_LEN 10
1159 1148          char sym_name[SYM_LEN+1];
1160 1149          size_t len;
1161 1150          const char * const fmt[] = {
1162 1151                  "%*llu %*llu \n",       /* FMT_T_DEC */
1163 1152                  "%*llx %*llx \n",       /* FMT_T_HEX */
1164 1153                  "%*llo %*llo \n"        /* FMT_T_OCT */
1165 1154          };
1166 1155  
↓ open down ↓ 26 lines elided ↑ open up ↑
1193 1182           *      (hex/octal/decimal)
1194 1183           */
1195 1184          (void) printf(fmt[fmt_flag], ndigits, EC_ADDR(sym_data->value),
1196 1185              ndigits, EC_XWORD(sym_data->size));
1197 1186  }
1198 1187  
1199 1188  /*
1200 1189   * other flags specified
1201 1190   */
1202 1191  static void
1203      -print_with_otherflags(
1204      -        int ndigits,
1205      -        Elf *elf_file,
1206      -        unsigned int shstrndx,
1207      -        SYM *sym_data,
1208      -        char *filename
1209      -)
     1192 +print_with_otherflags(int ndigits, Elf *elf_file, unsigned int shstrndx,
     1193 +    SYM *sym_data, char *filename)
1210 1194  {
1211 1195          const char * const fmt_value_size[] = {
1212 1196                  "%*llu|%*lld|",         /* FMT_T_DEC */
1213 1197                  "0x%.*llx|0x%.*llx|",   /* FMT_T_HEX */
1214 1198                  "0%.*llo|0%.*llo|"      /* FMT_T_OCT */
1215 1199          };
1216 1200          const char * const fmt_int[] = {
1217 1201                  "%-5d",                 /* FMT_T_DEC */
1218 1202                  "%#-5x",                /* FMT_T_HEX */
1219 1203                  "%#-5o"                 /* FMT_T_OCT */
↓ open down ↓ 293 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX