blob: 8303b63393b7299cc1dacfea1cae3317a48823de [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
Mark Salyzyn472245d2016-11-18 10:45:45 -080025#include <log/log_event_list.h>
Mark Salyzyn6debf982016-10-05 08:13:56 -070026#include <private/android_logger.h>
Mark Salyzyn9dd65102016-02-17 16:08:13 -080027
Mark Salyzynfacf94c2016-03-01 13:45:42 -080028#include "log_portability.h"
Mark Salyzyn6d753fa2016-03-10 08:25:33 -080029
Mark Salyzyn9dd65102016-02-17 16:08:13 -080030#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
31
32typedef struct {
33 uint32_t tag;
34 unsigned pos; /* Read/write position into buffer */
35 unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements */
36 unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* pos for list counter */
37 unsigned list_nest_depth;
38 unsigned len; /* Length or raw buffer. */
39 bool overflow;
40 bool list_stop; /* next call decrement list_nest_depth and issue a stop */
41 enum {
42 kAndroidLoggerRead = 1,
43 kAndroidLoggerWrite = 2,
44 } read_write_flag;
45 uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
46} android_log_context_internal;
47
Mark Salyzyn6d753fa2016-03-10 08:25:33 -080048LIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -080049 size_t needed, i;
50 android_log_context_internal *context;
51
52 context = calloc(1, sizeof(android_log_context_internal));
53 if (!context) {
54 return NULL;
55 }
56 context->tag = tag;
57 context->read_write_flag = kAndroidLoggerWrite;
58 needed = sizeof(uint8_t) + sizeof(uint8_t);
59 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
60 context->overflow = true;
61 }
62 /* Everything is a list */
63 context->storage[context->pos + 0] = EVENT_TYPE_LIST;
64 context->list[0] = context->pos + 1;
65 context->pos += needed;
66
67 return (android_log_context)context;
68}
69
Mark Salyzyn6d753fa2016-03-10 08:25:33 -080070LIBLOG_ABI_PUBLIC android_log_context create_android_log_parser(
71 const char *msg,
72 size_t len) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -080073 android_log_context_internal *context;
74 size_t i;
75
76 context = calloc(1, sizeof(android_log_context_internal));
77 if (!context) {
78 return NULL;
79 }
80 len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
81 context->len = len;
82 memcpy(context->storage, msg, len);
83 context->read_write_flag = kAndroidLoggerRead;
84
85 return (android_log_context)context;
86}
87
Mark Salyzyn6d753fa2016-03-10 08:25:33 -080088LIBLOG_ABI_PUBLIC int android_log_destroy(android_log_context *ctx) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -080089 android_log_context_internal *context;
90
91 context = (android_log_context_internal *)*ctx;
92 if (!context) {
93 return -EBADF;
94 }
95 memset(context, 0, sizeof(*context));
96 free(context);
97 *ctx = NULL;
98 return 0;
99}
100
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800101LIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800102 size_t needed;
103 android_log_context_internal *context;
104
105 context = (android_log_context_internal *)ctx;
106 if (!context ||
107 (kAndroidLoggerWrite != context->read_write_flag)) {
108 return -EBADF;
109 }
110 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
111 context->overflow = true;
112 return -EOVERFLOW;
113 }
114 needed = sizeof(uint8_t) + sizeof(uint8_t);
115 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
116 context->overflow = true;
117 return -EIO;
118 }
119 context->count[context->list_nest_depth]++;
120 context->list_nest_depth++;
121 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
122 context->overflow = true;
123 return -EOVERFLOW;
124 }
125 if (context->overflow) {
126 return -EIO;
127 }
128 context->storage[context->pos + 0] = EVENT_TYPE_LIST;
129 context->storage[context->pos + 1] = 0;
130 context->list[context->list_nest_depth] = context->pos + 1;
131 context->count[context->list_nest_depth] = 0;
132 context->pos += needed;
133 return 0;
134}
135
136static inline void copy4LE(uint8_t *buf, uint32_t val)
137{
138 buf[0] = val & 0xFF;
139 buf[1] = (val >> 8) & 0xFF;
140 buf[2] = (val >> 16) & 0xFF;
141 buf[3] = (val >> 24) & 0xFF;
142}
143
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800144LIBLOG_ABI_PUBLIC int android_log_write_int32(android_log_context ctx,
145 int32_t value) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800146 size_t needed;
147 android_log_context_internal *context;
148
149 context = (android_log_context_internal *)ctx;
150 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
151 return -EBADF;
152 }
153 if (context->overflow) {
154 return -EIO;
155 }
156 needed = sizeof(uint8_t) + sizeof(value);
157 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
158 context->overflow = true;
159 return -EIO;
160 }
161 context->count[context->list_nest_depth]++;
162 context->storage[context->pos + 0] = EVENT_TYPE_INT;
163 copy4LE(&context->storage[context->pos + 1], value);
164 context->pos += needed;
165 return 0;
166}
167
168static inline void copy8LE(uint8_t *buf, uint64_t val)
169{
170 buf[0] = val & 0xFF;
171 buf[1] = (val >> 8) & 0xFF;
172 buf[2] = (val >> 16) & 0xFF;
173 buf[3] = (val >> 24) & 0xFF;
174 buf[4] = (val >> 32) & 0xFF;
175 buf[5] = (val >> 40) & 0xFF;
176 buf[6] = (val >> 48) & 0xFF;
177 buf[7] = (val >> 56) & 0xFF;
178}
179
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800180LIBLOG_ABI_PUBLIC int android_log_write_int64(android_log_context ctx,
181 int64_t value) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800182 size_t needed;
183 android_log_context_internal *context;
184
185 context = (android_log_context_internal *)ctx;
186 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
187 return -EBADF;
188 }
189 if (context->overflow) {
190 return -EIO;
191 }
192 needed = sizeof(uint8_t) + sizeof(value);
193 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
194 context->overflow = true;
195 return -EIO;
196 }
197 context->count[context->list_nest_depth]++;
198 context->storage[context->pos + 0] = EVENT_TYPE_LONG;
199 copy8LE(&context->storage[context->pos + 1], value);
200 context->pos += needed;
201 return 0;
202}
203
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800204LIBLOG_ABI_PUBLIC int android_log_write_string8_len(android_log_context ctx,
205 const char *value,
206 size_t maxlen) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800207 size_t needed;
Mark Salyzyn1d5afc92016-02-25 08:41:25 -0800208 ssize_t len;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800209 android_log_context_internal *context;
210
211 context = (android_log_context_internal *)ctx;
212 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
213 return -EBADF;
214 }
215 if (context->overflow) {
216 return -EIO;
217 }
218 if (!value) {
Mark Salyzyn1d5afc92016-02-25 08:41:25 -0800219 value = "";
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800220 }
Mark Salyzyn1d5afc92016-02-25 08:41:25 -0800221 len = strnlen(value, maxlen);
222 needed = sizeof(uint8_t) + sizeof(int32_t) + len;
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800223 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
224 /* Truncate string for delivery */
Mark Salyzyn1d5afc92016-02-25 08:41:25 -0800225 len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800226 if (len <= 0) {
227 context->overflow = true;
228 return -EIO;
229 }
230 }
231 context->count[context->list_nest_depth]++;
232 context->storage[context->pos + 0] = EVENT_TYPE_STRING;
233 copy4LE(&context->storage[context->pos + 1], len);
Mark Salyzyn1d5afc92016-02-25 08:41:25 -0800234 if (len) {
235 memcpy(&context->storage[context->pos + 5], value, len);
236 }
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800237 context->pos += needed;
Mark Salyzyn1d5afc92016-02-25 08:41:25 -0800238 return len;
239}
240
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800241LIBLOG_ABI_PUBLIC int android_log_write_string8(android_log_context ctx,
242 const char *value) {
Mark Salyzyn1d5afc92016-02-25 08:41:25 -0800243 return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800244}
245
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800246LIBLOG_ABI_PUBLIC int android_log_write_float32(android_log_context ctx,
247 float value) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800248 size_t needed;
249 uint32_t ivalue;
250 android_log_context_internal *context;
251
252 context = (android_log_context_internal *)ctx;
253 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
254 return -EBADF;
255 }
256 if (context->overflow) {
257 return -EIO;
258 }
259 needed = sizeof(uint8_t) + sizeof(ivalue);
260 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
261 context->overflow = true;
262 return -EIO;
263 }
264 ivalue = *(uint32_t *)&value;
265 context->count[context->list_nest_depth]++;
266 context->storage[context->pos + 0] = EVENT_TYPE_FLOAT;
267 copy4LE(&context->storage[context->pos + 1], ivalue);
268 context->pos += needed;
269 return 0;
270}
271
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800272LIBLOG_ABI_PUBLIC int android_log_write_list_end(android_log_context ctx) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800273 android_log_context_internal *context;
274
275 context = (android_log_context_internal *)ctx;
276 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
277 return -EBADF;
278 }
279 if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
280 context->overflow = true;
281 context->list_nest_depth--;
282 return -EOVERFLOW;
283 }
284 if (!context->list_nest_depth) {
285 context->overflow = true;
286 return -EOVERFLOW;
287 }
288 if (context->list[context->list_nest_depth] <= 0) {
289 context->list_nest_depth--;
290 context->overflow = true;
291 return -EOVERFLOW;
292 }
293 context->storage[context->list[context->list_nest_depth]] =
294 context->count[context->list_nest_depth];
295 context->list_nest_depth--;
296 return 0;
297}
298
299/*
300 * Logs the list of elements to the event log.
301 */
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800302LIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx,
303 log_id_t id) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800304 android_log_context_internal *context;
305 const char *msg;
306 ssize_t len;
307
308 if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY)) {
309 return -EINVAL;
310 }
311
312 context = (android_log_context_internal *)ctx;
313 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
314 return -EBADF;
315 }
316 if (context->list_nest_depth) {
317 return -EIO;
318 }
319 /* NB: if there was overflow, then log is truncated. Nothing reported */
320 context->storage[1] = context->count[0];
321 len = context->len = context->pos;
322 msg = (const char *)context->storage;
323 /* it'snot a list */
324 if (context->count[0] <= 1) {
325 len -= sizeof(uint8_t) + sizeof(uint8_t);
326 if (len < 0) {
327 len = 0;
328 }
329 msg += sizeof(uint8_t) + sizeof(uint8_t);
330 }
331 return (id == LOG_ID_EVENTS) ?
332 __android_log_bwrite(context->tag, msg, len) :
333 __android_log_security_bwrite(context->tag, msg, len);
334}
335
336/*
337 * Extract a 4-byte value from a byte stream.
338 */
339static inline uint32_t get4LE(const uint8_t* src)
340{
341 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
342}
343
344/*
345 * Extract an 8-byte value from a byte stream.
346 */
347static inline uint64_t get8LE(const uint8_t* src)
348{
349 uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
350 uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
351 return ((uint64_t) high << 32) | (uint64_t) low;
352}
353
354/*
355 * Gets the next element. Parsing errors result in an EVENT_TYPE_UNKNOWN type.
356 * If there is nothing to process, the complete field is set to non-zero. If
357 * an EVENT_TYPE_UNKNOWN type is returned once, and the caller does not check
358 * this and continues to call this function, the behavior is undefined
359 * (although it won't crash).
360 */
361static android_log_list_element android_log_read_next_internal(
362 android_log_context ctx, int peek) {
363 android_log_list_element elem;
364 unsigned pos;
365 android_log_context_internal *context;
366
367 context = (android_log_context_internal *)ctx;
368
369 memset(&elem, 0, sizeof(elem));
370
371 /* Nothing to parse from this context, so return complete. */
372 if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
373 (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
374 (context->count[context->list_nest_depth] >=
375 (MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
376 elem.type = EVENT_TYPE_UNKNOWN;
377 if (context &&
378 (context->list_stop ||
379 ((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
380 !context->count[context->list_nest_depth]))) {
381 elem.type = EVENT_TYPE_LIST_STOP;
382 }
383 elem.complete = true;
384 return elem;
385 }
386
387 /*
388 * Use a different variable to update the position in case this
389 * operation is a "peek".
390 */
391 pos = context->pos;
392 if (context->list_stop) {
393 elem.type = EVENT_TYPE_LIST_STOP;
394 elem.complete = !context->count[0] && (!context->list_nest_depth ||
395 ((context->list_nest_depth == 1) && !context->count[1]));
396 if (!peek) {
397 /* Suck in superfluous stop */
398 if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
399 context->pos = pos + 1;
400 }
401 if (context->list_nest_depth) {
402 --context->list_nest_depth;
403 if (context->count[context->list_nest_depth]) {
404 context->list_stop = false;
405 }
406 } else {
407 context->list_stop = false;
408 }
409 }
410 return elem;
411 }
412 if ((pos + 1) > context->len) {
413 elem.type = EVENT_TYPE_UNKNOWN;
414 elem.complete = true;
415 return elem;
416 }
417
418 elem.type = context->storage[pos++];
419 switch ((int)elem.type) {
420 case EVENT_TYPE_FLOAT:
421 /* Rely on union to translate elem.data.int32 into elem.data.float32 */
422 /* FALLTHRU */
423 case EVENT_TYPE_INT:
424 elem.len = sizeof(int32_t);
425 if ((pos + elem.len) > context->len) {
426 elem.type = EVENT_TYPE_UNKNOWN;
427 return elem;
428 }
429 elem.data.int32 = get4LE(&context->storage[pos]);
430 /* common tangeable object suffix */
431 pos += elem.len;
432 elem.complete = !context->list_nest_depth && !context->count[0];
433 if (!peek) {
434 if (!context->count[context->list_nest_depth] ||
435 !--(context->count[context->list_nest_depth])) {
436 context->list_stop = true;
437 }
438 context->pos = pos;
439 }
440 return elem;
441
442 case EVENT_TYPE_LONG:
443 elem.len = sizeof(int64_t);
444 if ((pos + elem.len) > context->len) {
445 elem.type = EVENT_TYPE_UNKNOWN;
446 return elem;
447 }
448 elem.data.int64 = get8LE(&context->storage[pos]);
449 /* common tangeable object suffix */
450 pos += elem.len;
451 elem.complete = !context->list_nest_depth && !context->count[0];
452 if (!peek) {
453 if (!context->count[context->list_nest_depth] ||
454 !--(context->count[context->list_nest_depth])) {
455 context->list_stop = true;
456 }
457 context->pos = pos;
458 }
459 return elem;
460
461 case EVENT_TYPE_STRING:
462 if ((pos + sizeof(int32_t)) > context->len) {
463 elem.type = EVENT_TYPE_UNKNOWN;
464 elem.complete = true;
465 return elem;
466 }
467 elem.len = get4LE(&context->storage[pos]);
468 pos += sizeof(int32_t);
469 if ((pos + elem.len) > context->len) {
470 elem.len = context->len - pos; /* truncate string */
471 elem.complete = true;
472 if (!elem.len) {
473 elem.type = EVENT_TYPE_UNKNOWN;
474 return elem;
475 }
476 }
477 elem.data.string = (char *)&context->storage[pos];
478 /* common tangeable object suffix */
479 pos += elem.len;
480 elem.complete = !context->list_nest_depth && !context->count[0];
481 if (!peek) {
482 if (!context->count[context->list_nest_depth] ||
483 !--(context->count[context->list_nest_depth])) {
484 context->list_stop = true;
485 }
486 context->pos = pos;
487 }
488 return elem;
489
490 case EVENT_TYPE_LIST:
491 if ((pos + sizeof(uint8_t)) > context->len) {
492 elem.type = EVENT_TYPE_UNKNOWN;
493 elem.complete = true;
494 return elem;
495 }
496 elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
497 if (peek) {
498 return elem;
499 }
500 if (context->count[context->list_nest_depth]) {
501 context->count[context->list_nest_depth]--;
502 }
503 context->list_stop = !context->storage[pos];
504 context->list_nest_depth++;
505 if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
506 context->count[context->list_nest_depth] = context->storage[pos];
507 }
508 context->pos = pos + sizeof(uint8_t);
509 return elem;
510
511 case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
512 if (!peek) {
513 context->pos = pos;
514 }
515 elem.type = EVENT_TYPE_UNKNOWN;
516 elem.complete = !context->list_nest_depth;
517 if (context->list_nest_depth > 0) {
518 elem.type = EVENT_TYPE_LIST_STOP;
519 if (!peek) {
520 context->list_nest_depth--;
521 }
522 }
523 return elem;
524
525 default:
526 elem.type = EVENT_TYPE_UNKNOWN;
527 return elem;
528 }
529}
530
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800531LIBLOG_ABI_PUBLIC android_log_list_element android_log_read_next(
532 android_log_context ctx) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800533 return android_log_read_next_internal(ctx, 0);
534}
535
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800536LIBLOG_ABI_PUBLIC android_log_list_element android_log_peek_next(
537 android_log_context ctx) {
Mark Salyzyn9dd65102016-02-17 16:08:13 -0800538 return android_log_read_next_internal(ctx, 1);
539}