aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorCody P Schafer <cody@linux.vnet.ibm.com>2012-08-10 18:23:02 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-08-13 13:46:55 -0400
commit3aafe5ae08f2aed378e06d78b207883879d25cbe (patch)
treecf1eeeefb542e6abe0d52346193a5d64f3dce4f2 /tools
parent261360b6e90a782f0a63d8f61a67683c376c88cf (diff)
perf symbols: Use both runtime and debug images
We keep both a 'runtime' elf image as well as a 'debug' elf image around and generate symbols by looking at both of these. This eliminates the need for the want_symtab/goto restart mechanism combined with iterating over and reopening the elf images a second time. Also give dso__synthsize_plt_symbols() the runtime image (which has dynsyms) instead of the symbol image (which may only have a symtab and no dynsyms). Previously if a debug image was found all runtime images were ignored. This fixes 2 issues: - Symbol resolution to failure on PowerPC systems with debug symbols installed, as the debug images lack a '.opd' section which contains function descriptors. - On all archs, plt synthesis failed when a debug image was loaded and that debug image lacks a dynsym section while a runtime image has a dynsym section. Assumptions: - If a .opd section exists, it is contained in the highest priority image with a dynsym section. - This generally implies that the debug image lacks a dynsym section (ie: it is marked as NO_BITS). Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com> Cc: David Hansen <dave@linux.vnet.ibm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Matt Hellsley <matthltc@us.ibm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/1344637382-22789-17-git-send-email-cody@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/symbol-elf.c5
-rw-r--r--tools/perf/util/symbol-minimal.c6
-rw-r--r--tools/perf/util/symbol.c77
-rw-r--r--tools/perf/util/symbol.h1
4 files changed, 56 insertions, 33 deletions
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 36e4a458e7a1..5b37e13f08fb 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -525,6 +525,11 @@ static int dso__swap_init(struct dso *dso, unsigned char eidata)
525 return 0; 525 return 0;
526} 526}
527 527
528bool symsrc__possibly_runtime(struct symsrc *ss)
529{
530 return ss->dynsym || ss->opdsec;
531}
532
528bool symsrc__has_symtab(struct symsrc *ss) 533bool symsrc__has_symtab(struct symsrc *ss)
529{ 534{
530 return ss->symtab != NULL; 535 return ss->symtab != NULL;
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index 7747ea6d7e97..6738ea128c90 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -260,6 +260,12 @@ out_close:
260 return -1; 260 return -1;
261} 261}
262 262
263bool symsrc__possibly_runtime(struct symsrc *ss __used)
264{
265 /* Assume all sym sources could be a runtime image. */
266 return true;
267}
268
263bool symsrc__has_symtab(struct symsrc *ss __used) 269bool symsrc__has_symtab(struct symsrc *ss __used)
264{ 270{
265 return false; 271 return false;
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;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 1f3eed21f35d..fc4b1e630fd9 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -253,6 +253,7 @@ void symsrc__destroy(struct symsrc *ss);
253int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, 253int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
254 enum dso_binary_type type); 254 enum dso_binary_type type);
255bool symsrc__has_symtab(struct symsrc *ss); 255bool symsrc__has_symtab(struct symsrc *ss);
256bool symsrc__possibly_runtime(struct symsrc *ss);
256 257
257#define DSO__SWAP(dso, type, val) \ 258#define DSO__SWAP(dso, type, val) \
258({ \ 259({ \