1 /* -----------------------------------------------------------------------------
4 * This file provides access to the virtual memory map of a process
5 * including the location of the executable, data segments, shared
6 * libraries, and memory mapped regions.
8 * The primary purpose of this module is to collect this information
9 * and store it in a form that hides platform specific details (the
10 * WadSegment structure).
12 * Author(s) : David Beazley (beazley@cs.uchicago.edu)
14 * Copyright (C) 2000. The University of Chicago.
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 * See the file COPYING for a complete copy of the LGPL.
31 * ----------------------------------------------------------------------------- */
35 static char cvs[] = "$Id: segment.c 10001 2007-10-17 21:33:57Z wsfulton $";
37 /* Include the proper code for reading the segment map */
41 /* This code is used to read the process virtual memory map on Solaris machines */
46 f = open("/proc/self/map", O_RDONLY);
51 segment_read(int fs, WadSegment *s) {
56 n = read(fs, &pmap, sizeof(prmap_t));
58 s->mapname = wad_strdup(pmap.pr_mapname);
59 s->mappath = (char *) wad_malloc(20+strlen(pmap.pr_mapname));
60 wad_strcpy(s->mappath,"/proc/self/object/");
61 strcat(s->mappath,pmap.pr_mapname);
62 s->vaddr = (char *) pmap.pr_vaddr;
64 /* This is a solaris oddity. a.out section starts 1 page up, but
65 symbols are relative to a base of 0 */
67 if (strcmp(s->mapname,"a.out") == 0) s->base = 0;
68 else s->base = s->vaddr;
70 s->size = pmap.pr_size;
71 s->offset = pmap.pr_offset;
75 #endif /* WAD_SOLARIS */
78 static char linux_firstsegment[1024];
79 static int linux_first = 1;
84 f = fopen("/proc/self/maps", "r");
90 segment_read(int fd, WadSegment *s)
95 FILE *fs = (FILE *) fd;
96 c = fgets(pbuffer,1024,fs);
99 pbuffer[strlen(pbuffer)-1] = 0; /* Chop off endline */
101 /* Break up the field into records */
102 /* 0-8 : Starting address
103 9-17 : Ending Address
111 len = strlen(pbuffer);
116 s->mapname = wad_strdup(pbuffer+49);
117 s->mappath = s->mapname;
120 s->mappath = s->mapname;
123 wad_strcpy(linux_firstsegment, s->mappath);
126 s->vaddr = (char *) strtoul(pbuffer,NULL,16);
127 s->size = strtoul(pbuffer+9,NULL,16) - (long) (s->vaddr);
128 s->offset = strtoul(pbuffer+23,NULL,16);
129 if (strcmp(linux_firstsegment, s->mappath) == 0) {
138 #endif /* WAD_LINUX */
140 static WadSegment *segments = 0; /* Linked list of segments */
142 /* -----------------------------------------------------------------------------
145 * Read all of the memory segments into a linked list. Any previous segment
146 * map is simply lost. The only way to reclaim this memory is to call
147 * wad_release_memory().
148 * ----------------------------------------------------------------------------- */
154 WadSegment *s, *lasts;
161 s = (WadSegment *) wad_malloc(sizeof(WadSegment));
163 n = segment_read(fs,s);
165 if (wad_file_check(s->vaddr)) goto skip; /* Skip files we already loaded */
174 if (wad_debug_mode & DEBUG_SEGMENT) {
175 wad_printf("wad_segment: read : %08x-%08x, base=%x in %s\n", s->vaddr, ((char *) s->vaddr) + s->size, s->base, s->mappath);
182 /* -----------------------------------------------------------------------------
185 * Try to find the virtual memory segment corresponding to a virtual address.
186 * If a segment is mapped to a file, this function actually returns the *first*
187 * segment that is mapped. This is because symbol relocations are always
188 * performed relative to the beginning of the file (so we need the base address)
189 * ----------------------------------------------------------------------------- */
192 wad_segment_find(void *vaddr) {
195 char *addr = (char *)vaddr;
200 if (strcmp(s->mapname,ls->mapname) || (!strlen(ls->mapname))) {
201 ls = s; /* First segment for a given name */
203 if ((addr >= s->vaddr) && (addr < (s->vaddr + s->size))) {
204 if (wad_debug_mode & DEBUG_SEGMENT) {
205 wad_printf("wad_segment: %08x --> %08x-%08x in %s\n", vaddr, s->vaddr, ((char *) s->vaddr) + s->size, s->mappath);
214 /* -----------------------------------------------------------------------------
215 * wad_segment_valid()
217 * Checks to see if a memory address is valid or not based on data in the
219 * ----------------------------------------------------------------------------- */
221 int wad_segment_valid(void *vaddr) {
222 return wad_segment_find(vaddr) ? 1 : 0;