aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 739e5a32366a..2293a4a5af96 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1026,11 +1026,12 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1026{ 1026{
1027 char *name; 1027 char *name;
1028 int ret = -1; 1028 int ret = -1;
1029 struct symsrc ss;
1030 u_int i; 1029 u_int i;
1031 struct machine *machine; 1030 struct machine *machine;
1032 char *root_dir = (char *) ""; 1031 char *root_dir = (char *) "";
1033 int want_symtab; 1032 int ss_pos = 0;
1033 struct symsrc ss_[2];
1034 struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
1034 1035
1035 dso__set_loaded(dso, map->type); 1036 dso__set_loaded(dso, map->type);
1036 1037
@@ -1072,12 +1073,12 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1072 root_dir = machine->root_dir; 1073 root_dir = machine->root_dir;
1073 1074
1074 /* Iterate over candidate debug images. 1075 /* Iterate over candidate debug images.
1075 * On the first pass, only load images if they have a full symtab. 1076 * Keep track of "interesting" ones (those which have a symtab, dynsym,
1076 * Failing that, do a second pass where we accept .dynsym also 1077 * and/or opd section) for processing.
1077 */ 1078 */
1078 want_symtab = 1;
1079restart:
1080 for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) { 1079 for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
1080 struct symsrc *ss = &ss_[ss_pos];
1081 bool next_slot = false;
1081 1082
1082 enum dso_binary_type symtab_type = binary_type_symtab[i]; 1083 enum dso_binary_type symtab_type = binary_type_symtab[i];
1083 1084
@@ -1086,45 +1087,55 @@ restart:
1086 continue; 1087 continue;
1087 1088
1088 /* Name is now the name of the next image to try */ 1089 /* Name is now the name of the next image to try */
1089 if (symsrc__init(&ss, dso, name, symtab_type) < 0) 1090 if (symsrc__init(ss, dso, name, symtab_type) < 0)
1090 continue; 1091 continue;
1091 1092
1092 if (want_symtab && !symsrc__has_symtab(&ss)) { 1093 if (!syms_ss && symsrc__has_symtab(ss)) {
1093 symsrc__destroy(&ss); 1094 syms_ss = ss;
1094 continue; 1095 next_slot = true;
1095 } 1096 }
1096 1097
1097 ret = dso__load_sym(dso, map, &ss, &ss, filter, 0); 1098 if (!runtime_ss && symsrc__possibly_runtime(ss)) {
1098 1099 runtime_ss = ss;
1099 /* 1100 next_slot = true;
1100 * Some people seem to have debuginfo files _WITHOUT_ debug
1101 * info!?!?
1102 */
1103 if (!ret) {
1104 symsrc__destroy(&ss);
1105 continue;
1106 } 1101 }
1107 1102
1108 if (ret > 0) { 1103 if (next_slot) {
1109 int nr_plt; 1104 ss_pos++;
1110 1105
1111 nr_plt = dso__synthesize_plt_symbols(dso, &ss, map, filter); 1106 if (syms_ss && runtime_ss)
1112 if (nr_plt > 0) 1107 break;
1113 ret += nr_plt;
1114 symsrc__destroy(&ss);
1115 break;
1116 } 1108 }
1109
1117 } 1110 }
1118 1111
1119 /* 1112 if (!runtime_ss && !syms_ss)
1120 * If we wanted a full symtab but no image had one, 1113 goto out_free;
1121 * relax our requirements and repeat the search. 1114
1122 */ 1115 if (runtime_ss && !syms_ss) {
1123 if (ret <= 0 && want_symtab) { 1116 syms_ss = runtime_ss;
1124 want_symtab = 0; 1117 }
1125 goto restart; 1118
1119 /* We'll have to hope for the best */
1120 if (!runtime_ss && syms_ss)
1121 runtime_ss = syms_ss;
1122
1123 if (syms_ss)
1124 ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, 0);
1125 else
1126 ret = -1;
1127
1128 if (ret > 0 && runtime_ss->dynsym) {
1129 int nr_plt;
1130
1131 nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss, map, filter);
1132 if (nr_plt > 0)
1133 ret += nr_plt;
1126 } 1134 }
1127 1135
1136 for (; ss_pos > 0; ss_pos--)
1137 symsrc__destroy(&ss_[ss_pos - 1]);
1138out_free:
1128 free(name); 1139 free(name);
1129 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL) 1140 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1130 return 0; 1141 return 0;