diff options
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r-- | tools/perf/util/probe-finder.c | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 2be10fb27172..4ce5c5e18f48 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -686,8 +686,9 @@ static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
686 | pf->fb_ops = NULL; | 686 | pf->fb_ops = NULL; |
687 | #if _ELFUTILS_PREREQ(0, 142) | 687 | #if _ELFUTILS_PREREQ(0, 142) |
688 | } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && | 688 | } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && |
689 | pf->cfi != NULL) { | 689 | (pf->cfi_eh != NULL || pf->cfi_dbg != NULL)) { |
690 | if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 || | 690 | if ((dwarf_cfi_addrframe(pf->cfi_eh, pf->addr, &frame) != 0 && |
691 | (dwarf_cfi_addrframe(pf->cfi_dbg, pf->addr, &frame) != 0)) || | ||
691 | dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { | 692 | dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { |
692 | pr_warning("Failed to get call frame on 0x%jx\n", | 693 | pr_warning("Failed to get call frame on 0x%jx\n", |
693 | (uintmax_t)pf->addr); | 694 | (uintmax_t)pf->addr); |
@@ -1015,8 +1016,7 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data) | |||
1015 | return DWARF_CB_OK; | 1016 | return DWARF_CB_OK; |
1016 | } | 1017 | } |
1017 | 1018 | ||
1018 | /* Find probe points from debuginfo */ | 1019 | static int debuginfo__find_probe_location(struct debuginfo *dbg, |
1019 | static int debuginfo__find_probes(struct debuginfo *dbg, | ||
1020 | struct probe_finder *pf) | 1020 | struct probe_finder *pf) |
1021 | { | 1021 | { |
1022 | struct perf_probe_point *pp = &pf->pev->point; | 1022 | struct perf_probe_point *pp = &pf->pev->point; |
@@ -1025,27 +1025,6 @@ static int debuginfo__find_probes(struct debuginfo *dbg, | |||
1025 | Dwarf_Die *diep; | 1025 | Dwarf_Die *diep; |
1026 | int ret = 0; | 1026 | int ret = 0; |
1027 | 1027 | ||
1028 | #if _ELFUTILS_PREREQ(0, 142) | ||
1029 | Elf *elf; | ||
1030 | GElf_Ehdr ehdr; | ||
1031 | GElf_Shdr shdr; | ||
1032 | |||
1033 | /* Get the call frame information from this dwarf */ | ||
1034 | elf = dwarf_getelf(dbg->dbg); | ||
1035 | if (elf == NULL) | ||
1036 | return -EINVAL; | ||
1037 | |||
1038 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
1039 | return -EINVAL; | ||
1040 | |||
1041 | if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) && | ||
1042 | shdr.sh_type == SHT_PROGBITS) { | ||
1043 | pf->cfi = dwarf_getcfi_elf(elf); | ||
1044 | } else { | ||
1045 | pf->cfi = dwarf_getcfi(dbg->dbg); | ||
1046 | } | ||
1047 | #endif | ||
1048 | |||
1049 | off = 0; | 1028 | off = 0; |
1050 | pf->lcache = intlist__new(NULL); | 1029 | pf->lcache = intlist__new(NULL); |
1051 | if (!pf->lcache) | 1030 | if (!pf->lcache) |
@@ -1108,6 +1087,39 @@ found: | |||
1108 | return ret; | 1087 | return ret; |
1109 | } | 1088 | } |
1110 | 1089 | ||
1090 | /* Find probe points from debuginfo */ | ||
1091 | static int debuginfo__find_probes(struct debuginfo *dbg, | ||
1092 | struct probe_finder *pf) | ||
1093 | { | ||
1094 | int ret = 0; | ||
1095 | |||
1096 | #if _ELFUTILS_PREREQ(0, 142) | ||
1097 | Elf *elf; | ||
1098 | GElf_Ehdr ehdr; | ||
1099 | GElf_Shdr shdr; | ||
1100 | |||
1101 | if (pf->cfi_eh || pf->cfi_dbg) | ||
1102 | return debuginfo__find_probe_location(dbg, pf); | ||
1103 | |||
1104 | /* Get the call frame information from this dwarf */ | ||
1105 | elf = dwarf_getelf(dbg->dbg); | ||
1106 | if (elf == NULL) | ||
1107 | return -EINVAL; | ||
1108 | |||
1109 | if (gelf_getehdr(elf, &ehdr) == NULL) | ||
1110 | return -EINVAL; | ||
1111 | |||
1112 | if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) && | ||
1113 | shdr.sh_type == SHT_PROGBITS) | ||
1114 | pf->cfi_eh = dwarf_getcfi_elf(elf); | ||
1115 | |||
1116 | pf->cfi_dbg = dwarf_getcfi(dbg->dbg); | ||
1117 | #endif | ||
1118 | |||
1119 | ret = debuginfo__find_probe_location(dbg, pf); | ||
1120 | return ret; | ||
1121 | } | ||
1122 | |||
1111 | struct local_vars_finder { | 1123 | struct local_vars_finder { |
1112 | struct probe_finder *pf; | 1124 | struct probe_finder *pf; |
1113 | struct perf_probe_arg *args; | 1125 | struct perf_probe_arg *args; |