diff options
-rw-r--r-- | tools/perf/util/dso.c | 64 | ||||
-rw-r--r-- | tools/perf/util/dso.h | 1 |
2 files changed, 50 insertions, 15 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index fbf6cc98b8a9..db634383156c 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
@@ -205,6 +205,7 @@ static void close_data_fd(struct dso *dso) | |||
205 | if (dso->data.fd >= 0) { | 205 | if (dso->data.fd >= 0) { |
206 | close(dso->data.fd); | 206 | close(dso->data.fd); |
207 | dso->data.fd = -1; | 207 | dso->data.fd = -1; |
208 | dso->data.file_size = 0; | ||
208 | dso__list_del(dso); | 209 | dso__list_del(dso); |
209 | } | 210 | } |
210 | } | 211 | } |
@@ -373,16 +374,10 @@ dso_cache__memcpy(struct dso_cache *cache, u64 offset, | |||
373 | } | 374 | } |
374 | 375 | ||
375 | static ssize_t | 376 | static ssize_t |
376 | dso_cache__read(struct dso *dso, struct machine *machine, | 377 | dso_cache__read(struct dso *dso, u64 offset, u8 *data, ssize_t size) |
377 | u64 offset, u8 *data, ssize_t size) | ||
378 | { | 378 | { |
379 | struct dso_cache *cache; | 379 | struct dso_cache *cache; |
380 | ssize_t ret; | 380 | ssize_t ret; |
381 | int fd; | ||
382 | |||
383 | fd = dso__data_fd(dso, machine); | ||
384 | if (fd < 0) | ||
385 | return -1; | ||
386 | 381 | ||
387 | do { | 382 | do { |
388 | u64 cache_offset; | 383 | u64 cache_offset; |
@@ -396,10 +391,10 @@ dso_cache__read(struct dso *dso, struct machine *machine, | |||
396 | cache_offset = offset & DSO__DATA_CACHE_MASK; | 391 | cache_offset = offset & DSO__DATA_CACHE_MASK; |
397 | ret = -EINVAL; | 392 | ret = -EINVAL; |
398 | 393 | ||
399 | if (-1 == lseek(fd, cache_offset, SEEK_SET)) | 394 | if (-1 == lseek(dso->data.fd, cache_offset, SEEK_SET)) |
400 | break; | 395 | break; |
401 | 396 | ||
402 | ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE); | 397 | ret = read(dso->data.fd, cache->data, DSO__DATA_CACHE_SIZE); |
403 | if (ret <= 0) | 398 | if (ret <= 0) |
404 | break; | 399 | break; |
405 | 400 | ||
@@ -417,8 +412,8 @@ dso_cache__read(struct dso *dso, struct machine *machine, | |||
417 | return ret; | 412 | return ret; |
418 | } | 413 | } |
419 | 414 | ||
420 | static ssize_t dso_cache_read(struct dso *dso, struct machine *machine, | 415 | static ssize_t dso_cache_read(struct dso *dso, u64 offset, |
421 | u64 offset, u8 *data, ssize_t size) | 416 | u8 *data, ssize_t size) |
422 | { | 417 | { |
423 | struct dso_cache *cache; | 418 | struct dso_cache *cache; |
424 | 419 | ||
@@ -426,11 +421,10 @@ static ssize_t dso_cache_read(struct dso *dso, struct machine *machine, | |||
426 | if (cache) | 421 | if (cache) |
427 | return dso_cache__memcpy(cache, offset, data, size); | 422 | return dso_cache__memcpy(cache, offset, data, size); |
428 | else | 423 | else |
429 | return dso_cache__read(dso, machine, offset, data, size); | 424 | return dso_cache__read(dso, offset, data, size); |
430 | } | 425 | } |
431 | 426 | ||
432 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | 427 | static ssize_t cached_read(struct dso *dso, u64 offset, u8 *data, ssize_t size) |
433 | u64 offset, u8 *data, ssize_t size) | ||
434 | { | 428 | { |
435 | ssize_t r = 0; | 429 | ssize_t r = 0; |
436 | u8 *p = data; | 430 | u8 *p = data; |
@@ -438,7 +432,7 @@ ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | |||
438 | do { | 432 | do { |
439 | ssize_t ret; | 433 | ssize_t ret; |
440 | 434 | ||
441 | ret = dso_cache_read(dso, machine, offset, p, size); | 435 | ret = dso_cache_read(dso, offset, p, size); |
442 | if (ret < 0) | 436 | if (ret < 0) |
443 | return ret; | 437 | return ret; |
444 | 438 | ||
@@ -458,6 +452,46 @@ ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | |||
458 | return r; | 452 | return r; |
459 | } | 453 | } |
460 | 454 | ||
455 | static int data_file_size(struct dso *dso) | ||
456 | { | ||
457 | struct stat st; | ||
458 | |||
459 | if (!dso->data.file_size) { | ||
460 | if (fstat(dso->data.fd, &st)) { | ||
461 | pr_err("dso mmap failed, fstat: %s\n", strerror(errno)); | ||
462 | return -1; | ||
463 | } | ||
464 | dso->data.file_size = st.st_size; | ||
465 | } | ||
466 | |||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | static ssize_t data_read_offset(struct dso *dso, u64 offset, | ||
471 | u8 *data, ssize_t size) | ||
472 | { | ||
473 | if (data_file_size(dso)) | ||
474 | return -1; | ||
475 | |||
476 | /* Check the offset sanity. */ | ||
477 | if (offset > dso->data.file_size) | ||
478 | return -1; | ||
479 | |||
480 | if (offset + size < offset) | ||
481 | return -1; | ||
482 | |||
483 | return cached_read(dso, offset, data, size); | ||
484 | } | ||
485 | |||
486 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | ||
487 | u64 offset, u8 *data, ssize_t size) | ||
488 | { | ||
489 | if (dso__data_fd(dso, machine) < 0) | ||
490 | return -1; | ||
491 | |||
492 | return data_read_offset(dso, offset, data, size); | ||
493 | } | ||
494 | |||
461 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, | 495 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, |
462 | struct machine *machine, u64 addr, | 496 | struct machine *machine, u64 addr, |
463 | u8 *data, ssize_t size) | 497 | u8 *data, ssize_t size) |
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 90988bf06641..da47b13595f3 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h | |||
@@ -103,6 +103,7 @@ struct dso { | |||
103 | struct { | 103 | struct { |
104 | struct rb_root cache; | 104 | struct rb_root cache; |
105 | int fd; | 105 | int fd; |
106 | size_t file_size; | ||
106 | struct list_head open_entry; | 107 | struct list_head open_entry; |
107 | } data; | 108 | } data; |
108 | 109 | ||