github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/libmach/5obj.c (about) 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 char gotype; 46 }; 47 static Addr addr(Biobuf*); 48 static char type2char(int); 49 static void skip(Biobuf*, int); 50 51 int 52 _is5(char *s) 53 { 54 return s[0] == ANAME /* ANAME */ 55 && s[1] == D_FILE /* type */ 56 && s[2] == 1 /* sym */ 57 && s[3] == '<'; /* name of file */ 58 } 59 60 int 61 _read5(Biobuf *bp, Prog *p) 62 { 63 int as, n; 64 Addr a; 65 66 as = BGETC(bp); /* as */ 67 if(as < 0) 68 return 0; 69 p->kind = aNone; 70 p->sig = 0; 71 if(as == ANAME || as == ASIGNAME){ 72 if(as == ASIGNAME){ 73 Bread(bp, &p->sig, 4); 74 p->sig = leswal(p->sig); 75 } 76 p->kind = aName; 77 p->type = type2char(BGETC(bp)); /* type */ 78 p->sym = BGETC(bp); /* sym */ 79 n = 0; 80 for(;;) { 81 as = BGETC(bp); 82 if(as < 0) 83 return 0; 84 n++; 85 if(as == 0) 86 break; 87 } 88 p->id = malloc(n); 89 if(p->id == 0) 90 return 0; 91 Bseek(bp, -n, 1); 92 if(Bread(bp, p->id, n) != n) 93 return 0; 94 return 1; 95 } 96 if(as == ATEXT) 97 p->kind = aText; 98 else if(as == AGLOBL) 99 p->kind = aData; 100 skip(bp, 6); /* scond(1), reg(1), lineno(4) */ 101 a = addr(bp); 102 addr(bp); 103 if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN) 104 p->kind = aNone; 105 p->sym = a.sym; 106 return 1; 107 } 108 109 static Addr 110 addr(Biobuf *bp) 111 { 112 Addr a; 113 long off; 114 115 a.type = BGETC(bp); /* a.type */ 116 skip(bp,1); /* reg */ 117 a.sym = BGETC(bp); /* sym index */ 118 a.name = BGETC(bp); /* sym type */ 119 a.gotype = BGETC(bp); /* go type */ 120 switch(a.type){ 121 default: 122 case D_NONE: 123 case D_REG: 124 case D_FREG: 125 case D_PSR: 126 case D_FPCR: 127 break; 128 case D_REGREG: 129 case D_REGREG2: 130 BGETC(bp); 131 break; 132 case D_CONST2: 133 BGETLE4(bp); // fall through 134 case D_OREG: 135 case D_CONST: 136 case D_BRANCH: 137 case D_SHIFT: 138 off = BGETLE4(bp); 139 if(off < 0) 140 off = -off; 141 if(a.sym && (a.name==D_PARAM || a.name==D_AUTO)) 142 _offset(a.sym, off); 143 break; 144 case D_SCONST: 145 skip(bp, NSNAME); 146 break; 147 case D_FCONST: 148 skip(bp, 8); 149 break; 150 } 151 return a; 152 } 153 154 static char 155 type2char(int t) 156 { 157 switch(t){ 158 case D_EXTERN: return 'U'; 159 case D_STATIC: return 'b'; 160 case D_AUTO: return 'a'; 161 case D_PARAM: return 'p'; 162 default: return UNKNOWN; 163 } 164 } 165 166 static void 167 skip(Biobuf *bp, int n) 168 { 169 while (n-- > 0) 170 BGETC(bp); 171 }