aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/header.c75
1 files changed, 70 insertions, 5 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index d5359e3384e3..5e6d4d29a7a3 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -62,6 +62,7 @@ struct perf_file_attr {
62struct feat_fd { 62struct feat_fd {
63 struct perf_header *ph; 63 struct perf_header *ph;
64 int fd; 64 int fd;
65 void *buf; /* Either buf != NULL or fd >= 0 */
65 ssize_t offset; 66 ssize_t offset;
66 size_t size; 67 size_t size;
67}; 68};
@@ -81,19 +82,52 @@ bool perf_header__has_feat(const struct perf_header *header, int feat)
81 return test_bit(feat, header->adds_features); 82 return test_bit(feat, header->adds_features);
82} 83}
83 84
84/* Return: 0 if succeded, -ERR if failed. */ 85static int __do_write_fd(struct feat_fd *ff, const void *buf, size_t size)
85int do_write(struct feat_fd *ff, const void *buf, size_t size)
86{ 86{
87 ssize_t ret; 87 ssize_t ret = writen(ff->fd, buf, size);
88 88
89 ret = writen(ff->fd, buf, size);
90 if (ret != (ssize_t)size) 89 if (ret != (ssize_t)size)
91 return ret < 0 ? (int)ret : -1; 90 return ret < 0 ? (int)ret : -1;
91 return 0;
92}
93
94static int __do_write_buf(struct feat_fd *ff, const void *buf, size_t size)
95{
96 /* struct perf_event_header::size is u16 */
97 const size_t max_size = 0xffff - sizeof(struct perf_event_header);
98 size_t new_size = ff->size;
99 void *addr;
100
101 if (size + ff->offset > max_size)
102 return -E2BIG;
103
104 while (size > (new_size - ff->offset))
105 new_size <<= 1;
106 new_size = min(max_size, new_size);
107
108 if (ff->size < new_size) {
109 addr = realloc(ff->buf, new_size);
110 if (!addr)
111 return -ENOMEM;
112 ff->buf = addr;
113 ff->size = new_size;
114 }
115
116 memcpy(ff->buf + ff->offset, buf, size);
117 ff->offset += size;
92 118
93 return 0; 119 return 0;
94} 120}
95 121
96/* Return: 0 if succeded, -ERR if failed. */ 122/* Return: 0 if succeded, -ERR if failed. */
123int do_write(struct feat_fd *ff, const void *buf, size_t size)
124{
125 if (!ff->buf)
126 return __do_write_fd(ff, buf, size);
127 return __do_write_buf(ff, buf, size);
128}
129
130/* Return: 0 if succeded, -ERR if failed. */
97int write_padded(struct feat_fd *ff, const void *bf, 131int write_padded(struct feat_fd *ff, const void *bf,
98 size_t count, size_t count_aligned) 132 size_t count, size_t count_aligned)
99{ 133{
@@ -126,7 +160,7 @@ static int do_write_string(struct feat_fd *ff, const char *str)
126 return write_padded(ff, str, olen, len); 160 return write_padded(ff, str, olen, len);
127} 161}
128 162
129static int __do_read(struct feat_fd *ff, void *addr, ssize_t size) 163static int __do_read_fd(struct feat_fd *ff, void *addr, ssize_t size)
130{ 164{
131 ssize_t ret = readn(ff->fd, addr, size); 165 ssize_t ret = readn(ff->fd, addr, size);
132 166
@@ -135,6 +169,25 @@ static int __do_read(struct feat_fd *ff, void *addr, ssize_t size)
135 return 0; 169 return 0;
136} 170}
137 171
172static int __do_read_buf(struct feat_fd *ff, void *addr, ssize_t size)
173{
174 if (size > (ssize_t)ff->size - ff->offset)
175 return -1;
176
177 memcpy(addr, ff->buf + ff->offset, size);
178 ff->offset += size;
179
180 return 0;
181
182}
183
184static int __do_read(struct feat_fd *ff, void *addr, ssize_t size)
185{
186 if (!ff->buf)
187 return __do_read_fd(ff, addr, size);
188 return __do_read_buf(ff, addr, size);
189}
190
138static int do_read_u32(struct feat_fd *ff, u32 *addr) 191static int do_read_u32(struct feat_fd *ff, u32 *addr)
139{ 192{
140 int ret; 193 int ret;
@@ -189,6 +242,9 @@ static char *do_read_string(struct feat_fd *ff)
189static int write_tracing_data(struct feat_fd *ff, 242static int write_tracing_data(struct feat_fd *ff,
190 struct perf_evlist *evlist) 243 struct perf_evlist *evlist)
191{ 244{
245 if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__))
246 return -1;
247
192 return read_tracing_data(ff->fd, &evlist->entries); 248 return read_tracing_data(ff->fd, &evlist->entries);
193} 249}
194 250
@@ -203,6 +259,9 @@ static int write_build_id(struct feat_fd *ff,
203 if (!perf_session__read_build_ids(session, true)) 259 if (!perf_session__read_build_ids(session, true))
204 return -1; 260 return -1;
205 261
262 if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__))
263 return -1;
264
206 err = perf_session__write_buildid_table(session, ff); 265 err = perf_session__write_buildid_table(session, ff);
207 if (err < 0) { 266 if (err < 0) {
208 pr_debug("failed to write buildid table\n"); 267 pr_debug("failed to write buildid table\n");
@@ -912,6 +971,9 @@ static int write_auxtrace(struct feat_fd *ff,
912 struct perf_session *session; 971 struct perf_session *session;
913 int err; 972 int err;
914 973
974 if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__))
975 return -1;
976
915 session = container_of(ff->ph, struct perf_session, header); 977 session = container_of(ff->ph, struct perf_session, header);
916 978
917 err = auxtrace_index__write(ff->fd, &session->auxtrace_index); 979 err = auxtrace_index__write(ff->fd, &session->auxtrace_index);
@@ -2197,6 +2259,9 @@ static int do_write_feat(struct feat_fd *ff, int type,
2197 if (!feat_ops[type].write) 2259 if (!feat_ops[type].write)
2198 return -1; 2260 return -1;
2199 2261
2262 if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__))
2263 return -1;
2264
2200 (*p)->offset = lseek(ff->fd, 0, SEEK_CUR); 2265 (*p)->offset = lseek(ff->fd, 0, SEEK_CUR);
2201 2266
2202 err = feat_ops[type].write(ff, evlist); 2267 err = feat_ops[type].write(ff, evlist);