~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to tools/perf/util/probe-event.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

Lines of Context:
117
117
        struct rb_node *nd;
118
118
        struct map_groups *grp = &machine.kmaps;
119
119
 
 
120
        /* A file path -- this is an offline module */
 
121
        if (module && strchr(module, '/'))
 
122
                return machine__new_module(&machine, 0, module);
 
123
 
120
124
        if (!module)
121
125
                module = "kernel";
122
126
 
170
174
}
171
175
 
172
176
#ifdef DWARF_SUPPORT
173
 
static int open_vmlinux(const char *module)
 
177
/* Open new debuginfo of given module */
 
178
static struct debuginfo *open_debuginfo(const char *module)
174
179
{
175
 
        const char *path = kernel_get_module_path(module);
176
 
        if (!path) {
177
 
                pr_err("Failed to find path of %s module.\n",
178
 
                       module ?: "kernel");
179
 
                return -ENOENT;
 
180
        const char *path;
 
181
 
 
182
        /* A file path -- this is an offline module */
 
183
        if (module && strchr(module, '/'))
 
184
                path = module;
 
185
        else {
 
186
                path = kernel_get_module_path(module);
 
187
 
 
188
                if (!path) {
 
189
                        pr_err("Failed to find path of %s module.\n",
 
190
                               module ?: "kernel");
 
191
                        return NULL;
 
192
                }
180
193
        }
181
 
        pr_debug("Try to open %s\n", path);
182
 
        return open(path, O_RDONLY);
 
194
        return debuginfo__new(path);
183
195
}
184
196
 
185
197
/*
193
205
        struct map *map;
194
206
        u64 addr;
195
207
        int ret = -ENOENT;
 
208
        struct debuginfo *dinfo;
196
209
 
197
210
        sym = __find_kernel_function_by_name(tp->symbol, &map);
198
211
        if (sym) {
199
212
                addr = map->unmap_ip(map, sym->start + tp->offset);
200
213
                pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol,
201
214
                         tp->offset, addr);
202
 
                ret = find_perf_probe_point((unsigned long)addr, pp);
 
215
 
 
216
                dinfo = debuginfo__new_online_kernel(addr);
 
217
                if (dinfo) {
 
218
                        ret = debuginfo__find_probe_point(dinfo,
 
219
                                                 (unsigned long)addr, pp);
 
220
                        debuginfo__delete(dinfo);
 
221
                } else {
 
222
                        pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n",
 
223
                                 addr);
 
224
                        ret = -ENOENT;
 
225
                }
203
226
        }
204
227
        if (ret <= 0) {
205
228
                pr_debug("Failed to find corresponding probes from "
214
237
        return 0;
215
238
}
216
239
 
 
240
static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
 
241
                                            int ntevs, const char *module)
 
242
{
 
243
        int i, ret = 0;
 
244
        char *tmp;
 
245
 
 
246
        if (!module)
 
247
                return 0;
 
248
 
 
249
        tmp = strrchr(module, '/');
 
250
        if (tmp) {
 
251
                /* This is a module path -- get the module name */
 
252
                module = strdup(tmp + 1);
 
253
                if (!module)
 
254
                        return -ENOMEM;
 
255
                tmp = strchr(module, '.');
 
256
                if (tmp)
 
257
                        *tmp = '\0';
 
258
                tmp = (char *)module;   /* For free() */
 
259
        }
 
260
 
 
261
        for (i = 0; i < ntevs; i++) {
 
262
                tevs[i].point.module = strdup(module);
 
263
                if (!tevs[i].point.module) {
 
264
                        ret = -ENOMEM;
 
265
                        break;
 
266
                }
 
267
        }
 
268
 
 
269
        if (tmp)
 
270
                free(tmp);
 
271
 
 
272
        return ret;
 
273
}
 
274
 
217
275
/* Try to find perf_probe_event with debuginfo */
218
276
static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
219
 
                                           struct probe_trace_event **tevs,
220
 
                                           int max_tevs, const char *module)
 
277
                                          struct probe_trace_event **tevs,
 
278
                                          int max_tevs, const char *module)
221
279
{
222
280
        bool need_dwarf = perf_probe_event_need_dwarf(pev);
223
 
        int fd, ntevs;
 
281
        struct debuginfo *dinfo = open_debuginfo(module);
 
282
        int ntevs, ret = 0;
224
283
 
225
 
        fd = open_vmlinux(module);
226
 
        if (fd < 0) {
 
284
        if (!dinfo) {
227
285
                if (need_dwarf) {
228
286
                        pr_warning("Failed to open debuginfo file.\n");
229
 
                        return fd;
 
287
                        return -ENOENT;
230
288
                }
231
 
                pr_debug("Could not open vmlinux. Try to use symbols.\n");
 
289
                pr_debug("Could not open debuginfo. Try to use symbols.\n");
232
290
                return 0;
233
291
        }
234
292
 
235
 
        /* Searching trace events corresponding to probe event */
236
 
        ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs);
 
293
        /* Searching trace events corresponding to a probe event */
 
294
        ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs);
 
295
 
 
296
        debuginfo__delete(dinfo);
237
297
 
238
298
        if (ntevs > 0) {        /* Succeeded to find trace events */
239
299
                pr_debug("find %d probe_trace_events.\n", ntevs);
240
 
                return ntevs;
 
300
                if (module)
 
301
                        ret = add_module_to_probe_trace_events(*tevs, ntevs,
 
302
                                                               module);
 
303
                return ret < 0 ? ret : ntevs;
241
304
        }
242
305
 
243
306
        if (ntevs == 0) {       /* No error but failed to find probe point. */
371
434
{
372
435
        int l = 1;
373
436
        struct line_node *ln;
 
437
        struct debuginfo *dinfo;
374
438
        FILE *fp;
375
 
        int fd, ret;
 
439
        int ret;
376
440
        char *tmp;
377
441
 
378
442
        /* Search a line range */
380
444
        if (ret < 0)
381
445
                return ret;
382
446
 
383
 
        fd = open_vmlinux(module);
384
 
        if (fd < 0) {
 
447
        dinfo = open_debuginfo(module);
 
448
        if (!dinfo) {
385
449
                pr_warning("Failed to open debuginfo file.\n");
386
 
                return fd;
 
450
                return -ENOENT;
387
451
        }
388
452
 
389
 
        ret = find_line_range(fd, lr);
 
453
        ret = debuginfo__find_line_range(dinfo, lr);
 
454
        debuginfo__delete(dinfo);
390
455
        if (ret == 0) {
391
456
                pr_warning("Specified source line is not found.\n");
392
457
                return -ENOENT;
448
513
        return ret;
449
514
}
450
515
 
451
 
static int show_available_vars_at(int fd, struct perf_probe_event *pev,
 
516
static int show_available_vars_at(struct debuginfo *dinfo,
 
517
                                  struct perf_probe_event *pev,
452
518
                                  int max_vls, struct strfilter *_filter,
453
519
                                  bool externs)
454
520
{
463
529
                return -EINVAL;
464
530
        pr_debug("Searching variables at %s\n", buf);
465
531
 
466
 
        ret = find_available_vars_at(fd, pev, &vls, max_vls, externs);
 
532
        ret = debuginfo__find_available_vars_at(dinfo, pev, &vls,
 
533
                                                max_vls, externs);
467
534
        if (ret <= 0) {
468
535
                pr_err("Failed to find variables at %s (%d)\n", buf, ret);
469
536
                goto end;
504
571
                        int max_vls, const char *module,
505
572
                        struct strfilter *_filter, bool externs)
506
573
{
507
 
        int i, fd, ret = 0;
 
574
        int i, ret = 0;
 
575
        struct debuginfo *dinfo;
508
576
 
509
577
        ret = init_vmlinux();
510
578
        if (ret < 0)
511
579
                return ret;
512
580
 
 
581
        dinfo = open_debuginfo(module);
 
582
        if (!dinfo) {
 
583
                pr_warning("Failed to open debuginfo file.\n");
 
584
                return -ENOENT;
 
585
        }
 
586
 
513
587
        setup_pager();
514
588
 
515
 
        for (i = 0; i < npevs && ret >= 0; i++) {
516
 
                fd = open_vmlinux(module);
517
 
                if (fd < 0) {
518
 
                        pr_warning("Failed to open debug information file.\n");
519
 
                        ret = fd;
520
 
                        break;
521
 
                }
522
 
                ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter,
 
589
        for (i = 0; i < npevs && ret >= 0; i++)
 
590
                ret = show_available_vars_at(dinfo, &pevs[i], max_vls, _filter,
523
591
                                             externs);
524
 
        }
 
592
 
 
593
        debuginfo__delete(dinfo);
525
594
        return ret;
526
595
}
527
596
 
990
1059
 
991
1060
/* Parse probe_events event into struct probe_point */
992
1061
static int parse_probe_trace_command(const char *cmd,
993
 
                                        struct probe_trace_event *tev)
 
1062
                                     struct probe_trace_event *tev)
994
1063
{
995
1064
        struct probe_trace_point *tp = &tev->point;
996
1065
        char pr;
1023
1092
 
1024
1093
        tp->retprobe = (pr == 'r');
1025
1094
 
1026
 
        /* Scan function name and offset */
1027
 
        ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol,
 
1095
        /* Scan module name(if there), function name and offset */
 
1096
        p = strchr(argv[1], ':');
 
1097
        if (p) {
 
1098
                tp->module = strndup(argv[1], p - argv[1]);
 
1099
                p++;
 
1100
        } else
 
1101
                p = argv[1];
 
1102
        ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol,
1028
1103
                     &tp->offset);
1029
1104
        if (ret == 1)
1030
1105
                tp->offset = 0;
1269
1344
        if (buf == NULL)
1270
1345
                return NULL;
1271
1346
 
1272
 
        len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
 
1347
        len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
1273
1348
                         tp->retprobe ? 'r' : 'p',
1274
1349
                         tev->group, tev->event,
 
1350
                         tp->module ?: "", tp->module ? ":" : "",
1275
1351
                         tp->symbol, tp->offset);
1276
1352
        if (len <= 0)
1277
1353
                goto error;
1378
1454
                free(tev->group);
1379
1455
        if (tev->point.symbol)
1380
1456
                free(tev->point.symbol);
 
1457
        if (tev->point.module)
 
1458
                free(tev->point.module);
1381
1459
        for (i = 0; i < tev->nargs; i++) {
1382
1460
                if (tev->args[i].name)
1383
1461
                        free(tev->args[i].name);
1729
1807
        /* Convert perf_probe_event with debuginfo */
1730
1808
        ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module);
1731
1809
        if (ret != 0)
1732
 
                return ret;
 
1810
                return ret;     /* Found in debuginfo or got an error */
1733
1811
 
1734
1812
        /* Allocate trace event buffer */
1735
1813
        tev = *tevs = zalloc(sizeof(struct probe_trace_event));
1742
1820
                ret = -ENOMEM;
1743
1821
                goto error;
1744
1822
        }
 
1823
 
 
1824
        if (module) {
 
1825
                tev->point.module = strdup(module);
 
1826
                if (tev->point.module == NULL) {
 
1827
                        ret = -ENOMEM;
 
1828
                        goto error;
 
1829
                }
 
1830
        }
 
1831
 
1745
1832
        tev->point.offset = pev->point.offset;
1746
1833
        tev->point.retprobe = pev->point.retprobe;
1747
1834
        tev->nargs = pev->nargs;