The Go Programming Language

Text file src/libmach/map.c

     1	// Derived from Inferno libmach/map.c and
     2	// Plan 9 from User Space src/libmach/map.c
     3	//
     4	// http://code.swtch.com/plan9port/src/tip/src/libmach/map.c
     5	// http://code.google.com/p/inferno-os/source/browse/utils/libmach/map.c
     6	//
     7	//
     8	//	Copyright © 1994-1999 Lucent Technologies Inc.
     9	//	Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
    10	//	Portions Copyright © 1997-1999 Vita Nuova Limited.
    11	//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
    12	//	Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
    13	//	Portions Copyright © 2001-2007 Russ Cox.
    14	//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    15	//
    16	// Permission is hereby granted, free of charge, to any person obtaining a copy
    17	// of this software and associated documentation files (the "Software"), to deal
    18	// in the Software without restriction, including without limitation the rights
    19	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    20	// copies of the Software, and to permit persons to whom the Software is
    21	// furnished to do so, subject to the following conditions:
    22	//
    23	// The above copyright notice and this permission notice shall be included in
    24	// all copies or substantial portions of the Software.
    25	//
    26	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    27	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    28	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    29	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    30	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    31	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    32	// THE SOFTWARE.
    33	
    34	/*
    35	 * file map routines
    36	 */
    37	#include <u.h>
    38	#include <libc.h>
    39	#include <bio.h>
    40	#include <mach.h>
    41	
    42	Map *
    43	newmap(Map *map, int n)
    44	{
    45		int size;
    46	
    47		size = sizeof(Map)+(n-1)*sizeof(Seg);
    48		if (map == 0)
    49			map = malloc(size);
    50		else
    51			map = realloc(map, size);
    52		if (map == 0) {
    53			werrstr("out of memory: %r");
    54			return 0;
    55		}
    56		memset(map, 0, size);
    57		map->nsegs = n;
    58		return map;
    59	}
    60	
    61	int
    62	setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name, Maprw *rw)
    63	{
    64		int i;
    65	
    66		if (map == 0)
    67			return 0;
    68		for (i = 0; i < map->nsegs; i++)
    69			if (!map->seg[i].inuse)
    70				break;
    71		if (i >= map->nsegs)
    72			return 0;
    73		map->seg[i].b = b;
    74		map->seg[i].e = e;
    75		map->seg[i].f = f;
    76		map->seg[i].inuse = 1;
    77		map->seg[i].name = name;
    78		map->seg[i].fd = fd;
    79		map->seg[i].rw = rw;
    80		return 1;
    81	}
    82	
    83	/*
    84	static uvlong
    85	stacktop(int pid)
    86	{
    87		char buf[64];
    88		int fd;
    89		int n;
    90		char *cp;
    91	
    92		snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
    93		fd = open(buf, 0);
    94		if (fd < 0)
    95			return 0;
    96		n = read(fd, buf, sizeof(buf)-1);
    97		close(fd);
    98		buf[n] = 0;
    99		if (strncmp(buf, "Stack", 5))
   100			return 0;
   101		for (cp = buf+5; *cp && *cp == ' '; cp++)
   102			;
   103		if (!*cp)
   104			return 0;
   105		cp = strchr(cp, ' ');
   106		if (!cp)
   107			return 0;
   108		while (*cp && *cp == ' ')
   109			cp++;
   110		if (!*cp)
   111			return 0;
   112		return strtoull(cp, 0, 16);
   113	}
   114	*/
   115	
   116	int
   117	findseg(Map *map, char *name)
   118	{
   119		int i;
   120	
   121		if (!map)
   122			return -1;
   123		for (i = 0; i < map->nsegs; i++)
   124			if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
   125				return i;
   126		return -1;
   127	}
   128	
   129	void
   130	unusemap(Map *map, int i)
   131	{
   132		if (map != 0 && 0 <= i && i < map->nsegs)
   133			map->seg[i].inuse = 0;
   134	}
   135	
   136	int
   137	fdrw(Map *map, Seg *s, uvlong addr, void *v, uint n, int isread)
   138	{
   139		int tot, m;
   140	
   141		for(tot=0; tot<n; tot+=m){
   142			if(isread)
   143				m = pread(s->fd, (uchar*)v+tot, n-tot, addr+tot);
   144			else
   145				m = pwrite(s->fd, (uchar*)v+tot, n-tot, addr+tot);
   146			if(m == 0){
   147				werrstr("short %s", isread ? "read" : "write");
   148				return -1;
   149			}
   150			if(m < 0){
   151				werrstr("%s %d at %#llux (+%#llux): %r", isread ? "read" : "write", n, addr, s->f);
   152				return -1;
   153			}
   154		}
   155		return 0;
   156	}
   157	
   158	
   159	Map*
   160	loadmap(Map *map, int fd, Fhdr *fp)
   161	{
   162		map = newmap(map, 2);
   163		if (map == 0)
   164			return 0;
   165	
   166		map->seg[0].b = fp->txtaddr;
   167		map->seg[0].e = fp->txtaddr+fp->txtsz;
   168		map->seg[0].f = fp->txtoff;
   169		map->seg[0].fd = fd;
   170		map->seg[0].inuse = 1;
   171		map->seg[0].name = "text";
   172		map->seg[0].rw = fdrw;
   173		map->seg[1].b = fp->dataddr;
   174		map->seg[1].e = fp->dataddr+fp->datsz;
   175		map->seg[1].f = fp->datoff;
   176		map->seg[1].fd = fd;
   177		map->seg[1].inuse = 1;
   178		map->seg[1].name = "data";
   179		map->seg[0].rw = fdrw;
   180		return map;
   181	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.