The Go Programming Language

Text file src/libmach/5obj.c

     1	// Inferno libmach/5obj.c
     2	// http://code.google.com/p/inferno-os/source/browse/utils/libmach/5obj.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	 * 5obj.c - identify and parse an arm object file
    31	 */
    32	#include <u.h>
    33	#include <libc.h>
    34	#include <bio.h>
    35	#include <mach.h>
    36	#include "../cmd/5l/5.out.h"
    37	#include "obj.h"
    38	
    39	typedef struct Addr	Addr;
    40	struct Addr
    41	{
    42		char	type;
    43		char	sym;
    44		char	name;
    45	};
    46	static Addr addr(Biobuf*);
    47	static char type2char(int);
    48	static void skip(Biobuf*, int);
    49	
    50	int
    51	_is5(char *s)
    52	{
    53		return  s[0] == ANAME				/* ANAME */
    54			&& s[1] == D_FILE			/* type */
    55			&& s[2] == 1				/* sym */
    56			&& s[3] == '<';				/* name of file */
    57	}
    58	
    59	int
    60	_read5(Biobuf *bp, Prog *p)
    61	{
    62		int as, n;
    63		Addr a;
    64	
    65		as = Bgetc(bp);			/* as */
    66		if(as < 0)
    67			return 0;
    68		p->kind = aNone;
    69		p->sig = 0;
    70		if(as == ANAME || as == ASIGNAME){
    71			if(as == ASIGNAME){
    72				Bread(bp, &p->sig, 4);
    73				p->sig = leswal(p->sig);
    74			}
    75			p->kind = aName;
    76			p->type = type2char(Bgetc(bp));		/* type */
    77			p->sym = Bgetc(bp);			/* sym */
    78			n = 0;
    79			for(;;) {
    80				as = Bgetc(bp);
    81				if(as < 0)
    82					return 0;
    83				n++;
    84				if(as == 0)
    85					break;
    86			}
    87			p->id = malloc(n);
    88			if(p->id == 0)
    89				return 0;
    90			Bseek(bp, -n, 1);
    91			if(Bread(bp, p->id, n) != n)
    92				return 0;
    93			return 1;
    94		}
    95		if(as == ATEXT)
    96			p->kind = aText;
    97		else if(as == AGLOBL)
    98			p->kind = aData;
    99		skip(bp, 6);		/* scond(1), reg(1), lineno(4) */
   100		a = addr(bp);
   101		addr(bp);
   102		if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN)
   103			p->kind = aNone;
   104		p->sym = a.sym;
   105		return 1;
   106	}
   107	
   108	static Addr
   109	addr(Biobuf *bp)
   110	{
   111		Addr a;
   112		long off;
   113	
   114		a.type = Bgetc(bp);	/* a.type */
   115		skip(bp,1);		/* reg */
   116		a.sym = Bgetc(bp);	/* sym index */
   117		a.name = Bgetc(bp);	/* sym type */
   118		switch(a.type){
   119		default:
   120		case D_NONE:
   121		case D_REG:
   122		case D_FREG:
   123		case D_PSR:
   124		case D_FPCR:
   125			break;
   126		case D_REGREG:
   127			Bgetc(bp);
   128			break;
   129		case D_CONST2:
   130			Bgetc(bp);
   131			Bgetc(bp);
   132			Bgetc(bp);
   133			Bgetc(bp);	// fall through
   134		case D_OREG:
   135		case D_CONST:
   136		case D_BRANCH:
   137		case D_SHIFT:
   138			off = Bgetc(bp);
   139			off |= Bgetc(bp) << 8;
   140			off |= Bgetc(bp) << 16;
   141			off |= Bgetc(bp) << 24;
   142			if(off < 0)
   143				off = -off;
   144			if(a.sym && (a.name==D_PARAM || a.name==D_AUTO))
   145				_offset(a.sym, off);
   146			break;
   147		case D_SCONST:
   148			skip(bp, NSNAME);
   149			break;
   150		case D_FCONST:
   151			skip(bp, 8);
   152			break;
   153		}
   154		return a;
   155	}
   156	
   157	static char
   158	type2char(int t)
   159	{
   160		switch(t){
   161		case D_EXTERN:		return 'U';
   162		case D_STATIC:		return 'b';
   163		case D_AUTO:		return 'a';
   164		case D_PARAM:		return 'p';
   165		default:		return UNKNOWN;
   166		}
   167	}
   168	
   169	static void
   170	skip(Biobuf *bp, int n)
   171	{
   172		while (n-- > 0)
   173			Bgetc(bp);
   174	}

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