1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 
5 #include "mapinfo.h"
6 
7 extern void *__real_malloc(size_t size);
8 extern 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 
parse_maps_line(char * line)24 static 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 
init_mapinfo(int pid)49 mapinfo *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 
deinit_mapinfo(mapinfo * mi)69 void 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 */
map_to_name(mapinfo * mi,unsigned pc,const char * def)80 const 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 */
pc_to_mapinfo(mapinfo * mi,unsigned pc,unsigned * rel_pc)92 const 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