1 #include "lib9.h" 2 #include "isa.h" 3 #include "interp.h" 4 #include "runt.h" 5 #include "loadermod.h" 6 #include "raise.h" 7 #include <kernel.h> 8 9 static uchar Instmap[] = Loader_Inst_map; 10 static Type* Tinst; 11 static uchar Tdescmap[] = Loader_Typedesc_map; 12 static Type* Tdesc; 13 static uchar Tlinkmap[] = Loader_Link_map; 14 static Type* Tlink; 15 16 void 17 loadermodinit(void) 18 { 19 sysinit(); 20 builtinmod("$Loader", Loadermodtab, Loadermodlen); 21 Tinst = dtype(freeheap, sizeof(Loader_Inst), Instmap, sizeof(Instmap)); 22 Tdesc = dtype(freeheap, sizeof(Loader_Typedesc), Tdescmap, sizeof(Tdescmap)); 23 Tlink = dtype(freeheap, sizeof(Loader_Link), Tlinkmap, sizeof(Tlinkmap)); 24 } 25 26 static void 27 brunpatch(Loader_Inst *ip, Module *m) 28 { 29 switch(ip->op) { 30 case ICALL: 31 case IJMP: 32 case IBEQW: 33 case IBNEW: 34 case IBLTW: 35 case IBLEW: 36 case IBGTW: 37 case IBGEW: 38 case IBEQB: 39 case IBNEB: 40 case IBLTB: 41 case IBLEB: 42 case IBGTB: 43 case IBGEB: 44 case IBEQF: 45 case IBNEF: 46 case IBLTF: 47 case IBLEF: 48 case IBGTF: 49 case IBGEF: 50 case IBEQC: 51 case IBNEC: 52 case IBLTC: 53 case IBLEC: 54 case IBGTC: 55 case IBGEC: 56 case IBEQL: 57 case IBNEL: 58 case IBLTL: 59 case IBLEL: 60 case IBGTL: 61 case IBGEL: 62 case ISPAWN: 63 ip->dst = (Inst*)ip->dst - m->prog; 64 break; 65 } 66 } 67 68 void 69 Loader_ifetch(void *a) 70 { 71 Heap *h; 72 Array *ar; 73 Module *m; 74 Inst *i, *ie; 75 Loader_Inst *li; 76 F_Loader_ifetch *f; 77 78 f = a; 79 destroy(*f->ret); 80 *f->ret = H; 81 82 if(f->mp == H) 83 return; 84 m = f->mp->m; 85 if(m == H) 86 return; 87 if(m->compiled) { 88 kwerrstr("compiled module"); 89 return; 90 } 91 92 h = nheap(sizeof(Array)+m->nprog*sizeof(Loader_Inst)); 93 h->t = &Tarray; 94 h->t->ref++; 95 ar = H2D(Array*, h); 96 ar->t = Tinst; 97 Tinst->ref++; 98 ar->len = m->nprog; 99 ar->root = H; 100 ar->data = (uchar*)ar+sizeof(Array); 101 102 li = (Loader_Inst*)ar->data; 103 i = m->prog; 104 ie = i + m->nprog; 105 while(i < ie) { 106 li->op = i->op; 107 li->addr = i->add; 108 li->src = i->s.imm; 109 li->dst = i->d.imm; 110 li->mid = i->reg; 111 if(UDST(i->add) == AIMM) 112 brunpatch(li, m); 113 li++; 114 i++; 115 } 116 117 *f->ret = ar; 118 } 119 120 void 121 Loader_link(void *a) 122 { 123 Link *p; 124 Heap *h; 125 Type **t; 126 int nlink; 127 Module *m; 128 Array *ar; 129 Loader_Link *ll; 130 F_Loader_link *f; 131 132 f = a; 133 destroy(*f->ret); 134 *f->ret = H; 135 136 if(f->mp == H) 137 return; 138 m = f->mp->m; 139 if(m == H) 140 return; 141 142 nlink = 0; 143 for(p = m->ext; p->name; p++) 144 nlink++; 145 146 h = nheap(sizeof(Array)+nlink*sizeof(Loader_Link)); 147 h->t = &Tarray; 148 h->t->ref++; 149 ar = H2D(Array*, h); 150 ar->t = Tlink; 151 Tlink->ref++; 152 ar->len = nlink; 153 ar->root = H; 154 ar->data = (uchar*)ar+sizeof(Array); 155 156 ll = (Loader_Link*)ar->data + nlink; 157 for(p = m->ext; p->name; p++) { 158 ll--; 159 ll->name = c2string(p->name, strlen(p->name)); 160 ll->sig = p->sig; 161 if(m->prog == nil) { 162 ll->pc = -1; 163 ll->tdesc = -1; 164 } else { 165 ll->pc = p->u.pc - m->prog; 166 ll->tdesc = 0; 167 for(t = m->type; *t != p->frame; t++) 168 ll->tdesc++; 169 } 170 } 171 172 *f->ret = ar; 173 } 174 175 void 176 Loader_tdesc(void *a) 177 { 178 int i; 179 Heap *h; 180 Type *t; 181 Array *ar; 182 Module *m; 183 F_Loader_tdesc *f; 184 Loader_Typedesc *lt; 185 186 f = a; 187 destroy(*f->ret); 188 *f->ret = H; 189 190 if(f->mp == H) 191 return; 192 m = f->mp->m; 193 if(m == H) 194 return; 195 196 h = nheap(sizeof(Array)+m->ntype*sizeof(Loader_Typedesc)); 197 h->t = &Tarray; 198 h->t->ref++; 199 ar = H2D(Array*, h); 200 ar->t = Tdesc; 201 Tdesc->ref++; 202 ar->len = m->ntype; 203 ar->root = H; 204 ar->data = (uchar*)ar+sizeof(Array); 205 206 lt = (Loader_Typedesc*)ar->data; 207 for(i = 0; i < m->ntype; i++) { 208 t = m->type[i]; 209 lt->size = t->size; 210 lt->map = H; 211 if(t->np != 0) 212 lt->map = mem2array(t->map, t->np); 213 lt++; 214 } 215 216 *f->ret = ar; 217 } 218 219 void 220 Loader_newmod(void *a) 221 { 222 Heap *h; 223 Module *m; 224 Array *ia; 225 Modlink *ml; 226 Inst *i, *ie; 227 Loader_Inst *li; 228 F_Loader_newmod *f; 229 230 f = a; 231 destroy(*f->ret); 232 *f->ret = H; 233 234 if(f->inst == H || f->data == H) { 235 kwerrstr("nil parameters"); 236 return; 237 } 238 if(f->nlink < 0) { 239 kwerrstr("bad nlink"); 240 return; 241 } 242 243 m = malloc(sizeof(Module)); 244 if(m == nil) { 245 kwerrstr(exNomem); 246 return; 247 } 248 m->origmp = H; 249 m->ref = 1; 250 m->ss = f->ss; 251 m->name = strdup(string2c(f->name)); 252 m->path = strdup(m->name); 253 m->ntype = 1; 254 m->type = malloc(sizeof(Type*)); 255 if(m->name == nil || m->path == nil || m->type == nil) { 256 kwerrstr(exNomem); 257 goto bad; 258 } 259 m->origmp = (uchar*)f->data; 260 h = D2H(f->data); 261 h->ref++; 262 Setmark(h); 263 m->type[0] = h->t; 264 h->t->ref++; 265 266 ia = f->inst; 267 m->nprog = ia->len; 268 m->prog = malloc(m->nprog*sizeof(Inst)); 269 if(m->prog == nil) 270 goto bad; 271 i = m->prog; 272 ie = i + m->nprog; 273 li = (Loader_Inst*)ia->data; 274 while(i < ie) { 275 i->op = li->op; 276 i->add = li->addr; 277 i->reg = li->mid; 278 i->s.imm = li->src; 279 i->d.imm = li->dst; 280 if(brpatch(i, m) == 0) { 281 kwerrstr("bad branch addr"); 282 goto bad; 283 } 284 i++; 285 li++; 286 } 287 m->entryt = nil; 288 m->entry = m->prog; 289 290 ml = mklinkmod(m, f->nlink); 291 ml->MP = m->origmp; 292 m->origmp = H; 293 m->pctab = nil; 294 *f->ret = ml; 295 return; 296 bad: 297 destroy(m->origmp); 298 freemod(m); 299 } 300 301 void 302 Loader_tnew(void *a) 303 { 304 int mem; 305 Module *m; 306 Type *t, **nt; 307 Array *ar, az; 308 F_Loader_tnew *f; 309 310 f = a; 311 *f->ret = -1; 312 if(f->mp == H) 313 return; 314 m = f->mp->m; 315 if(m == H) 316 return; 317 if(m->origmp != H){ 318 kwerrstr("need newmod"); 319 return; 320 } 321 322 ar = f->map; 323 if(ar == H) { 324 ar = &az; 325 ar->len = 0; 326 ar->data = nil; 327 } 328 329 t = dtype(freeheap, f->size, ar->data, ar->len); 330 if(t == nil) 331 return; 332 333 mem = (m->ntype+1)*sizeof(Type*); 334 if(msize(m->type) > mem) { 335 *f->ret = m->ntype; 336 m->type[m->ntype++] = t; 337 return; 338 } 339 nt = realloc(m->type, mem); 340 if(nt == nil) { 341 kwerrstr(exNomem); 342 return; 343 } 344 m->type = nt; 345 f->mp->type = nt; 346 *f->ret = m->ntype; 347 m->type[m->ntype++] = t; 348 } 349 350 void 351 Loader_ext(void *a) 352 { 353 Modl *l; 354 Module *m; 355 Modlink *ml; 356 F_Loader_ext *f; 357 358 f = a; 359 *f->ret = -1; 360 if(f->mp == H) { 361 kwerrstr("nil mp"); 362 return; 363 } 364 ml = f->mp; 365 m = ml->m; 366 if(f->tdesc < 0 || f->tdesc >= m->ntype) { 367 kwerrstr("bad tdesc"); 368 return; 369 } 370 if(f->pc < 0 || f->pc >= m->nprog) { 371 kwerrstr("bad pc"); 372 return; 373 } 374 if(f->idx < 0 || f->idx >= ml->nlinks) { 375 kwerrstr("bad idx"); 376 return; 377 } 378 l = &ml->links[f->idx]; 379 l->u.pc = m->prog + f->pc; 380 l->frame = m->type[f->tdesc]; 381 *f->ret = 0; 382 } 383 384 void 385 Loader_dnew(void *a) 386 { 387 F_Loader_dnew *f; 388 Heap *h; 389 Array *ar, az; 390 Type *t; 391 392 f = a; 393 *f->ret = H; 394 if(f->map == H) 395 return; 396 ar = f->map; 397 if(ar == H) { 398 ar = &az; 399 ar->len = 0; 400 ar->data = nil; 401 } 402 t = dtype(freeheap, f->size, ar->data, ar->len); 403 if(t == nil) { 404 kwerrstr(exNomem); 405 return; 406 } 407 408 h=heapz(t); 409 if(h == nil) { 410 freetype(t); 411 kwerrstr(exNomem); 412 return; 413 } 414 415 *f->ret=H2D(Loader_Niladt*, h); 416 } 417 418 void 419 Loader_compile(void *a) 420 { 421 Module *m; 422 F_Loader_compile *f; 423 424 f = a; 425 *f->ret = -1; 426 if(f->mp == H) { 427 kwerrstr("nil mp"); 428 return; 429 } 430 m = f->mp->m; 431 if(m->compiled) { 432 kwerrstr("compiled module"); 433 return; 434 } 435 *f->ret = 0; 436 m->origmp = f->mp->MP; 437 if(cflag || f->flag) 438 if(compile(m, m->nprog, f->mp)) { 439 f->mp->prog = m->prog; 440 f->mp->compiled = 1; 441 } else 442 *f->ret = -1; 443 m->origmp = H; 444 } 445