diff options
-rw-r--r-- | tools/perf/builtin-probe.c | 1 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 135 | ||||
-rw-r--r-- | tools/perf/util/probe-event.h | 27 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 34 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.h | 10 |
5 files changed, 101 insertions, 106 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 54551867e7e0..199d5e19554f 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -267,4 +267,3 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) | |||
267 | } | 267 | } |
268 | return 0; | 268 | return 0; |
269 | } | 269 | } |
270 | |||
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 4445a1e7052f..2e665cb84055 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * probe-event.c : perf-probe definition to kprobe_events format converter | 2 | * probe-event.c : perf-probe definition to probe_events format converter |
3 | * | 3 | * |
4 | * Written by Masami Hiramatsu <mhiramat@redhat.com> | 4 | * Written by Masami Hiramatsu <mhiramat@redhat.com> |
5 | * | 5 | * |
@@ -120,8 +120,11 @@ static int open_vmlinux(void) | |||
120 | return open(machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name, O_RDONLY); | 120 | return open(machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name, O_RDONLY); |
121 | } | 121 | } |
122 | 122 | ||
123 | /* Convert trace point to probe point with debuginfo */ | 123 | /* |
124 | static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, | 124 | * Convert trace point to probe point with debuginfo |
125 | * Currently only handles kprobes. | ||
126 | */ | ||
127 | static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, | ||
125 | struct perf_probe_point *pp) | 128 | struct perf_probe_point *pp) |
126 | { | 129 | { |
127 | struct symbol *sym; | 130 | struct symbol *sym; |
@@ -151,8 +154,8 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, | |||
151 | } | 154 | } |
152 | 155 | ||
153 | /* Try to find perf_probe_event with debuginfo */ | 156 | /* Try to find perf_probe_event with debuginfo */ |
154 | static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, | 157 | static int try_to_find_probe_trace_events(struct perf_probe_event *pev, |
155 | struct kprobe_trace_event **tevs, | 158 | struct probe_trace_event **tevs, |
156 | int max_tevs) | 159 | int max_tevs) |
157 | { | 160 | { |
158 | bool need_dwarf = perf_probe_event_need_dwarf(pev); | 161 | bool need_dwarf = perf_probe_event_need_dwarf(pev); |
@@ -169,11 +172,11 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, | |||
169 | } | 172 | } |
170 | 173 | ||
171 | /* Searching trace events corresponding to probe event */ | 174 | /* Searching trace events corresponding to probe event */ |
172 | ntevs = find_kprobe_trace_events(fd, pev, tevs, max_tevs); | 175 | ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs); |
173 | close(fd); | 176 | close(fd); |
174 | 177 | ||
175 | if (ntevs > 0) { /* Succeeded to find trace events */ | 178 | if (ntevs > 0) { /* Succeeded to find trace events */ |
176 | pr_debug("find %d kprobe_trace_events.\n", ntevs); | 179 | pr_debug("find %d probe_trace_events.\n", ntevs); |
177 | return ntevs; | 180 | return ntevs; |
178 | } | 181 | } |
179 | 182 | ||
@@ -377,8 +380,8 @@ end: | |||
377 | 380 | ||
378 | #else /* !DWARF_SUPPORT */ | 381 | #else /* !DWARF_SUPPORT */ |
379 | 382 | ||
380 | static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, | 383 | static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, |
381 | struct perf_probe_point *pp) | 384 | struct perf_probe_point *pp) |
382 | { | 385 | { |
383 | pp->function = strdup(tp->symbol); | 386 | pp->function = strdup(tp->symbol); |
384 | if (pp->function == NULL) | 387 | if (pp->function == NULL) |
@@ -389,8 +392,8 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp, | |||
389 | return 0; | 392 | return 0; |
390 | } | 393 | } |
391 | 394 | ||
392 | static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, | 395 | static int try_to_find_probe_trace_events(struct perf_probe_event *pev, |
393 | struct kprobe_trace_event **tevs __unused, | 396 | struct probe_trace_event **tevs __unused, |
394 | int max_tevs __unused) | 397 | int max_tevs __unused) |
395 | { | 398 | { |
396 | if (perf_probe_event_need_dwarf(pev)) { | 399 | if (perf_probe_event_need_dwarf(pev)) { |
@@ -781,16 +784,17 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev) | |||
781 | return false; | 784 | return false; |
782 | } | 785 | } |
783 | 786 | ||
784 | /* Parse kprobe_events event into struct probe_point */ | 787 | /* Parse probe_events event into struct probe_point */ |
785 | int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev) | 788 | static int parse_probe_trace_command(const char *cmd, |
789 | struct probe_trace_event *tev) | ||
786 | { | 790 | { |
787 | struct kprobe_trace_point *tp = &tev->point; | 791 | struct probe_trace_point *tp = &tev->point; |
788 | char pr; | 792 | char pr; |
789 | char *p; | 793 | char *p; |
790 | int ret, i, argc; | 794 | int ret, i, argc; |
791 | char **argv; | 795 | char **argv; |
792 | 796 | ||
793 | pr_debug("Parsing kprobe_events: %s\n", cmd); | 797 | pr_debug("Parsing probe_events: %s\n", cmd); |
794 | argv = argv_split(cmd, &argc); | 798 | argv = argv_split(cmd, &argc); |
795 | if (!argv) { | 799 | if (!argv) { |
796 | pr_debug("Failed to split arguments.\n"); | 800 | pr_debug("Failed to split arguments.\n"); |
@@ -822,7 +826,7 @@ int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev) | |||
822 | tp->offset = 0; | 826 | tp->offset = 0; |
823 | 827 | ||
824 | tev->nargs = argc - 2; | 828 | tev->nargs = argc - 2; |
825 | tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs); | 829 | tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); |
826 | if (tev->args == NULL) { | 830 | if (tev->args == NULL) { |
827 | ret = -ENOMEM; | 831 | ret = -ENOMEM; |
828 | goto out; | 832 | goto out; |
@@ -968,13 +972,13 @@ char *synthesize_perf_probe_command(struct perf_probe_event *pev) | |||
968 | } | 972 | } |
969 | #endif | 973 | #endif |
970 | 974 | ||
971 | static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref, | 975 | static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref, |
972 | char **buf, size_t *buflen, | 976 | char **buf, size_t *buflen, |
973 | int depth) | 977 | int depth) |
974 | { | 978 | { |
975 | int ret; | 979 | int ret; |
976 | if (ref->next) { | 980 | if (ref->next) { |
977 | depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf, | 981 | depth = __synthesize_probe_trace_arg_ref(ref->next, buf, |
978 | buflen, depth + 1); | 982 | buflen, depth + 1); |
979 | if (depth < 0) | 983 | if (depth < 0) |
980 | goto out; | 984 | goto out; |
@@ -992,10 +996,10 @@ out: | |||
992 | 996 | ||
993 | } | 997 | } |
994 | 998 | ||
995 | static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg, | 999 | static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, |
996 | char *buf, size_t buflen) | 1000 | char *buf, size_t buflen) |
997 | { | 1001 | { |
998 | struct kprobe_trace_arg_ref *ref = arg->ref; | 1002 | struct probe_trace_arg_ref *ref = arg->ref; |
999 | int ret, depth = 0; | 1003 | int ret, depth = 0; |
1000 | char *tmp = buf; | 1004 | char *tmp = buf; |
1001 | 1005 | ||
@@ -1015,7 +1019,7 @@ static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg, | |||
1015 | 1019 | ||
1016 | /* Dereferencing arguments */ | 1020 | /* Dereferencing arguments */ |
1017 | if (ref) { | 1021 | if (ref) { |
1018 | depth = __synthesize_kprobe_trace_arg_ref(ref, &buf, | 1022 | depth = __synthesize_probe_trace_arg_ref(ref, &buf, |
1019 | &buflen, 1); | 1023 | &buflen, 1); |
1020 | if (depth < 0) | 1024 | if (depth < 0) |
1021 | return depth; | 1025 | return depth; |
@@ -1051,9 +1055,9 @@ static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg, | |||
1051 | return buf - tmp; | 1055 | return buf - tmp; |
1052 | } | 1056 | } |
1053 | 1057 | ||
1054 | char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev) | 1058 | char *synthesize_probe_trace_command(struct probe_trace_event *tev) |
1055 | { | 1059 | { |
1056 | struct kprobe_trace_point *tp = &tev->point; | 1060 | struct probe_trace_point *tp = &tev->point; |
1057 | char *buf; | 1061 | char *buf; |
1058 | int i, len, ret; | 1062 | int i, len, ret; |
1059 | 1063 | ||
@@ -1069,7 +1073,7 @@ char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev) | |||
1069 | goto error; | 1073 | goto error; |
1070 | 1074 | ||
1071 | for (i = 0; i < tev->nargs; i++) { | 1075 | for (i = 0; i < tev->nargs; i++) { |
1072 | ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len, | 1076 | ret = synthesize_probe_trace_arg(&tev->args[i], buf + len, |
1073 | MAX_CMDLEN - len); | 1077 | MAX_CMDLEN - len); |
1074 | if (ret <= 0) | 1078 | if (ret <= 0) |
1075 | goto error; | 1079 | goto error; |
@@ -1082,7 +1086,7 @@ error: | |||
1082 | return NULL; | 1086 | return NULL; |
1083 | } | 1087 | } |
1084 | 1088 | ||
1085 | int convert_to_perf_probe_event(struct kprobe_trace_event *tev, | 1089 | static int convert_to_perf_probe_event(struct probe_trace_event *tev, |
1086 | struct perf_probe_event *pev) | 1090 | struct perf_probe_event *pev) |
1087 | { | 1091 | { |
1088 | char buf[64] = ""; | 1092 | char buf[64] = ""; |
@@ -1095,7 +1099,7 @@ int convert_to_perf_probe_event(struct kprobe_trace_event *tev, | |||
1095 | return -ENOMEM; | 1099 | return -ENOMEM; |
1096 | 1100 | ||
1097 | /* Convert trace_point to probe_point */ | 1101 | /* Convert trace_point to probe_point */ |
1098 | ret = convert_to_perf_probe_point(&tev->point, &pev->point); | 1102 | ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point); |
1099 | if (ret < 0) | 1103 | if (ret < 0) |
1100 | return ret; | 1104 | return ret; |
1101 | 1105 | ||
@@ -1108,7 +1112,7 @@ int convert_to_perf_probe_event(struct kprobe_trace_event *tev, | |||
1108 | if (tev->args[i].name) | 1112 | if (tev->args[i].name) |
1109 | pev->args[i].name = strdup(tev->args[i].name); | 1113 | pev->args[i].name = strdup(tev->args[i].name); |
1110 | else { | 1114 | else { |
1111 | ret = synthesize_kprobe_trace_arg(&tev->args[i], | 1115 | ret = synthesize_probe_trace_arg(&tev->args[i], |
1112 | buf, 64); | 1116 | buf, 64); |
1113 | pev->args[i].name = strdup(buf); | 1117 | pev->args[i].name = strdup(buf); |
1114 | } | 1118 | } |
@@ -1159,9 +1163,9 @@ void clear_perf_probe_event(struct perf_probe_event *pev) | |||
1159 | memset(pev, 0, sizeof(*pev)); | 1163 | memset(pev, 0, sizeof(*pev)); |
1160 | } | 1164 | } |
1161 | 1165 | ||
1162 | void clear_kprobe_trace_event(struct kprobe_trace_event *tev) | 1166 | static void clear_probe_trace_event(struct probe_trace_event *tev) |
1163 | { | 1167 | { |
1164 | struct kprobe_trace_arg_ref *ref, *next; | 1168 | struct probe_trace_arg_ref *ref, *next; |
1165 | int i; | 1169 | int i; |
1166 | 1170 | ||
1167 | if (tev->event) | 1171 | if (tev->event) |
@@ -1222,7 +1226,7 @@ static int open_kprobe_events(bool readwrite) | |||
1222 | } | 1226 | } |
1223 | 1227 | ||
1224 | /* Get raw string list of current kprobe_events */ | 1228 | /* Get raw string list of current kprobe_events */ |
1225 | static struct strlist *get_kprobe_trace_command_rawlist(int fd) | 1229 | static struct strlist *get_probe_trace_command_rawlist(int fd) |
1226 | { | 1230 | { |
1227 | int ret, idx; | 1231 | int ret, idx; |
1228 | FILE *fp; | 1232 | FILE *fp; |
@@ -1290,7 +1294,7 @@ static int show_perf_probe_event(struct perf_probe_event *pev) | |||
1290 | int show_perf_probe_events(void) | 1294 | int show_perf_probe_events(void) |
1291 | { | 1295 | { |
1292 | int fd, ret; | 1296 | int fd, ret; |
1293 | struct kprobe_trace_event tev; | 1297 | struct probe_trace_event tev; |
1294 | struct perf_probe_event pev; | 1298 | struct perf_probe_event pev; |
1295 | struct strlist *rawlist; | 1299 | struct strlist *rawlist; |
1296 | struct str_node *ent; | 1300 | struct str_node *ent; |
@@ -1307,20 +1311,20 @@ int show_perf_probe_events(void) | |||
1307 | if (fd < 0) | 1311 | if (fd < 0) |
1308 | return fd; | 1312 | return fd; |
1309 | 1313 | ||
1310 | rawlist = get_kprobe_trace_command_rawlist(fd); | 1314 | rawlist = get_probe_trace_command_rawlist(fd); |
1311 | close(fd); | 1315 | close(fd); |
1312 | if (!rawlist) | 1316 | if (!rawlist) |
1313 | return -ENOENT; | 1317 | return -ENOENT; |
1314 | 1318 | ||
1315 | strlist__for_each(ent, rawlist) { | 1319 | strlist__for_each(ent, rawlist) { |
1316 | ret = parse_kprobe_trace_command(ent->s, &tev); | 1320 | ret = parse_probe_trace_command(ent->s, &tev); |
1317 | if (ret >= 0) { | 1321 | if (ret >= 0) { |
1318 | ret = convert_to_perf_probe_event(&tev, &pev); | 1322 | ret = convert_to_perf_probe_event(&tev, &pev); |
1319 | if (ret >= 0) | 1323 | if (ret >= 0) |
1320 | ret = show_perf_probe_event(&pev); | 1324 | ret = show_perf_probe_event(&pev); |
1321 | } | 1325 | } |
1322 | clear_perf_probe_event(&pev); | 1326 | clear_perf_probe_event(&pev); |
1323 | clear_kprobe_trace_event(&tev); | 1327 | clear_probe_trace_event(&tev); |
1324 | if (ret < 0) | 1328 | if (ret < 0) |
1325 | break; | 1329 | break; |
1326 | } | 1330 | } |
@@ -1330,20 +1334,19 @@ int show_perf_probe_events(void) | |||
1330 | } | 1334 | } |
1331 | 1335 | ||
1332 | /* Get current perf-probe event names */ | 1336 | /* Get current perf-probe event names */ |
1333 | static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group) | 1337 | static struct strlist *get_probe_trace_event_names(int fd, bool include_group) |
1334 | { | 1338 | { |
1335 | char buf[128]; | 1339 | char buf[128]; |
1336 | struct strlist *sl, *rawlist; | 1340 | struct strlist *sl, *rawlist; |
1337 | struct str_node *ent; | 1341 | struct str_node *ent; |
1338 | struct kprobe_trace_event tev; | 1342 | struct probe_trace_event tev; |
1339 | int ret = 0; | 1343 | int ret = 0; |
1340 | 1344 | ||
1341 | memset(&tev, 0, sizeof(tev)); | 1345 | memset(&tev, 0, sizeof(tev)); |
1342 | 1346 | rawlist = get_probe_trace_command_rawlist(fd); | |
1343 | rawlist = get_kprobe_trace_command_rawlist(fd); | ||
1344 | sl = strlist__new(true, NULL); | 1347 | sl = strlist__new(true, NULL); |
1345 | strlist__for_each(ent, rawlist) { | 1348 | strlist__for_each(ent, rawlist) { |
1346 | ret = parse_kprobe_trace_command(ent->s, &tev); | 1349 | ret = parse_probe_trace_command(ent->s, &tev); |
1347 | if (ret < 0) | 1350 | if (ret < 0) |
1348 | break; | 1351 | break; |
1349 | if (include_group) { | 1352 | if (include_group) { |
@@ -1353,7 +1356,7 @@ static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group) | |||
1353 | ret = strlist__add(sl, buf); | 1356 | ret = strlist__add(sl, buf); |
1354 | } else | 1357 | } else |
1355 | ret = strlist__add(sl, tev.event); | 1358 | ret = strlist__add(sl, tev.event); |
1356 | clear_kprobe_trace_event(&tev); | 1359 | clear_probe_trace_event(&tev); |
1357 | if (ret < 0) | 1360 | if (ret < 0) |
1358 | break; | 1361 | break; |
1359 | } | 1362 | } |
@@ -1366,13 +1369,13 @@ static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group) | |||
1366 | return sl; | 1369 | return sl; |
1367 | } | 1370 | } |
1368 | 1371 | ||
1369 | static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev) | 1372 | static int write_probe_trace_event(int fd, struct probe_trace_event *tev) |
1370 | { | 1373 | { |
1371 | int ret = 0; | 1374 | int ret = 0; |
1372 | char *buf = synthesize_kprobe_trace_command(tev); | 1375 | char *buf = synthesize_probe_trace_command(tev); |
1373 | 1376 | ||
1374 | if (!buf) { | 1377 | if (!buf) { |
1375 | pr_debug("Failed to synthesize kprobe trace event.\n"); | 1378 | pr_debug("Failed to synthesize probe trace event.\n"); |
1376 | return -EINVAL; | 1379 | return -EINVAL; |
1377 | } | 1380 | } |
1378 | 1381 | ||
@@ -1425,12 +1428,12 @@ static int get_new_event_name(char *buf, size_t len, const char *base, | |||
1425 | return ret; | 1428 | return ret; |
1426 | } | 1429 | } |
1427 | 1430 | ||
1428 | static int __add_kprobe_trace_events(struct perf_probe_event *pev, | 1431 | static int __add_probe_trace_events(struct perf_probe_event *pev, |
1429 | struct kprobe_trace_event *tevs, | 1432 | struct probe_trace_event *tevs, |
1430 | int ntevs, bool allow_suffix) | 1433 | int ntevs, bool allow_suffix) |
1431 | { | 1434 | { |
1432 | int i, fd, ret; | 1435 | int i, fd, ret; |
1433 | struct kprobe_trace_event *tev = NULL; | 1436 | struct probe_trace_event *tev = NULL; |
1434 | char buf[64]; | 1437 | char buf[64]; |
1435 | const char *event, *group; | 1438 | const char *event, *group; |
1436 | struct strlist *namelist; | 1439 | struct strlist *namelist; |
@@ -1439,7 +1442,7 @@ static int __add_kprobe_trace_events(struct perf_probe_event *pev, | |||
1439 | if (fd < 0) | 1442 | if (fd < 0) |
1440 | return fd; | 1443 | return fd; |
1441 | /* Get current event names */ | 1444 | /* Get current event names */ |
1442 | namelist = get_kprobe_trace_event_names(fd, false); | 1445 | namelist = get_probe_trace_event_names(fd, false); |
1443 | if (!namelist) { | 1446 | if (!namelist) { |
1444 | pr_debug("Failed to get current event list.\n"); | 1447 | pr_debug("Failed to get current event list.\n"); |
1445 | return -EIO; | 1448 | return -EIO; |
@@ -1474,7 +1477,7 @@ static int __add_kprobe_trace_events(struct perf_probe_event *pev, | |||
1474 | ret = -ENOMEM; | 1477 | ret = -ENOMEM; |
1475 | break; | 1478 | break; |
1476 | } | 1479 | } |
1477 | ret = write_kprobe_trace_event(fd, tev); | 1480 | ret = write_probe_trace_event(fd, tev); |
1478 | if (ret < 0) | 1481 | if (ret < 0) |
1479 | break; | 1482 | break; |
1480 | /* Add added event name to namelist */ | 1483 | /* Add added event name to namelist */ |
@@ -1511,21 +1514,21 @@ static int __add_kprobe_trace_events(struct perf_probe_event *pev, | |||
1511 | return ret; | 1514 | return ret; |
1512 | } | 1515 | } |
1513 | 1516 | ||
1514 | static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, | 1517 | static int convert_to_probe_trace_events(struct perf_probe_event *pev, |
1515 | struct kprobe_trace_event **tevs, | 1518 | struct probe_trace_event **tevs, |
1516 | int max_tevs) | 1519 | int max_tevs) |
1517 | { | 1520 | { |
1518 | struct symbol *sym; | 1521 | struct symbol *sym; |
1519 | int ret = 0, i; | 1522 | int ret = 0, i; |
1520 | struct kprobe_trace_event *tev; | 1523 | struct probe_trace_event *tev; |
1521 | 1524 | ||
1522 | /* Convert perf_probe_event with debuginfo */ | 1525 | /* Convert perf_probe_event with debuginfo */ |
1523 | ret = try_to_find_kprobe_trace_events(pev, tevs, max_tevs); | 1526 | ret = try_to_find_probe_trace_events(pev, tevs, max_tevs); |
1524 | if (ret != 0) | 1527 | if (ret != 0) |
1525 | return ret; | 1528 | return ret; |
1526 | 1529 | ||
1527 | /* Allocate trace event buffer */ | 1530 | /* Allocate trace event buffer */ |
1528 | tev = *tevs = zalloc(sizeof(struct kprobe_trace_event)); | 1531 | tev = *tevs = zalloc(sizeof(struct probe_trace_event)); |
1529 | if (tev == NULL) | 1532 | if (tev == NULL) |
1530 | return -ENOMEM; | 1533 | return -ENOMEM; |
1531 | 1534 | ||
@@ -1538,7 +1541,7 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, | |||
1538 | tev->point.offset = pev->point.offset; | 1541 | tev->point.offset = pev->point.offset; |
1539 | tev->nargs = pev->nargs; | 1542 | tev->nargs = pev->nargs; |
1540 | if (tev->nargs) { | 1543 | if (tev->nargs) { |
1541 | tev->args = zalloc(sizeof(struct kprobe_trace_arg) | 1544 | tev->args = zalloc(sizeof(struct probe_trace_arg) |
1542 | * tev->nargs); | 1545 | * tev->nargs); |
1543 | if (tev->args == NULL) { | 1546 | if (tev->args == NULL) { |
1544 | ret = -ENOMEM; | 1547 | ret = -ENOMEM; |
@@ -1579,7 +1582,7 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, | |||
1579 | 1582 | ||
1580 | return 1; | 1583 | return 1; |
1581 | error: | 1584 | error: |
1582 | clear_kprobe_trace_event(tev); | 1585 | clear_probe_trace_event(tev); |
1583 | free(tev); | 1586 | free(tev); |
1584 | *tevs = NULL; | 1587 | *tevs = NULL; |
1585 | return ret; | 1588 | return ret; |
@@ -1587,7 +1590,7 @@ error: | |||
1587 | 1590 | ||
1588 | struct __event_package { | 1591 | struct __event_package { |
1589 | struct perf_probe_event *pev; | 1592 | struct perf_probe_event *pev; |
1590 | struct kprobe_trace_event *tevs; | 1593 | struct probe_trace_event *tevs; |
1591 | int ntevs; | 1594 | int ntevs; |
1592 | }; | 1595 | }; |
1593 | 1596 | ||
@@ -1610,7 +1613,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | |||
1610 | for (i = 0; i < npevs; i++) { | 1613 | for (i = 0; i < npevs; i++) { |
1611 | pkgs[i].pev = &pevs[i]; | 1614 | pkgs[i].pev = &pevs[i]; |
1612 | /* Convert with or without debuginfo */ | 1615 | /* Convert with or without debuginfo */ |
1613 | ret = convert_to_kprobe_trace_events(pkgs[i].pev, | 1616 | ret = convert_to_probe_trace_events(pkgs[i].pev, |
1614 | &pkgs[i].tevs, max_tevs); | 1617 | &pkgs[i].tevs, max_tevs); |
1615 | if (ret < 0) | 1618 | if (ret < 0) |
1616 | goto end; | 1619 | goto end; |
@@ -1619,24 +1622,24 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | |||
1619 | 1622 | ||
1620 | /* Loop 2: add all events */ | 1623 | /* Loop 2: add all events */ |
1621 | for (i = 0; i < npevs && ret >= 0; i++) | 1624 | for (i = 0; i < npevs && ret >= 0; i++) |
1622 | ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs, | 1625 | ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs, |
1623 | pkgs[i].ntevs, force_add); | 1626 | pkgs[i].ntevs, force_add); |
1624 | end: | 1627 | end: |
1625 | /* Loop 3: cleanup trace events */ | 1628 | /* Loop 3: cleanup trace events */ |
1626 | for (i = 0; i < npevs; i++) | 1629 | for (i = 0; i < npevs; i++) |
1627 | for (j = 0; j < pkgs[i].ntevs; j++) | 1630 | for (j = 0; j < pkgs[i].ntevs; j++) |
1628 | clear_kprobe_trace_event(&pkgs[i].tevs[j]); | 1631 | clear_probe_trace_event(&pkgs[i].tevs[j]); |
1629 | 1632 | ||
1630 | return ret; | 1633 | return ret; |
1631 | } | 1634 | } |
1632 | 1635 | ||
1633 | static int __del_trace_kprobe_event(int fd, struct str_node *ent) | 1636 | static int __del_trace_probe_event(int fd, struct str_node *ent) |
1634 | { | 1637 | { |
1635 | char *p; | 1638 | char *p; |
1636 | char buf[128]; | 1639 | char buf[128]; |
1637 | int ret; | 1640 | int ret; |
1638 | 1641 | ||
1639 | /* Convert from perf-probe event to trace-kprobe event */ | 1642 | /* Convert from perf-probe event to trace-probe event */ |
1640 | ret = e_snprintf(buf, 128, "-:%s", ent->s); | 1643 | ret = e_snprintf(buf, 128, "-:%s", ent->s); |
1641 | if (ret < 0) | 1644 | if (ret < 0) |
1642 | goto error; | 1645 | goto error; |
@@ -1662,7 +1665,7 @@ error: | |||
1662 | return ret; | 1665 | return ret; |
1663 | } | 1666 | } |
1664 | 1667 | ||
1665 | static int del_trace_kprobe_event(int fd, const char *group, | 1668 | static int del_trace_probe_event(int fd, const char *group, |
1666 | const char *event, struct strlist *namelist) | 1669 | const char *event, struct strlist *namelist) |
1667 | { | 1670 | { |
1668 | char buf[128]; | 1671 | char buf[128]; |
@@ -1679,7 +1682,7 @@ static int del_trace_kprobe_event(int fd, const char *group, | |||
1679 | strlist__for_each_safe(ent, n, namelist) | 1682 | strlist__for_each_safe(ent, n, namelist) |
1680 | if (strglobmatch(ent->s, buf)) { | 1683 | if (strglobmatch(ent->s, buf)) { |
1681 | found++; | 1684 | found++; |
1682 | ret = __del_trace_kprobe_event(fd, ent); | 1685 | ret = __del_trace_probe_event(fd, ent); |
1683 | if (ret < 0) | 1686 | if (ret < 0) |
1684 | break; | 1687 | break; |
1685 | strlist__remove(namelist, ent); | 1688 | strlist__remove(namelist, ent); |
@@ -1688,7 +1691,7 @@ static int del_trace_kprobe_event(int fd, const char *group, | |||
1688 | ent = strlist__find(namelist, buf); | 1691 | ent = strlist__find(namelist, buf); |
1689 | if (ent) { | 1692 | if (ent) { |
1690 | found++; | 1693 | found++; |
1691 | ret = __del_trace_kprobe_event(fd, ent); | 1694 | ret = __del_trace_probe_event(fd, ent); |
1692 | if (ret >= 0) | 1695 | if (ret >= 0) |
1693 | strlist__remove(namelist, ent); | 1696 | strlist__remove(namelist, ent); |
1694 | } | 1697 | } |
@@ -1712,7 +1715,7 @@ int del_perf_probe_events(struct strlist *dellist) | |||
1712 | return fd; | 1715 | return fd; |
1713 | 1716 | ||
1714 | /* Get current event names */ | 1717 | /* Get current event names */ |
1715 | namelist = get_kprobe_trace_event_names(fd, true); | 1718 | namelist = get_probe_trace_event_names(fd, true); |
1716 | if (namelist == NULL) | 1719 | if (namelist == NULL) |
1717 | return -EINVAL; | 1720 | return -EINVAL; |
1718 | 1721 | ||
@@ -1733,7 +1736,7 @@ int del_perf_probe_events(struct strlist *dellist) | |||
1733 | event = str; | 1736 | event = str; |
1734 | } | 1737 | } |
1735 | pr_debug("Group: %s, Event: %s\n", group, event); | 1738 | pr_debug("Group: %s, Event: %s\n", group, event); |
1736 | ret = del_trace_kprobe_event(fd, group, event, namelist); | 1739 | ret = del_trace_probe_event(fd, group, event, namelist); |
1737 | free(str); | 1740 | free(str); |
1738 | if (ret < 0) | 1741 | if (ret < 0) |
1739 | break; | 1742 | break; |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index ed362acff4b6..5af39243a25b 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
@@ -7,33 +7,33 @@ | |||
7 | extern bool probe_event_dry_run; | 7 | extern bool probe_event_dry_run; |
8 | 8 | ||
9 | /* kprobe-tracer tracing point */ | 9 | /* kprobe-tracer tracing point */ |
10 | struct kprobe_trace_point { | 10 | struct probe_trace_point { |
11 | char *symbol; /* Base symbol */ | 11 | char *symbol; /* Base symbol */ |
12 | unsigned long offset; /* Offset from symbol */ | 12 | unsigned long offset; /* Offset from symbol */ |
13 | bool retprobe; /* Return probe flag */ | 13 | bool retprobe; /* Return probe flag */ |
14 | }; | 14 | }; |
15 | 15 | ||
16 | /* kprobe-tracer tracing argument referencing offset */ | 16 | /* probe-tracer tracing argument referencing offset */ |
17 | struct kprobe_trace_arg_ref { | 17 | struct probe_trace_arg_ref { |
18 | struct kprobe_trace_arg_ref *next; /* Next reference */ | 18 | struct probe_trace_arg_ref *next; /* Next reference */ |
19 | long offset; /* Offset value */ | 19 | long offset; /* Offset value */ |
20 | }; | 20 | }; |
21 | 21 | ||
22 | /* kprobe-tracer tracing argument */ | 22 | /* kprobe-tracer tracing argument */ |
23 | struct kprobe_trace_arg { | 23 | struct probe_trace_arg { |
24 | char *name; /* Argument name */ | 24 | char *name; /* Argument name */ |
25 | char *value; /* Base value */ | 25 | char *value; /* Base value */ |
26 | char *type; /* Type name */ | 26 | char *type; /* Type name */ |
27 | struct kprobe_trace_arg_ref *ref; /* Referencing offset */ | 27 | struct probe_trace_arg_ref *ref; /* Referencing offset */ |
28 | }; | 28 | }; |
29 | 29 | ||
30 | /* kprobe-tracer tracing event (point + arg) */ | 30 | /* kprobe-tracer tracing event (point + arg) */ |
31 | struct kprobe_trace_event { | 31 | struct probe_trace_event { |
32 | char *event; /* Event name */ | 32 | char *event; /* Event name */ |
33 | char *group; /* Group name */ | 33 | char *group; /* Group name */ |
34 | struct kprobe_trace_point point; /* Trace point */ | 34 | struct probe_trace_point point; /* Trace point */ |
35 | int nargs; /* Number of args */ | 35 | int nargs; /* Number of args */ |
36 | struct kprobe_trace_arg *args; /* Arguments */ | 36 | struct probe_trace_arg *args; /* Arguments */ |
37 | }; | 37 | }; |
38 | 38 | ||
39 | /* Perf probe probing point */ | 39 | /* Perf probe probing point */ |
@@ -93,25 +93,18 @@ struct line_range { | |||
93 | /* Command string to events */ | 93 | /* Command string to events */ |
94 | extern int parse_perf_probe_command(const char *cmd, | 94 | extern int parse_perf_probe_command(const char *cmd, |
95 | struct perf_probe_event *pev); | 95 | struct perf_probe_event *pev); |
96 | extern int parse_kprobe_trace_command(const char *cmd, | ||
97 | struct kprobe_trace_event *tev); | ||
98 | 96 | ||
99 | /* Events to command string */ | 97 | /* Events to command string */ |
100 | extern char *synthesize_perf_probe_command(struct perf_probe_event *pev); | 98 | extern char *synthesize_perf_probe_command(struct perf_probe_event *pev); |
101 | extern char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev); | 99 | extern char *synthesize_probe_trace_command(struct probe_trace_event *tev); |
102 | extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, | 100 | extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, |
103 | size_t len); | 101 | size_t len); |
104 | 102 | ||
105 | /* Check the perf_probe_event needs debuginfo */ | 103 | /* Check the perf_probe_event needs debuginfo */ |
106 | extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); | 104 | extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); |
107 | 105 | ||
108 | /* Convert from kprobe_trace_event to perf_probe_event */ | ||
109 | extern int convert_to_perf_probe_event(struct kprobe_trace_event *tev, | ||
110 | struct perf_probe_event *pev); | ||
111 | |||
112 | /* Release event contents */ | 106 | /* Release event contents */ |
113 | extern void clear_perf_probe_event(struct perf_probe_event *pev); | 107 | extern void clear_perf_probe_event(struct perf_probe_event *pev); |
114 | extern void clear_kprobe_trace_event(struct kprobe_trace_event *tev); | ||
115 | 108 | ||
116 | /* Command string to line-range */ | 109 | /* Command string to line-range */ |
117 | extern int parse_line_range_desc(const char *cmd, struct line_range *lr); | 110 | extern int parse_line_range_desc(const char *cmd, struct line_range *lr); |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index f88070ea5b90..840f1aabbb74 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -366,10 +366,10 @@ static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, | |||
366 | * Probe finder related functions | 366 | * Probe finder related functions |
367 | */ | 367 | */ |
368 | 368 | ||
369 | static struct kprobe_trace_arg_ref *alloc_trace_arg_ref(long offs) | 369 | static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs) |
370 | { | 370 | { |
371 | struct kprobe_trace_arg_ref *ref; | 371 | struct probe_trace_arg_ref *ref; |
372 | ref = zalloc(sizeof(struct kprobe_trace_arg_ref)); | 372 | ref = zalloc(sizeof(struct probe_trace_arg_ref)); |
373 | if (ref != NULL) | 373 | if (ref != NULL) |
374 | ref->offset = offs; | 374 | ref->offset = offs; |
375 | return ref; | 375 | return ref; |
@@ -385,7 +385,7 @@ static int convert_variable_location(Dwarf_Die *vr_die, struct probe_finder *pf) | |||
385 | Dwarf_Word offs = 0; | 385 | Dwarf_Word offs = 0; |
386 | bool ref = false; | 386 | bool ref = false; |
387 | const char *regs; | 387 | const char *regs; |
388 | struct kprobe_trace_arg *tvar = pf->tvar; | 388 | struct probe_trace_arg *tvar = pf->tvar; |
389 | int ret; | 389 | int ret; |
390 | 390 | ||
391 | /* TODO: handle more than 1 exprs */ | 391 | /* TODO: handle more than 1 exprs */ |
@@ -459,10 +459,10 @@ static int convert_variable_location(Dwarf_Die *vr_die, struct probe_finder *pf) | |||
459 | } | 459 | } |
460 | 460 | ||
461 | static int convert_variable_type(Dwarf_Die *vr_die, | 461 | static int convert_variable_type(Dwarf_Die *vr_die, |
462 | struct kprobe_trace_arg *tvar, | 462 | struct probe_trace_arg *tvar, |
463 | const char *cast) | 463 | const char *cast) |
464 | { | 464 | { |
465 | struct kprobe_trace_arg_ref **ref_ptr = &tvar->ref; | 465 | struct probe_trace_arg_ref **ref_ptr = &tvar->ref; |
466 | Dwarf_Die type; | 466 | Dwarf_Die type; |
467 | char buf[16]; | 467 | char buf[16]; |
468 | int ret; | 468 | int ret; |
@@ -500,7 +500,7 @@ static int convert_variable_type(Dwarf_Die *vr_die, | |||
500 | while (*ref_ptr) | 500 | while (*ref_ptr) |
501 | ref_ptr = &(*ref_ptr)->next; | 501 | ref_ptr = &(*ref_ptr)->next; |
502 | /* Add new reference with offset +0 */ | 502 | /* Add new reference with offset +0 */ |
503 | *ref_ptr = zalloc(sizeof(struct kprobe_trace_arg_ref)); | 503 | *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref)); |
504 | if (*ref_ptr == NULL) { | 504 | if (*ref_ptr == NULL) { |
505 | pr_warning("Out of memory error\n"); | 505 | pr_warning("Out of memory error\n"); |
506 | return -ENOMEM; | 506 | return -ENOMEM; |
@@ -545,10 +545,10 @@ static int convert_variable_type(Dwarf_Die *vr_die, | |||
545 | 545 | ||
546 | static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, | 546 | static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, |
547 | struct perf_probe_arg_field *field, | 547 | struct perf_probe_arg_field *field, |
548 | struct kprobe_trace_arg_ref **ref_ptr, | 548 | struct probe_trace_arg_ref **ref_ptr, |
549 | Dwarf_Die *die_mem) | 549 | Dwarf_Die *die_mem) |
550 | { | 550 | { |
551 | struct kprobe_trace_arg_ref *ref = *ref_ptr; | 551 | struct probe_trace_arg_ref *ref = *ref_ptr; |
552 | Dwarf_Die type; | 552 | Dwarf_Die type; |
553 | Dwarf_Word offs; | 553 | Dwarf_Word offs; |
554 | int ret, tag; | 554 | int ret, tag; |
@@ -574,7 +574,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, | |||
574 | pr_debug2("Array real type: (%x)\n", | 574 | pr_debug2("Array real type: (%x)\n", |
575 | (unsigned)dwarf_dieoffset(&type)); | 575 | (unsigned)dwarf_dieoffset(&type)); |
576 | if (tag == DW_TAG_pointer_type) { | 576 | if (tag == DW_TAG_pointer_type) { |
577 | ref = zalloc(sizeof(struct kprobe_trace_arg_ref)); | 577 | ref = zalloc(sizeof(struct probe_trace_arg_ref)); |
578 | if (ref == NULL) | 578 | if (ref == NULL) |
579 | return -ENOMEM; | 579 | return -ENOMEM; |
580 | if (*ref_ptr) | 580 | if (*ref_ptr) |
@@ -605,7 +605,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, | |||
605 | return -EINVAL; | 605 | return -EINVAL; |
606 | } | 606 | } |
607 | 607 | ||
608 | ref = zalloc(sizeof(struct kprobe_trace_arg_ref)); | 608 | ref = zalloc(sizeof(struct probe_trace_arg_ref)); |
609 | if (ref == NULL) | 609 | if (ref == NULL) |
610 | return -ENOMEM; | 610 | return -ENOMEM; |
611 | if (*ref_ptr) | 611 | if (*ref_ptr) |
@@ -738,7 +738,7 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
738 | /* Show a probe point to output buffer */ | 738 | /* Show a probe point to output buffer */ |
739 | static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) | 739 | static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) |
740 | { | 740 | { |
741 | struct kprobe_trace_event *tev; | 741 | struct probe_trace_event *tev; |
742 | Dwarf_Addr eaddr; | 742 | Dwarf_Addr eaddr; |
743 | Dwarf_Die die_mem; | 743 | Dwarf_Die die_mem; |
744 | const char *name; | 744 | const char *name; |
@@ -803,7 +803,7 @@ static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
803 | 803 | ||
804 | /* Find each argument */ | 804 | /* Find each argument */ |
805 | tev->nargs = pf->pev->nargs; | 805 | tev->nargs = pf->pev->nargs; |
806 | tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs); | 806 | tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); |
807 | if (tev->args == NULL) | 807 | if (tev->args == NULL) |
808 | return -ENOMEM; | 808 | return -ENOMEM; |
809 | for (i = 0; i < pf->pev->nargs; i++) { | 809 | for (i = 0; i < pf->pev->nargs; i++) { |
@@ -1060,9 +1060,9 @@ static int find_probe_point_by_func(struct probe_finder *pf) | |||
1060 | return _param.retval; | 1060 | return _param.retval; |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ | 1063 | /* Find probe_trace_events specified by perf_probe_event from debuginfo */ |
1064 | int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, | 1064 | int find_probe_trace_events(int fd, struct perf_probe_event *pev, |
1065 | struct kprobe_trace_event **tevs, int max_tevs) | 1065 | struct probe_trace_event **tevs, int max_tevs) |
1066 | { | 1066 | { |
1067 | struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs}; | 1067 | struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs}; |
1068 | struct perf_probe_point *pp = &pev->point; | 1068 | struct perf_probe_point *pp = &pev->point; |
@@ -1072,7 +1072,7 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, | |||
1072 | Dwarf *dbg; | 1072 | Dwarf *dbg; |
1073 | int ret = 0; | 1073 | int ret = 0; |
1074 | 1074 | ||
1075 | pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * max_tevs); | 1075 | pf.tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs); |
1076 | if (pf.tevs == NULL) | 1076 | if (pf.tevs == NULL) |
1077 | return -ENOMEM; | 1077 | return -ENOMEM; |
1078 | *tevs = pf.tevs; | 1078 | *tevs = pf.tevs; |
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index e1f61dcd18ff..4507d519f183 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h | |||
@@ -16,9 +16,9 @@ static inline int is_c_varname(const char *name) | |||
16 | } | 16 | } |
17 | 17 | ||
18 | #ifdef DWARF_SUPPORT | 18 | #ifdef DWARF_SUPPORT |
19 | /* Find kprobe_trace_events specified by perf_probe_event from debuginfo */ | 19 | /* Find probe_trace_events specified by perf_probe_event from debuginfo */ |
20 | extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, | 20 | extern int find_probe_trace_events(int fd, struct perf_probe_event *pev, |
21 | struct kprobe_trace_event **tevs, | 21 | struct probe_trace_event **tevs, |
22 | int max_tevs); | 22 | int max_tevs); |
23 | 23 | ||
24 | /* Find a perf_probe_point from debuginfo */ | 24 | /* Find a perf_probe_point from debuginfo */ |
@@ -33,7 +33,7 @@ extern int find_line_range(int fd, struct line_range *lr); | |||
33 | 33 | ||
34 | struct probe_finder { | 34 | struct probe_finder { |
35 | struct perf_probe_event *pev; /* Target probe event */ | 35 | struct perf_probe_event *pev; /* Target probe event */ |
36 | struct kprobe_trace_event *tevs; /* Result trace events */ | 36 | struct probe_trace_event *tevs; /* Result trace events */ |
37 | int ntevs; /* Number of trace events */ | 37 | int ntevs; /* Number of trace events */ |
38 | int max_tevs; /* Max number of trace events */ | 38 | int max_tevs; /* Max number of trace events */ |
39 | 39 | ||
@@ -50,7 +50,7 @@ struct probe_finder { | |||
50 | #endif | 50 | #endif |
51 | Dwarf_Op *fb_ops; /* Frame base attribute */ | 51 | Dwarf_Op *fb_ops; /* Frame base attribute */ |
52 | struct perf_probe_arg *pvar; /* Current target variable */ | 52 | struct perf_probe_arg *pvar; /* Current target variable */ |
53 | struct kprobe_trace_arg *tvar; /* Current result variable */ | 53 | struct probe_trace_arg *tvar; /* Current result variable */ |
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct line_finder { | 56 | struct line_finder { |