8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1988 AT&T
24 * Copyright (c) 1989 AT&T
25 * All Rights Reserved
26 *
27 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
28 */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <ctype.h>
34 #include <locale.h>
35 #include <libelf.h>
36 #include <sys/elf_SPARC.h>
37
38
39 /* exit return codes */
40 #define NOARGS 1
41 #define BADELF 2
42 #define NOALLOC 3
43
44 #include <fcntl.h>
45 #include <sys/stat.h>
46 #include <errno.h>
47 #include <string.h>
788 Elf32_Word *symshndx = 0;
789 unsigned int nosymshndx = 0;
790 int i;
791
792 if ((buf = calloc(num, sizeof (SYM))) == NULL) {
793 (void) fprintf(stderr, gettext("%s: cannot allocate memory\n"),
794 prog_name);
795 return (NULL);
796 }
797
798 s = buf; /* save pointer to head of array */
799
800 for (i = 1; i < num; i++, buf++) {
801 (void) gelf_getsym(data, i, &sym);
802
803 buf->indx = i;
804 /* allow to work on machines where NULL-derefs dump core */
805 if (sym.st_name == 0)
806 buf->name = "";
807 else if (C_flag) {
808 const char *dn;
809 char *name = (char *)elf_strptr(elf, link, sym.st_name);
810 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 */
816 name = FormatName(name, dn);
817 }
818 buf->name = name;
819 }
820 else
821 buf->name = (char *)elf_strptr(elf, link, sym.st_name);
822
823 buf->value = sym.st_value;
824 buf->size = sym.st_size;
825 buf->type = GELF_ST_TYPE(sym.st_info);
826 buf->bind = GELF_ST_BIND(sym.st_info);
827 buf->other = sym.st_other;
828 if ((sym.st_shndx == SHN_XINDEX) &&
829 (symshndx == 0) && (nosymshndx == 0)) {
830 Elf_Scn *_scn;
831 GElf_Shdr _shdr;
832 _scn = 0;
833 while ((_scn = elf_nextscn(elf, _scn)) != 0) {
834 if (gelf_getshdr(_scn, &_shdr) == 0)
835 break;
836 if ((_shdr.sh_type == SHT_SYMTAB_SHNDX) &&
837 (_shdr.sh_link == symscnndx)) {
997 default:
998 return (0);
999 }
1000 default:
1001 return (0);
1002 }
1003 }
1004
1005 /*
1006 * If it comes here, any symbol can be printed.
1007 * (So basically, -f is no-op.)
1008 */
1009 return (1);
1010 }
1011
1012 #ifndef XPG4
1013 /*
1014 * -u flag specified
1015 */
1016 static void
1017 print_with_uflag(
1018 SYM *sym_data,
1019 char *filename
1020 )
1021 {
1022 if ((sym_data->shndx == SHN_UNDEF) && (strlen(sym_data->name))) {
1023 if (!r_flag) {
1024 if (R_flag) {
1025 if (archive_name != (char *)0)
1026 (void) printf(" %s:%s:%s\n",
1027 archive_name, filename,
1028 sym_data->name);
1029 else
1030 (void) printf(" %s:%s\n",
1031 filename, sym_data->name);
1032 }
1033 else
1034 (void) printf(" %s\n", sym_data->name);
1035 }
1036 else
1037 (void) printf(" %s:%s\n", filename, sym_data->name);
1038 }
1039 }
1040 #endif
1077 sym_key = lookup(sym_data->type, sym_data->bind);
1078 }
1079
1080 if (sym_key != NULL) {
1081 if (!l_flag)
1082 (void) printf("%c ", sym_key[0]);
1083 else
1084 (void) printf("%-3s", sym_key);
1085 } else {
1086 if (!l_flag)
1087 (void) printf("%-2d", sym_data->type);
1088 else
1089 (void) printf("%-3d", sym_data->type);
1090 }
1091 }
1092
1093 /*
1094 * -p flag specified
1095 */
1096 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 )
1104 {
1105 const char * const fmt[] = {
1106 "%.*llu ", /* FMT_T_DEC */
1107 "0x%.*llx ", /* FMT_T_HEX */
1108 "0%.*llo " /* FMT_T_OCT */
1109 };
1110
1111 if (is_sym_print(sym_data) != 1)
1112 return;
1113 /*
1114 * -A header
1115 */
1116 if (A_flag != 0)
1117 (void) printf("%s", A_header);
1118
1119 /*
1120 * Symbol Value.
1121 * (hex/octal/decimal)
1122 */
1123 (void) printf(fmt[fmt_flag], ndigits, EC_ADDR(sym_data->value));
1131 if (!r_flag) {
1132 if (R_flag) {
1133 if (archive_name != (char *)0)
1134 (void) printf("%s:%s:%s\n", archive_name,
1135 filename, sym_data->name);
1136 else
1137 (void) printf("%s:%s\n", filename,
1138 sym_data->name);
1139 }
1140 else
1141 (void) printf("%s\n", sym_data->name);
1142 }
1143 else
1144 (void) printf("%s:%s\n", filename, sym_data->name);
1145 }
1146
1147 /*
1148 * -P flag specified
1149 */
1150 static void
1151 print_with_Pflag(
1152 int ndigits,
1153 Elf *elf_file,
1154 unsigned int shstrndx,
1155 SYM *sym_data
1156 )
1157 {
1158 #define SYM_LEN 10
1159 char sym_name[SYM_LEN+1];
1160 size_t len;
1161 const char * const fmt[] = {
1162 "%*llu %*llu \n", /* FMT_T_DEC */
1163 "%*llx %*llx \n", /* FMT_T_HEX */
1164 "%*llo %*llo \n" /* FMT_T_OCT */
1165 };
1166
1167 if (is_sym_print(sym_data) != 1)
1168 return;
1169 /*
1170 * -A header
1171 */
1172 if (A_flag != 0)
1173 (void) printf("%s", A_header);
1174
1175 /*
1176 * Symbol name
1183 (void) printf("%s ", sym_name);
1184 }
1185
1186 /*
1187 * Symbol Type.
1188 */
1189 print_brief_sym_type(elf_file, shstrndx, sym_data);
1190
1191 /*
1192 * Symbol Value & size
1193 * (hex/octal/decimal)
1194 */
1195 (void) printf(fmt[fmt_flag], ndigits, EC_ADDR(sym_data->value),
1196 ndigits, EC_XWORD(sym_data->size));
1197 }
1198
1199 /*
1200 * other flags specified
1201 */
1202 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 )
1210 {
1211 const char * const fmt_value_size[] = {
1212 "%*llu|%*lld|", /* FMT_T_DEC */
1213 "0x%.*llx|0x%.*llx|", /* FMT_T_HEX */
1214 "0%.*llo|0%.*llo|" /* FMT_T_OCT */
1215 };
1216 const char * const fmt_int[] = {
1217 "%-5d", /* FMT_T_DEC */
1218 "%#-5x", /* FMT_T_HEX */
1219 "%#-5o" /* FMT_T_OCT */
1220 };
1221
1222 if (is_sym_print(sym_data) != 1)
1223 return;
1224 (void) printf("%s", A_header);
1225 (void) printf("[%d]\t|", sym_data->indx);
1226 (void) printf(fmt_value_size[fmt_flag], ndigits,
1227 EC_ADDR(sym_data->value), ndigits, EC_XWORD(sym_data->size));
1228
1229 switch (sym_data->type) {
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1988 AT&T
24 * Copyright (c) 1989 AT&T
25 * All Rights Reserved
26 *
27 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Copyright 2018 Jason King
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <ctype.h>
35 #include <locale.h>
36 #include <libelf.h>
37 #include <sys/elf_SPARC.h>
38
39
40 /* exit return codes */
41 #define NOARGS 1
42 #define BADELF 2
43 #define NOALLOC 3
44
45 #include <fcntl.h>
46 #include <sys/stat.h>
47 #include <errno.h>
48 #include <string.h>
789 Elf32_Word *symshndx = 0;
790 unsigned int nosymshndx = 0;
791 int i;
792
793 if ((buf = calloc(num, sizeof (SYM))) == NULL) {
794 (void) fprintf(stderr, gettext("%s: cannot allocate memory\n"),
795 prog_name);
796 return (NULL);
797 }
798
799 s = buf; /* save pointer to head of array */
800
801 for (i = 1; i < num; i++, buf++) {
802 (void) gelf_getsym(data, i, &sym);
803
804 buf->indx = i;
805 /* allow to work on machines where NULL-derefs dump core */
806 if (sym.st_name == 0)
807 buf->name = "";
808 else if (C_flag) {
809 const char *dn = NULL;
810 char *name = (char *)elf_strptr(elf, link, sym.st_name);
811
812 dn = conv_demangle_name(name);
813 if (dn != name) {
814 name = FormatName(name, dn);
815 free((void *)dn);
816 } else if (exotic(name)) {
817 name = FormatName(name, d_buf);
818 }
819 buf->name = name;
820 }
821 else
822 buf->name = (char *)elf_strptr(elf, link, sym.st_name);
823
824 buf->value = sym.st_value;
825 buf->size = sym.st_size;
826 buf->type = GELF_ST_TYPE(sym.st_info);
827 buf->bind = GELF_ST_BIND(sym.st_info);
828 buf->other = sym.st_other;
829 if ((sym.st_shndx == SHN_XINDEX) &&
830 (symshndx == 0) && (nosymshndx == 0)) {
831 Elf_Scn *_scn;
832 GElf_Shdr _shdr;
833 _scn = 0;
834 while ((_scn = elf_nextscn(elf, _scn)) != 0) {
835 if (gelf_getshdr(_scn, &_shdr) == 0)
836 break;
837 if ((_shdr.sh_type == SHT_SYMTAB_SHNDX) &&
838 (_shdr.sh_link == symscnndx)) {
998 default:
999 return (0);
1000 }
1001 default:
1002 return (0);
1003 }
1004 }
1005
1006 /*
1007 * If it comes here, any symbol can be printed.
1008 * (So basically, -f is no-op.)
1009 */
1010 return (1);
1011 }
1012
1013 #ifndef XPG4
1014 /*
1015 * -u flag specified
1016 */
1017 static void
1018 print_with_uflag(SYM *sym_data, char *filename)
1019 {
1020 if ((sym_data->shndx == SHN_UNDEF) && (strlen(sym_data->name))) {
1021 if (!r_flag) {
1022 if (R_flag) {
1023 if (archive_name != (char *)0)
1024 (void) printf(" %s:%s:%s\n",
1025 archive_name, filename,
1026 sym_data->name);
1027 else
1028 (void) printf(" %s:%s\n",
1029 filename, sym_data->name);
1030 }
1031 else
1032 (void) printf(" %s\n", sym_data->name);
1033 }
1034 else
1035 (void) printf(" %s:%s\n", filename, sym_data->name);
1036 }
1037 }
1038 #endif
1075 sym_key = lookup(sym_data->type, sym_data->bind);
1076 }
1077
1078 if (sym_key != NULL) {
1079 if (!l_flag)
1080 (void) printf("%c ", sym_key[0]);
1081 else
1082 (void) printf("%-3s", sym_key);
1083 } else {
1084 if (!l_flag)
1085 (void) printf("%-2d", sym_data->type);
1086 else
1087 (void) printf("%-3d", sym_data->type);
1088 }
1089 }
1090
1091 /*
1092 * -p flag specified
1093 */
1094 static void
1095 print_with_pflag(int ndigits, Elf *elf_file, unsigned int shstrndx,
1096 SYM *sym_data, char *filename)
1097 {
1098 const char * const fmt[] = {
1099 "%.*llu ", /* FMT_T_DEC */
1100 "0x%.*llx ", /* FMT_T_HEX */
1101 "0%.*llo " /* FMT_T_OCT */
1102 };
1103
1104 if (is_sym_print(sym_data) != 1)
1105 return;
1106 /*
1107 * -A header
1108 */
1109 if (A_flag != 0)
1110 (void) printf("%s", A_header);
1111
1112 /*
1113 * Symbol Value.
1114 * (hex/octal/decimal)
1115 */
1116 (void) printf(fmt[fmt_flag], ndigits, EC_ADDR(sym_data->value));
1124 if (!r_flag) {
1125 if (R_flag) {
1126 if (archive_name != (char *)0)
1127 (void) printf("%s:%s:%s\n", archive_name,
1128 filename, sym_data->name);
1129 else
1130 (void) printf("%s:%s\n", filename,
1131 sym_data->name);
1132 }
1133 else
1134 (void) printf("%s\n", sym_data->name);
1135 }
1136 else
1137 (void) printf("%s:%s\n", filename, sym_data->name);
1138 }
1139
1140 /*
1141 * -P flag specified
1142 */
1143 static void
1144 print_with_Pflag(int ndigits, Elf *elf_file, unsigned int shstrndx,
1145 SYM *sym_data)
1146 {
1147 #define SYM_LEN 10
1148 char sym_name[SYM_LEN+1];
1149 size_t len;
1150 const char * const fmt[] = {
1151 "%*llu %*llu \n", /* FMT_T_DEC */
1152 "%*llx %*llx \n", /* FMT_T_HEX */
1153 "%*llo %*llo \n" /* FMT_T_OCT */
1154 };
1155
1156 if (is_sym_print(sym_data) != 1)
1157 return;
1158 /*
1159 * -A header
1160 */
1161 if (A_flag != 0)
1162 (void) printf("%s", A_header);
1163
1164 /*
1165 * Symbol name
1172 (void) printf("%s ", sym_name);
1173 }
1174
1175 /*
1176 * Symbol Type.
1177 */
1178 print_brief_sym_type(elf_file, shstrndx, sym_data);
1179
1180 /*
1181 * Symbol Value & size
1182 * (hex/octal/decimal)
1183 */
1184 (void) printf(fmt[fmt_flag], ndigits, EC_ADDR(sym_data->value),
1185 ndigits, EC_XWORD(sym_data->size));
1186 }
1187
1188 /*
1189 * other flags specified
1190 */
1191 static void
1192 print_with_otherflags(int ndigits, Elf *elf_file, unsigned int shstrndx,
1193 SYM *sym_data, char *filename)
1194 {
1195 const char * const fmt_value_size[] = {
1196 "%*llu|%*lld|", /* FMT_T_DEC */
1197 "0x%.*llx|0x%.*llx|", /* FMT_T_HEX */
1198 "0%.*llo|0%.*llo|" /* FMT_T_OCT */
1199 };
1200 const char * const fmt_int[] = {
1201 "%-5d", /* FMT_T_DEC */
1202 "%#-5x", /* FMT_T_HEX */
1203 "%#-5o" /* FMT_T_OCT */
1204 };
1205
1206 if (is_sym_print(sym_data) != 1)
1207 return;
1208 (void) printf("%s", A_header);
1209 (void) printf("[%d]\t|", sym_data->indx);
1210 (void) printf(fmt_value_size[fmt_flag], ndigits,
1211 EC_ADDR(sym_data->value), ndigits, EC_XWORD(sym_data->size));
1212
1213 switch (sym_data->type) {
|