aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/dso.c64
-rw-r--r--tools/perf/util/dso.h1
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
375static ssize_t 376static ssize_t
376dso_cache__read(struct dso *dso, struct machine *machine, 377dso_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
420static ssize_t dso_cache_read(struct dso *dso, struct machine *machine, 415static 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
432ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, 427static 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
455static 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
470static 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
486ssize_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
461ssize_t dso__data_read_addr(struct dso *dso, struct map *map, 495ssize_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