diff options
Diffstat (limited to 'tools/perf/util/dso.c')
| -rw-r--r-- | tools/perf/util/dso.c | 64 |
1 files changed, 49 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) |
