changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/libmach/7obj.c

changeset 7186: 4dd5e2428c1d
author: cinap_lenrek@felloff.net
date: Fri, 03 May 2019 21:00:17 +0200
permissions: -rw-r--r--
description: libmach: initial arm64 support
1 /*
2  * 7obj.c - identify and parse an arm64 object file
3  */
4 #include <u.h>
5 #include <libc.h>
6 #include <bio.h>
7 #include <mach.h>
8 #include "7c/7.out.h"
9 #include "obj.h"
10 
11 typedef struct Addr Addr;
12 struct Addr
13 {
14  char type;
15  char sym;
16  char name;
17 };
18 static Addr addr(Biobuf*);
19 static char type2char(int);
20 static void skip(Biobuf*, int);
21 
22 int
23 _is7(char *s)
24 {
25  return s[0] == (ANAME&0xff) /* aslo = ANAME */
26  && s[1] == ((ANAME>>8)&0xff)
27  && s[2] == D_FILE /* type */
28  && s[3] == 1 /* sym */
29  && s[4] == '<'; /* name of file */
30 }
31 
32 int
33 _read7(Biobuf *bp, Prog *p)
34 {
35  int as, n;
36  Addr a;
37 
38  as = (uchar)Bgetc(bp); /* as */
39  as |= (uchar)Bgetc(bp)<<8;
40  if(as <= AXXX || as >= ALAST)
41  return 0;
42  p->kind = aNone;
43  p->sig = 0;
44  if(as == ANAME || as == ASIGNAME){
45  if(as == ASIGNAME){
46  Bread(bp, &p->sig, 4);
47  p->sig = leswal(p->sig);
48  }
49  p->kind = aName;
50  p->type = type2char(Bgetc(bp)); /* type */
51  p->sym = Bgetc(bp); /* sym */
52  n = 0;
53  for(;;) {
54  as = Bgetc(bp);
55  if(as < 0)
56  return 0;
57  n++;
58  if(as == 0)
59  break;
60  }
61  p->id = malloc(n);
62  if(p->id == 0)
63  return 0;
64  Bseek(bp, -n, 1);
65  if(Bread(bp, p->id, n) != n)
66  return 0;
67  return 1;
68  }
69  if(as == ATEXT)
70  p->kind = aText;
71  else if(as == AGLOBL)
72  p->kind = aData;
73  skip(bp, 5); /* reg(1) lineno(4) */
74  a = addr(bp);
75  addr(bp);
76  if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN)
77  p->kind = aNone;
78  p->sym = a.sym;
79  return 1;
80 }
81 
82 static Addr
83 addr(Biobuf *bp)
84 {
85  Addr a;
86  long off;
87 
88  a.type = Bgetc(bp); /* a.type */
89  skip(bp,1); /* reg */
90  a.sym = Bgetc(bp); /* sym index */
91  a.name = Bgetc(bp); /* sym type */
92  switch(a.type){
93  default:
94  case D_NONE:
95  case D_REG:
96  case D_SP:
97  case D_FREG:
98  case D_VREG:
99  case D_COND:
100  break;
101 
102  case D_OREG:
103  case D_XPRE:
104  case D_XPOST:
105  case D_CONST:
106  case D_BRANCH:
107  case D_SHIFT:
108  case D_EXTREG:
109  case D_ROFF:
110  case D_SPR:
111  off = Bgetc(bp);
112  off |= Bgetc(bp) << 8;
113  off |= Bgetc(bp) << 16;
114  off |= Bgetc(bp) << 24;
115  if(off < 0)
116  off = -off;
117  if(a.sym && (a.name==D_PARAM || a.name==D_AUTO))
118  _offset(a.sym, off);
119  break;
120  case D_DCONST:
121  skip(bp, 8);
122  break;
123  case D_SCONST:
124  skip(bp, NSNAME);
125  break;
126  case D_FCONST:
127  skip(bp, 8);
128  break;
129  }
130  return a;
131 }
132 
133 static char
134 type2char(int t)
135 {
136  switch(t){
137  case D_EXTERN: return 'U';
138  case D_STATIC: return 'b';
139  case D_AUTO: return 'a';
140  case D_PARAM: return 'p';
141  default: return UNKNOWN;
142  }
143 }
144 
145 static void
146 skip(Biobuf *bp, int n)
147 {
148  while (n-- > 0)
149  Bgetc(bp);
150 }