blob: 50a27c090420ff2f15c018b61853fd3503915955 [file] [log] [blame]
Mark Salyzyn9dd65102016-02-17 16:08:13 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <errno.h>
18#include <inttypes.h>
19#include <stdbool.h>
20#include <stdint.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include <log/log.h>
26#include <log/logger.h>
27
28#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
29
30typedef struct {
31 uint32_t tag;
32 unsigned pos; /* Read/write position into buffer */
33 unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements */
34 unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* pos for list counter */
35 unsigned list_nest_depth;
36 unsigned len; /* Length or raw buffer. */
37 bool overflow;
38 bool list_stop; /* next call decrement list_nest_depth and issue a stop */
39 enum {
40 kAndroidLoggerRead = 1,
41 kAndroidLoggerWrite = 2,
42 } read_write_flag;
43 uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
44} android_log_context_internal;
45
46android_log_context create_android_logger(uint32_t tag) {
47 size_t needed, i;
48 android_log_context_internal *context;
49
50 context = calloc(1, sizeof(android_log_context_internal));
51 if (!context) {
52 return NULL;
53 }
54 context->tag = tag;
55 context->read_write_flag = kAndroidLoggerWrite;
56 needed = sizeof(uint8_t) + sizeof(uint8_t);
57 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
58 context->overflow = true;
59 }
60 /* Everything is a list */
61 context->storage[context->pos + 0] = EVENT_TYPE_LIST;
62 context->list[0] = context->pos + 1;
63 context->pos += needed;
64
65 return (android_log_context)context;
66}
67
68android_log_context create_android_log_parser(const char *msg, size_t len) {
69 android_log_context_internal *context;
70 size_t i;
71
72 context = calloc(1, sizeof(android_log_context_internal));
73 if (!context) {
74 return NULL;
75 }
76 len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
77 context->len = len;
78 memcpy(context->storage, msg, len);
79 context->read_write_flag = kAndroidLoggerRead;
80
81 return (android_log_context)context;
82}
83
84int android_log_destroy(android_log_context *ctx) {
85 android_log_context_internal *context;
86
87 context = (android_log_context_internal *)*ctx;
88 if (!context) {
89 return -EBADF;
90 }
91 memset(context, 0, sizeof(*context));
92 free(context);
93 *ctx = NULL;
94 return 0;
95}
96
97int android_log_write_list_begin(android_log_context ctx) {
98 size_t needed;
99 android_log_context_internal *context;
100
101 context = (android_log_context_internal *)ctx;
102 if (!context ||
103 (kAndroidLoggerWrite != context->read_write_flag)) {
104 return -EBADF;
105 }
106 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
107 context->overflow = true;
108 return -EOVERFLOW;
109 }
110 needed = sizeof(uint8_t) + sizeof(uint8_t);
111 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
112 context->overflow = true;
113 return -EIO;
114 }
115 context->count[context->list_nest_depth]++;
116 context->list_nest_depth++;
117 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
118 context->overflow = true;
119 return -EOVERFLOW;
120 }
121 if (context->overflow) {
122 return -EIO;
123 }
124 context->storage[context->pos + 0] = EVENT_TYPE_LIST;
125 context->storage[context->pos + 1] = 0;
126 context->list[context->list_nest_depth] = context->pos + 1;
127 context->count[context->list_nest_depth] = 0;
128 context->pos += needed;
129 return 0;
130}
131
132static inline void copy4LE(uint8_t *buf, uint32_t val)
133{
134 buf[0] = val & 0xFF;
135 buf[1] = (val >> 8) & 0xFF;
136 buf[2] = (val >> 16) & 0xFF;
137 buf[3] = (val >> 24) & 0xFF;
138}
139
140int android_log_write_int32(android_log_context ctx, int32_t value) {
141 size_t needed;
142 android_log_context_internal *context;
143
144 context = (android_log_context_internal *)ctx;
145 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
146 return -EBADF;
147 }
148 if (context->overflow) {
149 return -EIO;
150 }
151 needed = sizeof(uint8_t) + sizeof(value);
152 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
153 context->overflow = true;
154 return -EIO;
155 }
156 context->count[context->list_nest_depth]++;
157 context->storage[context->pos + 0] = EVENT_TYPE_INT;
158 copy4LE(&context->storage[context->pos + 1], value);
159 context->pos += needed;
160 return 0;
161}
162
163static inline void copy8LE(uint8_t *buf, uint64_t val)
164{
165 buf[0] = val & 0xFF;
166 buf[1] = (val >> 8) & 0xFF;
167 buf[2] = (val >> 16) & 0xFF;
168 buf[3] = (val >> 24) & 0xFF;
169 buf[4] = (val >> 32) & 0xFF;
170 buf[5] = (val >> 40) & 0xFF;
171 buf[6] = (val >> 48) & 0xFF;
172 buf[7] = (val >> 56) & 0xFF;
173}
174
175int android_log_write_int64(android_log_context ctx, int64_t value) {
176 size_t needed;
177 android_log_context_internal *context;
178
179 context = (android_log_context_internal *)ctx;
180 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
181 return -EBADF;
182 }
183 if (context->overflow) {
184 return -EIO;
185 }
186 needed = sizeof(uint8_t) + sizeof(value);
187 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
188 context->overflow = true;
189 return -EIO;
190 }
191 context->count[context->list_nest_depth]++;
192 context->storage[context->pos + 0] = EVENT_TYPE_LONG;
193 copy8LE(&context->storage[context->pos + 1], value);
194 context->pos += needed;
195 return 0;
196}
197
198int android_log_write_string8(android_log_context ctx, const char *value) {
199 size_t needed;
200 int32_t len;
201 android_log_context_internal *context;
202
203 context = (android_log_context_internal *)ctx;
204 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
205 return -EBADF;
206 }
207 if (context->overflow) {
208 return -EIO;
209 }
210 if (!value) {
211 return -EINVAL;
212 }
213 len = strlen(value);
214 needed = sizeof(uint8_t) + sizeof(len) + len;
215 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
216 /* Truncate string for delivery */
217 len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(len);
218 if (len <= 0) {
219 context->overflow = true;
220 return -EIO;
221 }
222 }
223 context->count[context->list_nest_depth]++;
224 context->storage[context->pos + 0] = EVENT_TYPE_STRING;
225 copy4LE(&context->storage[context->pos + 1], len);
226 memcpy(&context->storage[context->pos + 5], value, len);
227 context->pos += needed;
228 return 0;
229}
230
231int android_log_write_float32(android_log_context ctx, float value) {
232 size_t needed;
233 uint32_t ivalue;
234 android_log_context_internal *context;
235
236 context = (android_log_context_internal *)ctx;
237 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
238 return -EBADF;
239 }
240 if (context->overflow) {
241 return -EIO;
242 }
243 needed = sizeof(uint8_t) + sizeof(ivalue);
244 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
245 context->overflow = true;
246 return -EIO;
247 }
248 ivalue = *(uint32_t *)&value;
249 context->count[context->list_nest_depth]++;
250 context->storage[context->pos + 0] = EVENT_TYPE_FLOAT;
251 copy4LE(&context->storage[context->pos + 1], ivalue);
252 context->pos += needed;
253 return 0;
254}
255
256int android_log_write_list_end(android_log_context ctx) {
257 android_log_context_internal *context;
258
259 context = (android_log_context_internal *)ctx;
260 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
261 return -EBADF;
262 }
263 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
264 context->overflow = true;
265 context->list_nest_depth--;
266 return -EOVERFLOW;
267 }
268 if (!context->list_nest_depth) {
269 context->overflow = true;
270 return -EOVERFLOW;
271 }
272 if (context->list[context->list_nest_depth] <= 0) {
273 context->list_nest_depth--;
274 context->overflow = true;
275 return -EOVERFLOW;
276 }
277 context->storage[context->list[context->list_nest_depth]] =
278 context->count[context->list_nest_depth];
279 context->list_nest_depth--;
280 return 0;
281}
282
283/*
284 * Logs the list of elements to the event log.
285 */
286int android_log_write_list(android_log_context ctx, log_id_t id) {
287 android_log_context_internal *context;
288 const char *msg;
289 ssize_t len;
290
291 if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY)) {
292 return -EINVAL;
293 }
294
295 context = (android_log_context_internal *)ctx;
296 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
297 return -EBADF;
298 }
299 if (context->list_nest_depth) {
300 return -EIO;
301 }
302 /* NB: if there was overflow, then log is truncated. Nothing reported */
303 context->storage[1] = context->count[0];
304 len = context->len = context->pos;
305 msg = (const char *)context->storage;
306 /* it'snot a list */
307 if (context->count[0] <= 1) {
308 len -= sizeof(uint8_t) + sizeof(uint8_t);
309 if (len < 0) {
310 len = 0;
311 }
312 msg += sizeof(uint8_t) + sizeof(uint8_t);
313 }
314 return (id == LOG_ID_EVENTS) ?
315 __android_log_bwrite(context->tag, msg, len) :
316 __android_log_security_bwrite(context->tag, msg, len);
317}
318
319/*
320 * Extract a 4-byte value from a byte stream.
321 */
322static inline uint32_t get4LE(const uint8_t* src)
323{
324 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
325}
326
327/*
328 * Extract an 8-byte value from a byte stream.
329 */
330static inline uint64_t get8LE(const uint8_t* src)
331{
332 uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
333 uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
334 return ((uint64_t) high << 32) | (uint64_t) low;
335}
336
337/*
338 * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.
339 * If there is nothing to process, the complete field is set to non-zero. If
340 * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check
341 * this and continues to call this function, the behavior is undefined
342 * (although it won't crash).
343 */
344static android_log_list_element android_log_read_next_internal(
345 android_log_context ctx, int peek) {
346 android_log_list_element elem;
347 unsigned pos;
348 android_log_context_internal *context;
349
350 context = (android_log_context_internal *)ctx;
351
352 memset(&elem, 0, sizeof(elem));
353
354 /* Nothing to parse from this context, so return complete. */
355 if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
356 (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
357 (context->count[context->list_nest_depth] >=
358 (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
359 elem.type = EVENT_TYPE_UNKNOWN;
360 if (context &&
361 (context->list_stop ||
362 ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
363 !context->count[context->list_nest_depth]))) {
364 elem.type = EVENT_TYPE_LIST_STOP;
365 }
366 elem.complete = true;
367 return elem;
368 }
369
370 /*
371 * Use a different variable to update the position in case this
372 * operation is a "peek".
373 */
374 pos = context->pos;
375 if (context->list_stop) {
376 elem.type = EVENT_TYPE_LIST_STOP;
377 elem.complete = !context->count[0] && (!context->list_nest_depth ||
378 ((context->list_nest_depth == 1) && !context->count[1]));
379 if (!peek) {
380 /* Suck in superfluous stop */
381 if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
382 context->pos = pos + 1;
383 }
384 if (context->list_nest_depth) {
385 --context->list_nest_depth;
386 if (context->count[context->list_nest_depth]) {
387 context->list_stop = false;
388 }
389 } else {
390 context->list_stop = false;
391 }
392 }
393 return elem;
394 }
395 if ((pos + 1) > context->len) {
396 elem.type = EVENT_TYPE_UNKNOWN;
397 elem.complete = true;
398 return elem;
399 }
400
401 elem.type = context->storage[pos++];
402 switch ((int)elem.type) {
403 case EVENT_TYPE_FLOAT:
404 /* Rely on union to translate elem.data.int32 into elem.data.float32 */
405 /* FALLTHRU */
406 case EVENT_TYPE_INT:
407 elem.len = sizeof(int32_t);
408 if ((pos + elem.len) > context->len) {
409 elem.type = EVENT_TYPE_UNKNOWN;
410 return elem;
411 }
412 elem.data.int32 = get4LE(&context->storage[pos]);
413 /* common tangeable object suffix */
414 pos += elem.len;
415 elem.complete = !context->list_nest_depth && !context->count[0];
416 if (!peek) {
417 if (!context->count[context->list_nest_depth] ||
418 !--(context->count[context->list_nest_depth])) {
419 context->list_stop = true;
420 }
421 context->pos = pos;
422 }
423 return elem;
424
425 case EVENT_TYPE_LONG:
426 elem.len = sizeof(int64_t);
427 if ((pos + elem.len) > context->len) {
428 elem.type = EVENT_TYPE_UNKNOWN;
429 return elem;
430 }
431 elem.data.int64 = get8LE(&context->storage[pos]);
432 /* common tangeable object suffix */
433 pos += elem.len;
434 elem.complete = !context->list_nest_depth && !context->count[0];
435 if (!peek) {
436 if (!context->count[context->list_nest_depth] ||
437 !--(context->count[context->list_nest_depth])) {
438 context->list_stop = true;
439 }
440 context->pos = pos;
441 }
442 return elem;
443
444 case EVENT_TYPE_STRING:
445 if ((pos + sizeof(int32_t)) > context->len) {
446 elem.type = EVENT_TYPE_UNKNOWN;
447 elem.complete = true;
448 return elem;
449 }
450 elem.len = get4LE(&context->storage[pos]);
451 pos += sizeof(int32_t);
452 if ((pos + elem.len) > context->len) {
453 elem.len = context->len - pos; /* truncate string */
454 elem.complete = true;
455 if (!elem.len) {
456 elem.type = EVENT_TYPE_UNKNOWN;
457 return elem;
458 }
459 }
460 elem.data.string = (char *)&context->storage[pos];
461 /* common tangeable object suffix */
462 pos += elem.len;
463 elem.complete = !context->list_nest_depth && !context->count[0];
464 if (!peek) {
465 if (!context->count[context->list_nest_depth] ||
466 !--(context->count[context->list_nest_depth])) {
467 context->list_stop = true;
468 }
469 context->pos = pos;
470 }
471 return elem;
472
473 case EVENT_TYPE_LIST:
474 if ((pos + sizeof(uint8_t)) > context->len) {
475 elem.type = EVENT_TYPE_UNKNOWN;
476 elem.complete = true;
477 return elem;
478 }
479 elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
480 if (peek) {
481 return elem;
482 }
483 if (context->count[context->list_nest_depth]) {
484 context->count[context->list_nest_depth]--;
485 }
486 context->list_stop = !context->storage[pos];
487 context->list_nest_depth++;
488 if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
489 context->count[context->list_nest_depth] = context->storage[pos];
490 }
491 context->pos = pos + sizeof(uint8_t);
492 return elem;
493
494 case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
495 if (!peek) {
496 context->pos = pos;
497 }
498 elem.type = EVENT_TYPE_UNKNOWN;
499 elem.complete = !context->list_nest_depth;
500 if (context->list_nest_depth > 0) {
501 elem.type = EVENT_TYPE_LIST_STOP;
502 if (!peek) {
503 context->list_nest_depth--;
504 }
505 }
506 return elem;
507
508 default:
509 elem.type = EVENT_TYPE_UNKNOWN;
510 return elem;
511 }
512}
513
514android_log_list_element android_log_read_next(android_log_context ctx) {
515 return android_log_read_next_internal(ctx, 0);
516}
517
518android_log_list_element android_log_peek_next(android_log_context ctx) {
519 return android_log_read_next_internal(ctx, 1);
520}