The Go Programming Language

Text file src/libmach/6obj.c

     1	// Inferno libmach/6obj.c
     2	// http://code.google.com/p/inferno-os/source/browse/utils/libmach/6obj.c
     3	//
     4	// 	Copyright © 1994-1999 Lucent Technologies Inc.
     5	// 	Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
     6	// 	Portions Copyright © 1997-1999 Vita Nuova Limited.
     7	// 	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
     8	// 	Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
     9	//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    10	//
    11	// Permission is hereby granted, free of charge, to any person obtaining a copy
    12	// of this software and associated documentation files (the "Software"), to deal
    13	// in the Software without restriction, including without limitation the rights
    14	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    15	// copies of the Software, and to permit persons to whom the Software is
    16	// furnished to do so, subject to the following conditions:
    17	//
    18	// The above copyright notice and this permission notice shall be included in
    19	// all copies or substantial portions of the Software.
    20	//
    21	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    22	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    23	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    24	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    25	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    26	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    27	// THE SOFTWARE.
    28	
    29	/*
    30	 * 6obj.c - identify and parse an amd64 object file
    31	 */
    32	#include <u.h>
    33	#include <libc.h>
    34	#include <bio.h>
    35	#include <mach.h>
    36	#include "../cmd/6l/6.out.h"
    37	#include "obj.h"
    38	
    39	typedef struct Addr	Addr;
    40	struct Addr
    41	{
    42		char	sym;
    43		char	flags;
    44		char gotype;
    45	};
    46	static	Addr	addr(Biobuf*);
    47	static	char	type2char(int);
    48	static	void	skip(Biobuf*, int);
    49	
    50	int
    51	_is6(char *t)
    52	{
    53		uchar *s = (uchar*)t;
    54	
    55		return  s[0] == (ANAME&0xff)			/* aslo = ANAME */
    56			&& s[1] == ((ANAME>>8)&0xff)
    57			&& s[2] == D_FILE			/* type */
    58			&& s[3] == 1				/* sym */
    59			&& s[4] == '<';				/* name of file */
    60	}
    61	
    62	int
    63	_read6(Biobuf *bp, Prog* p)
    64	{
    65		int as, n, c;
    66		Addr a;
    67	
    68		as = Bgetc(bp);		/* as(low) */
    69		if(as < 0)
    70			return 0;
    71		c = Bgetc(bp);		/* as(high) */
    72		if(c < 0)
    73			return 0;
    74		as |= ((c & 0xff) << 8);
    75		p->kind = aNone;
    76		p->sig = 0;
    77		if(as == ANAME || as == ASIGNAME){
    78			if(as == ASIGNAME){
    79				Bread(bp, &p->sig, 4);
    80				p->sig = leswal(p->sig);
    81			}
    82			p->kind = aName;
    83			p->type = type2char(Bgetc(bp));		/* type */
    84			p->sym = Bgetc(bp);			/* sym */
    85			n = 0;
    86			for(;;) {
    87				as = Bgetc(bp);
    88				if(as < 0)
    89					return 0;
    90				n++;
    91				if(as == 0)
    92					break;
    93			}
    94			p->id = malloc(n);
    95			if(p->id == 0)
    96				return 0;
    97			Bseek(bp, -n, 1);
    98			if(Bread(bp, p->id, n) != n)
    99				return 0;
   100			return 1;
   101		}
   102		if(as == ATEXT)
   103			p->kind = aText;
   104		if(as == AGLOBL)
   105			p->kind = aData;
   106		skip(bp, 4);		/* lineno(4) */
   107		a = addr(bp);
   108		addr(bp);
   109		if(!(a.flags & T_SYM))
   110			p->kind = aNone;
   111		p->sym = a.sym;
   112		return 1;
   113	}
   114	
   115	static Addr
   116	addr(Biobuf *bp)
   117	{
   118		Addr a;
   119		int t;
   120		int32 l;
   121		vlong off;
   122	
   123		off = 0;
   124		a.sym = -1;
   125		a.flags = Bgetc(bp);			/* flags */
   126		a.gotype = 0;
   127		if(a.flags & T_INDEX)
   128			skip(bp, 2);
   129		if(a.flags & T_OFFSET){
   130			l = Bgetc(bp);
   131			l |= Bgetc(bp) << 8;
   132			l |= Bgetc(bp) << 16;
   133			l |= Bgetc(bp) << 24;
   134			off = l;
   135			if(a.flags & T_64){
   136				l = Bgetc(bp);
   137				l |= Bgetc(bp) << 8;
   138				l |= Bgetc(bp) << 16;
   139				l |= Bgetc(bp) << 24;
   140				off = ((vlong)l << 32) | (off & 0xFFFFFFFF);
   141			}
   142			if(off < 0)
   143				off = -off;
   144		}
   145		if(a.flags & T_SYM)
   146			a.sym = Bgetc(bp);
   147		if(a.flags & T_FCONST)
   148			skip(bp, 8);
   149		else
   150		if(a.flags & T_SCONST)
   151			skip(bp, NSNAME);
   152		if(a.flags & T_TYPE) {
   153			t = Bgetc(bp);
   154			if(a.sym > 0 && (t==D_PARAM || t==D_AUTO))
   155				_offset(a.sym, off);
   156		}
   157		if(a.flags & T_GOTYPE)
   158			a.gotype = Bgetc(bp);
   159		return a;
   160	}
   161	
   162	static char
   163	type2char(int t)
   164	{
   165		switch(t){
   166		case D_EXTERN:		return 'U';
   167		case D_STATIC:		return 'b';
   168		case D_AUTO:		return 'a';
   169		case D_PARAM:		return 'p';
   170		default:		return UNKNOWN;
   171		}
   172	}
   173	
   174	static void
   175	skip(Biobuf *bp, int n)
   176	{
   177		while (n-- > 0)
   178			Bgetc(bp);
   179	}

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