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