1c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <stdio.h> 2c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <string.h> 3c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <stdlib.h> 4c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 5c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "mapinfo.h" 6c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 7c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevextern void *__real_malloc(size_t size); 8c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevextern void __real_free(void *ptr); 9c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 10c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#if 0 11c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev while (p <= end) { 12c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); 13c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev _LOG(tfd, (sp_depth > 2) || only_in_tombstone, 14c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev " %08x %08x %s\n", p, data, 15c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev map_to_name(map, data, "")); 16c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev p += 4; 17c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 18c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#endif 19c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 20c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so 21c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev// 012345678901234567890123456789012345678901234567890123456789 22c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev// 0 1 2 3 4 5 23c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 24c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic mapinfo *parse_maps_line(char *line) 25c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 26c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mapinfo *mi; 27c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int len = strlen(line); 28c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 29c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(len < 1) return 0; 30c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev line[--len] = 0; 31c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 32c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(len < 50) return 0; 33c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(line[20] != 'x') return 0; 34c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 35c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mi = __real_malloc(sizeof(mapinfo) + (len - 47)); 36c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(mi == 0) return 0; 37c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 38c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mi->start = strtoul(line, 0, 16); 39c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mi->end = strtoul(line + 9, 0, 16); 40c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* To be filled in parse_elf_info if the mapped section starts with 41c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * elf_header 42c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */ 43c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mi->next = 0; 44c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev strcpy(mi->name, line + 49); 45c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 46c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return mi; 47c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 48c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 49c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevmapinfo *init_mapinfo(int pid) 50c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 51c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev struct mapinfo *milist = NULL; 52c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev char data[1024]; 53c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev sprintf(data, "/proc/%d/maps", pid); 54c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev FILE *fp = fopen(data, "r"); 55c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(fp) { 56c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev while(fgets(data, sizeof(data), fp)) { 57c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mapinfo *mi = parse_maps_line(data); 58c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(mi) { 59c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mi->next = milist; 60c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev milist = mi; 61c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 62c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 63c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev fclose(fp); 64c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 65c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 66c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return milist; 67c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 68c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 69c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid deinit_mapinfo(mapinfo *mi) 70c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 71c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mapinfo *del; 72c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev while(mi) { 73c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev del = mi; 74c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mi = mi->next; 75c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev __real_free(del); 76c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 77c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 78c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 79c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/* Map a pc address to the name of the containing ELF file */ 80c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst char *map_to_name(mapinfo *mi, unsigned pc, const char* def) 81c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 82c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev while(mi) { 83c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if((pc >= mi->start) && (pc < mi->end)){ 84c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return mi->name; 85c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 86c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mi = mi->next; 87c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 88c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return def; 89c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 90c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 91c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/* Find the containing map info for the pc */ 92c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst mapinfo *pc_to_mapinfo(mapinfo *mi, unsigned pc, unsigned *rel_pc) 93c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 94c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *rel_pc = pc; 95c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev while(mi) { 96c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if((pc >= mi->start) && (pc < mi->end)){ 97c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Only calculate the relative offset for shared libraries 98c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (strstr(mi->name, ".so")) { 99c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *rel_pc -= mi->start; 100c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 101c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return mi; 102c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 103c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mi = mi->next; 104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NULL; 106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 107