/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> #define DEVICE "/dev/seemplog" #define SZ_1M 0x100000 #define FOUR_MB (4 * SZ_1M) #define BLK_SIZE 256 #define BLK_HDR_SIZE 64 #define TS_SIZE 20 #define BLK_MAX_MSG_SZ (BLK_SIZE - BLK_HDR_SIZE) #define TASK_COMM_LEN 16 #define MAGIC 'z' #define SEEMP_CMD_RESERVE_RDBLKS _IOR(MAGIC, 1, int) #define SEEMP_CMD_RELEASE_RDBLKS _IO(MAGIC, 2) #define SEEMP_CMD_GET_RINGSZ _IOR(MAGIC, 3, int) #define SEEMP_CMD_GET_BLKSZ _IOR(MAGIC, 4, int) #define SEEMP_CMD_SET_MASK _IO(MAGIC, 5) #define SEEMP_CMD_SET_MAPPING _IO(MAGIC, 6) #define SEEMP_CMD_CHECK_FILTER _IOR(MAGIC, 7, int) #define SEEMP_CMD_DEBUG_START _IOR(MAGIC, 8, int) #define SEEMP_CMD_DEBUG_STOP _IOR(MAGIC, 9, int) struct read_range { int start_idx; int num; }; struct blk_payload { uint32_t api_id; char msg[BLK_MAX_MSG_SZ]; } __attribute__((packed)); struct seemp_logk_blk { uint8_t status; uint16_t len; uint8_t version; int32_t pid; int32_t uid; int32_t tid; int32_t sec; int32_t nsec; char ts[TS_SIZE]; char appname[TASK_COMM_LEN]; struct blk_payload payload; } __attribute__((packed)); void dump_blk_headers(char *ptr) { int i; struct seemp_logk_blk *temp; for (i = 0; i < (FOUR_MB / 256); i++) { temp = (struct seemp_logk_blk *)ptr; ptr += 256; } } void print_maps(int time) { char cmd[] = "/proc/%d/maps"; char cmd2[sizeof("/proc/-2147483648/maps")]; FILE *fp; size_t nread; char buf[1024]; snprintf(cmd2, sizeof(cmd2)-1, cmd, getpid()); fp = fopen(cmd2, "r"); if (fp == NULL) { exit(-1); } while ((nread = fread(buf, 1, sizeof(buf), fp)) > 0) fwrite(buf, 1, nread, stdout); fclose(fp); sleep(time); } void reserve_rdblks(int fd) { struct read_range rrange; ioctl(fd, SEEMP_CMD_RESERVE_RDBLKS, &rrange); } unsigned int get_ringsz(int fd) { unsigned int ringsz; ioctl(fd, SEEMP_CMD_GET_RINGSZ, &ringsz); return ringsz; } unsigned int get_blksz(int fd) { unsigned int blksz; ioctl(fd, SEEMP_CMD_GET_BLKSZ, &blksz); return blksz; } void write_to_file(char *ptr) { FILE *dumpfp = fopen("/data/local/tmp/dump", "wb"); int i; if (dumpfp == NULL) { exit(-1); } fwrite(ptr, 1, FOUR_MB, dumpfp); fclose(dumpfp); } void write_to_dev(int fd) { char ts[] = "IIIIIIIIIIIIIIIIIIII"; char appname[] = "JJJJJJJJJJJJJJJJ"; char msg[] = "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; struct seemp_logk_blk block; block.status = 0xff; block.len = 0x4242; block.version = 'C'; block.pid = 0x44444444; block.uid = 0x45454545; block.tid = 0x46464646; block.sec = 0x47474747; block.nsec = 0x48484848; strcpy(block.ts, ts); strcpy(block.appname, appname); block.payload.api_id = 0x51515151; strcpy(block.payload.msg, msg); } void do_mapping(void **ptr, int fd) { *ptr = mmap(NULL, FOUR_MB, 0x7, MAP_SHARED, fd, 0); if (*ptr == MAP_FAILED) { close(fd); exit(-1); } } void spam_mapped_region(char *ptr, int offset, int size) { int i; for (i = offset; i < size; i++) *(ptr + i) = 'A'; } void start_printk(int fd) { ioctl(fd, SEEMP_CMD_DEBUG_START, NULL); } void stop_printk(int fd) { ioctl(fd, SEEMP_CMD_DEBUG_STOP, NULL); } int main() { int fd; void *ptr; int i; fd = open(DEVICE, O_RDWR); if (fd == -1) { exit(-1); } start_printk(fd); do_mapping(&ptr, fd); for (i = 0; i < (FOUR_MB / 256); i++) write_to_dev(fd); dump_blk_headers(ptr); print_maps(5); write_to_file(ptr); stop_printk(fd); close(fd); munmap(ptr, FOUR_MB); return 0; }