]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/7l/dyn.c
cwfs: fix listen filedescriptor leaks
[plan9front.git] / sys / src / cmd / 7l / dyn.c
1 #include "l.h"
2
3 enum{
4         ABSD = 0,
5         ABSU = 1,
6         RELD = 2,
7         RELU = 3,
8 };
9
10 int modemap[4] = { 0, 1, -1, 2, };
11
12 typedef struct Reloc Reloc;
13
14 struct Reloc
15 {
16         int n;
17         int t;
18         uchar *m;
19         ulong *a;
20 };
21
22 Reloc rels;
23
24 static void
25 grow(Reloc *r)
26 {
27         int t;
28         uchar *m, *nm;
29         ulong *a, *na;
30
31         t = r->t;
32         r->t += 64;
33         m = r->m;
34         a = r->a;
35         r->m = nm = malloc(r->t*sizeof(uchar));
36         r->a = na = malloc(r->t*sizeof(ulong));
37         memmove(nm, m, t*sizeof(uchar));
38         memmove(na, a, t*sizeof(ulong));
39         free(m);
40         free(a);
41 }
42
43 void
44 dynreloc(Sym *s, long v, int abs)
45 {
46         int i, k, n;
47         uchar *m;
48         ulong *a;
49         Reloc *r;
50
51         if(v&3)
52                 diag("bad relocation address");
53         v >>= 2;
54         if(s != S && s->type == SUNDEF)
55                 k = abs ? ABSU : RELU;
56         else
57                 k = abs ? ABSD : RELD;
58         /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
59         k = modemap[k];
60         r = &rels;
61         n = r->n;
62         if(n >= r->t)
63                 grow(r);
64         m = r->m;
65         a = r->a;
66         for(i = n; i > 0; i--){
67                 if(v < a[i-1]){ /* happens occasionally for data */
68                         m[i] = m[i-1];
69                         a[i] = a[i-1];
70                 }
71                 else
72                         break;
73         }
74         m[i] = k;
75         a[i] = v;
76         r->n++;
77 }
78
79 static int
80 sput(char *s)
81 {
82         char *p;
83
84         p = s;
85         while(*s)
86                 cput(*s++);
87         cput(0);
88         return  s-p+1;
89 }
90
91 void
92 asmdyn(void)
93 {
94         int i, n, t, c;
95         Sym *s;
96         ulong la, ra, *a;
97         vlong off;
98         uchar *m;
99         Reloc *r;
100
101         cflush();
102         off = seek(cout, 0, 1);
103         lput(0);
104         t = 0;
105         lput(imports);
106         t += 4;
107         for(i = 0; i < NHASH; i++)
108                 for(s = hash[i]; s != S; s = s->link)
109                         if(s->type == SUNDEF){
110                                 lput(s->sig);
111                                 t += 4;
112                                 t += sput(s->name);
113                         }
114         
115         la = 0;
116         r = &rels;
117         n = r->n;
118         m = r->m;
119         a = r->a;
120         lput(n);
121         t += 4;
122         for(i = 0; i < n; i++){
123                 ra = *a-la;
124                 if(*a < la)
125                         diag("bad relocation order");
126                 if(ra < 256)
127                         c = 0;
128                 else if(ra < 65536)
129                         c = 1;
130                 else
131                         c = 2;
132                 cput((c<<6)|*m++);
133                 t++;
134                 if(c == 0){
135                         cput(ra);
136                         t++;
137                 }
138                 else if(c == 1){
139                         wput(ra);
140                         t += 2;
141                 }
142                 else{
143                         lput(ra);
144                         t += 4;
145                 }
146                 la = *a++;
147         }
148
149         cflush();
150         seek(cout, off, 0);
151         lput(t);
152
153         if(debug['v']){
154                 Bprint(&bso, "import table entries = %d\n", imports);
155                 Bprint(&bso, "export table entries = %d\n", exports);
156         }
157 }