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