aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/header.c53
-rw-r--r--tools/perf/util/session.c4
2 files changed, 50 insertions, 7 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 9f867d96c6a5..666f18972fa3 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1973,6 +1973,51 @@ static int perf_header__read_pipe(struct perf_session *session, int fd)
1973 return 0; 1973 return 0;
1974} 1974}
1975 1975
1976static int read_attr(int fd, struct perf_header *ph,
1977 struct perf_file_attr *f_attr)
1978{
1979 struct perf_event_attr *attr = &f_attr->attr;
1980 size_t sz, left;
1981 size_t our_sz = sizeof(f_attr->attr);
1982 int ret;
1983
1984 memset(f_attr, 0, sizeof(*f_attr));
1985
1986 /* read minimal guaranteed structure */
1987 ret = readn(fd, attr, PERF_ATTR_SIZE_VER0);
1988 if (ret <= 0) {
1989 pr_debug("cannot read %d bytes of header attr\n",
1990 PERF_ATTR_SIZE_VER0);
1991 return -1;
1992 }
1993
1994 /* on file perf_event_attr size */
1995 sz = attr->size;
1996 if (ph->needs_swap)
1997 sz = bswap_32(sz);
1998
1999 if (sz == 0) {
2000 /* assume ABI0 */
2001 sz = PERF_ATTR_SIZE_VER0;
2002 } else if (sz > our_sz) {
2003 pr_debug("file uses a more recent and unsupported ABI"
2004 " (%zu bytes extra)\n", sz - our_sz);
2005 return -1;
2006 }
2007 /* what we have not yet read and that we know about */
2008 left = sz - PERF_ATTR_SIZE_VER0;
2009 if (left) {
2010 void *ptr = attr;
2011 ptr += PERF_ATTR_SIZE_VER0;
2012
2013 ret = readn(fd, ptr, left);
2014 }
2015 /* read perf_file_section, ids are read in caller */
2016 ret = readn(fd, &f_attr->ids, sizeof(f_attr->ids));
2017
2018 return ret <= 0 ? -1 : 0;
2019}
2020
1976int perf_session__read_header(struct perf_session *session, int fd) 2021int perf_session__read_header(struct perf_session *session, int fd)
1977{ 2022{
1978 struct perf_header *header = &session->header; 2023 struct perf_header *header = &session->header;
@@ -1988,19 +2033,17 @@ int perf_session__read_header(struct perf_session *session, int fd)
1988 if (session->fd_pipe) 2033 if (session->fd_pipe)
1989 return perf_header__read_pipe(session, fd); 2034 return perf_header__read_pipe(session, fd);
1990 2035
1991 if (perf_file_header__read(&f_header, header, fd) < 0) { 2036 if (perf_file_header__read(&f_header, header, fd) < 0)
1992 pr_debug("incompatible file format\n");
1993 return -EINVAL; 2037 return -EINVAL;
1994 }
1995 2038
1996 nr_attrs = f_header.attrs.size / sizeof(f_attr); 2039 nr_attrs = f_header.attrs.size / f_header.attr_size;
1997 lseek(fd, f_header.attrs.offset, SEEK_SET); 2040 lseek(fd, f_header.attrs.offset, SEEK_SET);
1998 2041
1999 for (i = 0; i < nr_attrs; i++) { 2042 for (i = 0; i < nr_attrs; i++) {
2000 struct perf_evsel *evsel; 2043 struct perf_evsel *evsel;
2001 off_t tmp; 2044 off_t tmp;
2002 2045
2003 if (readn(fd, &f_attr, sizeof(f_attr)) <= 0) 2046 if (read_attr(fd, header, &f_attr) < 0)
2004 goto out_errno; 2047 goto out_errno;
2005 2048
2006 if (header->needs_swap) 2049 if (header->needs_swap)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index bec8a328b1b8..e650de8f4396 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -24,7 +24,7 @@ static int perf_session__open(struct perf_session *self, bool force)
24 self->fd = STDIN_FILENO; 24 self->fd = STDIN_FILENO;
25 25
26 if (perf_session__read_header(self, self->fd) < 0) 26 if (perf_session__read_header(self, self->fd) < 0)
27 pr_err("incompatible file format"); 27 pr_err("incompatible file format (rerun with -v to learn more)");
28 28
29 return 0; 29 return 0;
30 } 30 }
@@ -56,7 +56,7 @@ static int perf_session__open(struct perf_session *self, bool force)
56 } 56 }
57 57
58 if (perf_session__read_header(self, self->fd) < 0) { 58 if (perf_session__read_header(self, self->fd) < 0) {
59 pr_err("incompatible file format"); 59 pr_err("incompatible file format (rerun with -v to learn more)");
60 goto out_close; 60 goto out_close;
61 } 61 }
62 62