github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/ld/data.c (about) 1 // Inferno utils/8l/asm.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 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 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 // Data layout and relocation. 32 33 #include "l.h" 34 #include "../ld/lib.h" 35 #include "../ld/elf.h" 36 #include "../ld/macho.h" 37 #include "../ld/pe.h" 38 #include "../../pkg/runtime/mgc0.h" 39 40 void dynreloc(void); 41 42 /* 43 * divide-and-conquer list-link 44 * sort of LSym* structures. 45 * Used for the data block. 46 */ 47 int 48 datcmp(LSym *s1, LSym *s2) 49 { 50 if(s1->type != s2->type) 51 return (int)s1->type - (int)s2->type; 52 if(s1->size != s2->size) { 53 if(s1->size < s2->size) 54 return -1; 55 return +1; 56 } 57 return strcmp(s1->name, s2->name); 58 } 59 60 LSym* 61 listsort(LSym *l, int (*cmp)(LSym*, LSym*), int off) 62 { 63 LSym *l1, *l2, *le; 64 #define NEXT(l) (*(LSym**)((char*)(l)+off)) 65 66 if(l == 0 || NEXT(l) == 0) 67 return l; 68 69 l1 = l; 70 l2 = l; 71 for(;;) { 72 l2 = NEXT(l2); 73 if(l2 == 0) 74 break; 75 l2 = NEXT(l2); 76 if(l2 == 0) 77 break; 78 l1 = NEXT(l1); 79 } 80 81 l2 = NEXT(l1); 82 NEXT(l1) = 0; 83 l1 = listsort(l, cmp, off); 84 l2 = listsort(l2, cmp, off); 85 86 /* set up lead element */ 87 if(cmp(l1, l2) < 0) { 88 l = l1; 89 l1 = NEXT(l1); 90 } else { 91 l = l2; 92 l2 = NEXT(l2); 93 } 94 le = l; 95 96 for(;;) { 97 if(l1 == 0) { 98 while(l2) { 99 NEXT(le) = l2; 100 le = l2; 101 l2 = NEXT(l2); 102 } 103 NEXT(le) = 0; 104 break; 105 } 106 if(l2 == 0) { 107 while(l1) { 108 NEXT(le) = l1; 109 le = l1; 110 l1 = NEXT(l1); 111 } 112 break; 113 } 114 if(cmp(l1, l2) < 0) { 115 NEXT(le) = l1; 116 le = l1; 117 l1 = NEXT(l1); 118 } else { 119 NEXT(le) = l2; 120 le = l2; 121 l2 = NEXT(l2); 122 } 123 } 124 NEXT(le) = 0; 125 return l; 126 127 #undef NEXT 128 } 129 130 void 131 relocsym(LSym *s) 132 { 133 Reloc *r; 134 LSym *rs; 135 int32 i, off, siz, fl; 136 vlong o; 137 uchar *cast; 138 139 ctxt->cursym = s; 140 for(r=s->r; r<s->r+s->nr; r++) { 141 r->done = 1; 142 off = r->off; 143 siz = r->siz; 144 if(off < 0 || off+siz > s->np) { 145 diag("%s: invalid relocation %d+%d not in [%d,%d)", s->name, off, siz, 0, s->np); 146 continue; 147 } 148 if(r->sym != S && (r->sym->type & SMASK == 0 || r->sym->type & SMASK == SXREF)) { 149 diag("%s: not defined", r->sym->name); 150 continue; 151 } 152 if(r->type >= 256) 153 continue; 154 if(r->siz == 0) // informational relocation - no work to do 155 continue; 156 157 // Solaris needs the ability to reference dynimport symbols. 158 if(HEADTYPE != Hsolaris && r->sym != S && r->sym->type == SDYNIMPORT) 159 diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type); 160 if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable) 161 diag("unreachable sym in relocation: %s %s", s->name, r->sym->name); 162 163 switch(r->type) { 164 default: 165 o = 0; 166 if(archreloc(r, s, &o) < 0) 167 diag("unknown reloc %d", r->type); 168 break; 169 case R_TLS: 170 if(linkmode == LinkInternal && iself && thechar == '5') { 171 // On ELF ARM, the thread pointer is 8 bytes before 172 // the start of the thread-local data block, so add 8 173 // to the actual TLS offset (r->sym->value). 174 // This 8 seems to be a fundamental constant of 175 // ELF on ARM (or maybe Glibc on ARM); it is not 176 // related to the fact that our own TLS storage happens 177 // to take up 8 bytes. 178 o = 8 + r->sym->value; 179 break; 180 } 181 r->done = 0; 182 o = 0; 183 if(thechar != '6') 184 o = r->add; 185 break; 186 case R_TLS_LE: 187 if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) { 188 r->done = 0; 189 r->sym = ctxt->gmsym; 190 r->xsym = ctxt->gmsym; 191 r->xadd = r->add; 192 o = 0; 193 if(thechar != '6') 194 o = r->add; 195 break; 196 } 197 o = ctxt->tlsoffset + r->add; 198 break; 199 200 case R_TLS_IE: 201 if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) { 202 r->done = 0; 203 r->sym = ctxt->gmsym; 204 r->xsym = ctxt->gmsym; 205 r->xadd = r->add; 206 o = 0; 207 if(thechar != '6') 208 o = r->add; 209 break; 210 } 211 if(iself || ctxt->headtype == Hplan9) 212 o = ctxt->tlsoffset + r->add; 213 else if(ctxt->headtype == Hwindows) 214 o = r->add; 215 else 216 sysfatal("unexpected R_TLS_IE relocation for %s", headstr(ctxt->headtype)); 217 break; 218 case R_ADDR: 219 if(linkmode == LinkExternal && r->sym->type != SCONST) { 220 r->done = 0; 221 222 // set up addend for eventual relocation via outer symbol. 223 rs = r->sym; 224 r->xadd = r->add; 225 while(rs->outer != nil) { 226 r->xadd += symaddr(rs) - symaddr(rs->outer); 227 rs = rs->outer; 228 } 229 if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil) 230 diag("missing section for %s", rs->name); 231 r->xsym = rs; 232 233 o = r->xadd; 234 if(iself) { 235 if(thechar == '6') 236 o = 0; 237 } else if(HEADTYPE == Hdarwin) { 238 if(rs->type != SHOSTOBJ) 239 o += symaddr(rs); 240 } else { 241 diag("unhandled pcrel relocation for %s", headstring); 242 } 243 break; 244 } 245 o = symaddr(r->sym) + r->add; 246 247 // On amd64, 4-byte offsets will be sign-extended, so it is impossible to 248 // access more than 2GB of static data; fail at link time is better than 249 // fail at runtime. See http://golang.org/issue/7980. 250 // Instead of special casing only amd64, we treat this as an error on all 251 // 64-bit architectures so as to be future-proof. 252 if((int32)o < 0 && PtrSize > 4 && siz == 4) { 253 diag("non-pc-relative relocation address is too big: %#llux", o); 254 errorexit(); 255 } 256 break; 257 case R_CALL: 258 case R_PCREL: 259 // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call. 260 if(linkmode == LinkExternal && r->sym && r->sym->type != SCONST && r->sym->sect != ctxt->cursym->sect) { 261 r->done = 0; 262 263 // set up addend for eventual relocation via outer symbol. 264 rs = r->sym; 265 r->xadd = r->add; 266 while(rs->outer != nil) { 267 r->xadd += symaddr(rs) - symaddr(rs->outer); 268 rs = rs->outer; 269 } 270 r->xadd -= r->siz; // relative to address after the relocated chunk 271 if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil) 272 diag("missing section for %s", rs->name); 273 r->xsym = rs; 274 275 o = r->xadd; 276 if(iself) { 277 if(thechar == '6') 278 o = 0; 279 } else if(HEADTYPE == Hdarwin) { 280 if(rs->type != SHOSTOBJ) 281 o += symaddr(rs) - rs->sect->vaddr; 282 o -= r->off; // WTF? 283 } else { 284 diag("unhandled pcrel relocation for %s", headstring); 285 } 286 break; 287 } 288 o = 0; 289 if(r->sym) 290 o += symaddr(r->sym); 291 // NOTE: The (int32) cast on the next line works around a bug in Plan 9's 8c 292 // compiler. The expression s->value + r->off + r->siz is int32 + int32 + 293 // uchar, and Plan 9 8c incorrectly treats the expression as type uint32 294 // instead of int32, causing incorrect values when sign extended for adding 295 // to o. The bug only occurs on Plan 9, because this C program is compiled by 296 // the standard host compiler (gcc on most other systems). 297 o += r->add - (s->value + r->off + (int32)r->siz); 298 break; 299 case R_SIZE: 300 o = r->sym->size + r->add; 301 break; 302 } 303 //print("relocate %s %#llux (%#llux+%#llux, size %d) => %s %#llux +%#llx [%llx]\n", s->name, (uvlong)(s->value+off), (uvlong)s->value, (uvlong)r->off, r->siz, r->sym ? r->sym->name : "<nil>", (uvlong)symaddr(r->sym), (vlong)r->add, (vlong)o); 304 switch(siz) { 305 default: 306 ctxt->cursym = s; 307 diag("bad reloc size %#ux for %s", siz, r->sym->name); 308 case 1: 309 // TODO(rsc): Remove. 310 s->p[off] = (int8)o; 311 break; 312 case 4: 313 if(r->type == R_PCREL || r->type == R_CALL) { 314 if(o != (int32)o) 315 diag("pc-relative relocation address is too big: %#llx", o); 316 } else { 317 if(o != (int32)o && o != (uint32)o) 318 diag("non-pc-relative relocation address is too big: %#llux", o); 319 } 320 fl = o; 321 cast = (uchar*)&fl; 322 for(i=0; i<4; i++) 323 s->p[off+i] = cast[inuxi4[i]]; 324 break; 325 case 8: 326 cast = (uchar*)&o; 327 for(i=0; i<8; i++) 328 s->p[off+i] = cast[inuxi8[i]]; 329 break; 330 } 331 } 332 } 333 334 void 335 reloc(void) 336 { 337 LSym *s; 338 339 if(debug['v']) 340 Bprint(&bso, "%5.2f reloc\n", cputime()); 341 Bflush(&bso); 342 343 for(s=ctxt->textp; s!=S; s=s->next) 344 relocsym(s); 345 for(s=datap; s!=S; s=s->next) 346 relocsym(s); 347 } 348 349 void 350 dynrelocsym(LSym *s) 351 { 352 Reloc *r; 353 354 if(HEADTYPE == Hwindows) { 355 LSym *rel, *targ; 356 357 rel = linklookup(ctxt, ".rel", 0); 358 if(s == rel) 359 return; 360 for(r=s->r; r<s->r+s->nr; r++) { 361 targ = r->sym; 362 if(targ == nil) 363 continue; 364 if(!targ->reachable) 365 diag("internal inconsistency: dynamic symbol %s is not reachable.", targ->name); 366 if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files. 367 targ->plt = rel->size; 368 r->sym = rel; 369 r->add = targ->plt; 370 371 // jmp *addr 372 if(thechar == '8') { 373 adduint8(ctxt, rel, 0xff); 374 adduint8(ctxt, rel, 0x25); 375 addaddr(ctxt, rel, targ); 376 adduint8(ctxt, rel, 0x90); 377 adduint8(ctxt, rel, 0x90); 378 } else { 379 adduint8(ctxt, rel, 0xff); 380 adduint8(ctxt, rel, 0x24); 381 adduint8(ctxt, rel, 0x25); 382 addaddrplus4(ctxt, rel, targ, 0); 383 adduint8(ctxt, rel, 0x90); 384 } 385 } else if(r->sym->plt >= 0) { 386 r->sym = rel; 387 r->add = targ->plt; 388 } 389 } 390 return; 391 } 392 393 for(r=s->r; r<s->r+s->nr; r++) { 394 if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256) { 395 if(r->sym != S && !r->sym->reachable) 396 diag("internal inconsistency: dynamic symbol %s is not reachable.", r->sym->name); 397 adddynrel(s, r); 398 } 399 } 400 } 401 402 void 403 dynreloc(void) 404 { 405 LSym *s; 406 407 // -d suppresses dynamic loader format, so we may as well not 408 // compute these sections or mark their symbols as reachable. 409 if(debug['d'] && HEADTYPE != Hwindows) 410 return; 411 if(debug['v']) 412 Bprint(&bso, "%5.2f reloc\n", cputime()); 413 Bflush(&bso); 414 415 for(s=ctxt->textp; s!=S; s=s->next) 416 dynrelocsym(s); 417 for(s=datap; s!=S; s=s->next) 418 dynrelocsym(s); 419 if(iself) 420 elfdynhash(); 421 } 422 423 static void 424 blk(LSym *start, int32 addr, int32 size) 425 { 426 LSym *sym; 427 int32 eaddr; 428 uchar *p, *ep; 429 430 for(sym = start; sym != nil; sym = sym->next) 431 if(!(sym->type&SSUB) && sym->value >= addr) 432 break; 433 434 eaddr = addr+size; 435 for(; sym != nil; sym = sym->next) { 436 if(sym->type&SSUB) 437 continue; 438 if(sym->value >= eaddr) 439 break; 440 if(sym->value < addr) { 441 diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type); 442 errorexit(); 443 } 444 ctxt->cursym = sym; 445 for(; addr < sym->value; addr++) 446 cput(0); 447 p = sym->p; 448 ep = p + sym->np; 449 while(p < ep) 450 cput(*p++); 451 addr += sym->np; 452 for(; addr < sym->value+sym->size; addr++) 453 cput(0); 454 if(addr != sym->value+sym->size) { 455 diag("phase error: addr=%#llx value+size=%#llx", (vlong)addr, (vlong)sym->value+sym->size); 456 errorexit(); 457 } 458 } 459 460 for(; addr < eaddr; addr++) 461 cput(0); 462 cflush(); 463 } 464 465 void 466 codeblk(int32 addr, int32 size) 467 { 468 LSym *sym; 469 int32 eaddr, n; 470 uchar *q; 471 472 if(debug['a']) 473 Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos()); 474 475 blk(ctxt->textp, addr, size); 476 477 /* again for printing */ 478 if(!debug['a']) 479 return; 480 481 for(sym = ctxt->textp; sym != nil; sym = sym->next) { 482 if(!sym->reachable) 483 continue; 484 if(sym->value >= addr) 485 break; 486 } 487 488 eaddr = addr + size; 489 for(; sym != nil; sym = sym->next) { 490 if(!sym->reachable) 491 continue; 492 if(sym->value >= eaddr) 493 break; 494 495 if(addr < sym->value) { 496 Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr); 497 for(; addr < sym->value; addr++) 498 Bprint(&bso, " %.2ux", 0); 499 Bprint(&bso, "\n"); 500 } 501 502 Bprint(&bso, "%.6llux\t%-20s\n", (vlong)addr, sym->name); 503 n = sym->size; 504 q = sym->p; 505 506 while(n >= 16) { 507 Bprint(&bso, "%.6ux\t%-20.16I\n", addr, q); 508 addr += 16; 509 q += 16; 510 n -= 16; 511 } 512 if(n > 0) 513 Bprint(&bso, "%.6ux\t%-20.*I\n", addr, (int)n, q); 514 addr += n; 515 } 516 517 if(addr < eaddr) { 518 Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr); 519 for(; addr < eaddr; addr++) 520 Bprint(&bso, " %.2ux", 0); 521 } 522 Bflush(&bso); 523 } 524 525 void 526 datblk(int32 addr, int32 size) 527 { 528 LSym *sym; 529 int32 i, eaddr; 530 uchar *p, *ep; 531 char *typ, *rsname; 532 Reloc *r; 533 534 if(debug['a']) 535 Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos()); 536 537 blk(datap, addr, size); 538 539 /* again for printing */ 540 if(!debug['a']) 541 return; 542 543 for(sym = datap; sym != nil; sym = sym->next) 544 if(sym->value >= addr) 545 break; 546 547 eaddr = addr + size; 548 for(; sym != nil; sym = sym->next) { 549 if(sym->value >= eaddr) 550 break; 551 if(addr < sym->value) { 552 Bprint(&bso, "\t%.8ux| 00 ...\n", addr); 553 addr = sym->value; 554 } 555 Bprint(&bso, "%s\n\t%.8ux|", sym->name, (uint)addr); 556 p = sym->p; 557 ep = p + sym->np; 558 while(p < ep) { 559 if(p > sym->p && (int)(p-sym->p)%16 == 0) 560 Bprint(&bso, "\n\t%.8ux|", (uint)(addr+(p-sym->p))); 561 Bprint(&bso, " %.2ux", *p++); 562 } 563 addr += sym->np; 564 for(; addr < sym->value+sym->size; addr++) 565 Bprint(&bso, " %.2ux", 0); 566 Bprint(&bso, "\n"); 567 568 if(linkmode == LinkExternal) { 569 for(i=0; i<sym->nr; i++) { 570 r = &sym->r[i]; 571 rsname = ""; 572 if(r->sym) 573 rsname = r->sym->name; 574 typ = "?"; 575 switch(r->type) { 576 case R_ADDR: 577 typ = "addr"; 578 break; 579 case R_PCREL: 580 typ = "pcrel"; 581 break; 582 case R_CALL: 583 typ = "call"; 584 break; 585 } 586 Bprint(&bso, "\treloc %.8ux/%d %s %s+%#llx [%#llx]\n", 587 (uint)(sym->value+r->off), r->siz, typ, rsname, (vlong)r->add, (vlong)(r->sym->value+r->add)); 588 } 589 } 590 } 591 592 if(addr < eaddr) 593 Bprint(&bso, "\t%.8ux| 00 ...\n", (uint)addr); 594 Bprint(&bso, "\t%.8ux|\n", (uint)eaddr); 595 } 596 597 void 598 strnput(char *s, int n) 599 { 600 for(; n > 0 && *s; s++) { 601 cput(*s); 602 n--; 603 } 604 while(n > 0) { 605 cput(0); 606 n--; 607 } 608 } 609 610 void 611 addstrdata(char *name, char *value) 612 { 613 LSym *s, *sp; 614 char *p; 615 616 p = smprint("%s.str", name); 617 sp = linklookup(ctxt, p, 0); 618 free(p); 619 addstring(sp, value); 620 621 s = linklookup(ctxt, name, 0); 622 s->size = 0; 623 s->dupok = 1; 624 addaddr(ctxt, s, sp); 625 adduint32(ctxt, s, strlen(value)); 626 if(PtrSize == 8) 627 adduint32(ctxt, s, 0); // round struct to pointer width 628 629 // in case reachability has already been computed 630 sp->reachable = s->reachable; 631 } 632 633 vlong 634 addstring(LSym *s, char *str) 635 { 636 int n; 637 int32 r; 638 639 if(s->type == 0) 640 s->type = SNOPTRDATA; 641 s->reachable = 1; 642 r = s->size; 643 n = strlen(str)+1; 644 if(strcmp(s->name, ".shstrtab") == 0) 645 elfsetstring(str, r); 646 symgrow(ctxt, s, r+n); 647 memmove(s->p+r, str, n); 648 s->size += n; 649 return r; 650 } 651 652 void 653 dosymtype(void) 654 { 655 LSym *s; 656 657 for(s = ctxt->allsym; s != nil; s = s->allsym) { 658 if(s->np > 0) { 659 if(s->type == SBSS) 660 s->type = SDATA; 661 if(s->type == SNOPTRBSS) 662 s->type = SNOPTRDATA; 663 } 664 } 665 } 666 667 static int32 668 symalign(LSym *s) 669 { 670 int32 align; 671 672 if(s->align != 0) 673 return s->align; 674 675 align = MaxAlign; 676 while(align > s->size && align > 1) 677 align >>= 1; 678 if(align < s->align) 679 align = s->align; 680 return align; 681 } 682 683 static vlong 684 aligndatsize(vlong datsize, LSym *s) 685 { 686 return rnd(datsize, symalign(s)); 687 } 688 689 // maxalign returns the maximum required alignment for 690 // the list of symbols s; the list stops when s->type exceeds type. 691 static int32 692 maxalign(LSym *s, int type) 693 { 694 int32 align, max; 695 696 max = 0; 697 for(; s != S && s->type <= type; s = s->next) { 698 align = symalign(s); 699 if(max < align) 700 max = align; 701 } 702 return max; 703 } 704 705 static void 706 gcaddsym(LSym *gc, LSym *s, vlong off) 707 { 708 vlong a; 709 LSym *gotype; 710 711 if(s->size < PtrSize) 712 return; 713 if(strcmp(s->name, ".string") == 0) 714 return; 715 716 gotype = s->gotype; 717 if(gotype != nil) { 718 //print("gcaddsym: %s %d %s\n", s->name, s->size, gotype->name); 719 adduintxx(ctxt, gc, GC_CALL, PtrSize); 720 adduintxx(ctxt, gc, off, PtrSize); 721 addpcrelplus(ctxt, gc, decodetype_gc(gotype), 3*PtrSize+4); 722 if(PtrSize == 8) 723 adduintxx(ctxt, gc, 0, 4); 724 } else { 725 //print("gcaddsym: %s %d <unknown type>\n", s->name, s->size); 726 for(a = -off&(PtrSize-1); a+PtrSize<=s->size; a+=PtrSize) { 727 adduintxx(ctxt, gc, GC_APTR, PtrSize); 728 adduintxx(ctxt, gc, off+a, PtrSize); 729 } 730 } 731 } 732 733 void 734 growdatsize(vlong *datsizep, LSym *s) 735 { 736 vlong datsize; 737 738 datsize = *datsizep; 739 if(s->size < 0) 740 diag("negative size (datsize = %lld, s->size = %lld)", datsize, s->size); 741 if(datsize + s->size < datsize) 742 diag("symbol too large (datsize = %lld, s->size = %lld)", datsize, s->size); 743 *datsizep = datsize + s->size; 744 } 745 746 void 747 dodata(void) 748 { 749 int32 n; 750 vlong datsize; 751 Section *sect; 752 Segment *segro; 753 LSym *s, *last, **l; 754 LSym *gcdata1, *gcbss1; 755 756 if(debug['v']) 757 Bprint(&bso, "%5.2f dodata\n", cputime()); 758 Bflush(&bso); 759 760 gcdata1 = linklookup(ctxt, "gcdata", 0); 761 gcbss1 = linklookup(ctxt, "gcbss", 0); 762 763 // size of .data and .bss section. the zero value is later replaced by the actual size of the section. 764 adduintxx(ctxt, gcdata1, 0, PtrSize); 765 adduintxx(ctxt, gcbss1, 0, PtrSize); 766 767 last = nil; 768 datap = nil; 769 770 for(s=ctxt->allsym; s!=S; s=s->allsym) { 771 if(!s->reachable || s->special) 772 continue; 773 if(STEXT < s->type && s->type < SXREF) { 774 if(s->onlist) 775 sysfatal("symbol %s listed multiple times", s->name); 776 s->onlist = 1; 777 if(last == nil) 778 datap = s; 779 else 780 last->next = s; 781 s->next = nil; 782 last = s; 783 } 784 } 785 786 for(s = datap; s != nil; s = s->next) { 787 if(s->np > s->size) 788 diag("%s: initialize bounds (%lld < %d)", 789 s->name, (vlong)s->size, s->np); 790 } 791 792 793 /* 794 * now that we have the datap list, but before we start 795 * to assign addresses, record all the necessary 796 * dynamic relocations. these will grow the relocation 797 * symbol, which is itself data. 798 * 799 * on darwin, we need the symbol table numbers for dynreloc. 800 */ 801 if(HEADTYPE == Hdarwin) 802 machosymorder(); 803 dynreloc(); 804 805 /* some symbols may no longer belong in datap (Mach-O) */ 806 for(l=&datap; (s=*l) != nil; ) { 807 if(s->type <= STEXT || SXREF <= s->type) 808 *l = s->next; 809 else 810 l = &s->next; 811 } 812 *l = nil; 813 814 datap = listsort(datap, datcmp, offsetof(LSym, next)); 815 816 /* 817 * allocate sections. list is sorted by type, 818 * so we can just walk it for each piece we want to emit. 819 * segdata is processed before segtext, because we need 820 * to see all symbols in the .data and .bss sections in order 821 * to generate garbage collection information. 822 */ 823 824 /* begin segdata */ 825 826 /* skip symbols belonging to segtext */ 827 s = datap; 828 for(; s != nil && s->type < SELFSECT; s = s->next) 829 ; 830 831 /* writable ELF sections */ 832 datsize = 0; 833 for(; s != nil && s->type < SNOPTRDATA; s = s->next) { 834 sect = addsection(&segdata, s->name, 06); 835 sect->align = symalign(s); 836 datsize = rnd(datsize, sect->align); 837 sect->vaddr = datsize; 838 s->sect = sect; 839 s->type = SDATA; 840 s->value = datsize - sect->vaddr; 841 growdatsize(&datsize, s); 842 sect->len = datsize - sect->vaddr; 843 } 844 845 /* pointer-free data */ 846 sect = addsection(&segdata, ".noptrdata", 06); 847 sect->align = maxalign(s, SINITARR-1); 848 datsize = rnd(datsize, sect->align); 849 sect->vaddr = datsize; 850 linklookup(ctxt, "noptrdata", 0)->sect = sect; 851 linklookup(ctxt, "enoptrdata", 0)->sect = sect; 852 for(; s != nil && s->type < SINITARR; s = s->next) { 853 datsize = aligndatsize(datsize, s); 854 s->sect = sect; 855 s->type = SDATA; 856 s->value = datsize - sect->vaddr; 857 growdatsize(&datsize, s); 858 } 859 sect->len = datsize - sect->vaddr; 860 861 /* shared library initializer */ 862 if(flag_shared) { 863 sect = addsection(&segdata, ".init_array", 06); 864 sect->align = maxalign(s, SINITARR); 865 datsize = rnd(datsize, sect->align); 866 sect->vaddr = datsize; 867 for(; s != nil && s->type == SINITARR; s = s->next) { 868 datsize = aligndatsize(datsize, s); 869 s->sect = sect; 870 s->value = datsize - sect->vaddr; 871 growdatsize(&datsize, s); 872 } 873 sect->len = datsize - sect->vaddr; 874 } 875 876 /* data */ 877 sect = addsection(&segdata, ".data", 06); 878 sect->align = maxalign(s, SBSS-1); 879 datsize = rnd(datsize, sect->align); 880 sect->vaddr = datsize; 881 linklookup(ctxt, "data", 0)->sect = sect; 882 linklookup(ctxt, "edata", 0)->sect = sect; 883 for(; s != nil && s->type < SBSS; s = s->next) { 884 if(s->type == SINITARR) { 885 ctxt->cursym = s; 886 diag("unexpected symbol type %d", s->type); 887 } 888 s->sect = sect; 889 s->type = SDATA; 890 datsize = aligndatsize(datsize, s); 891 s->value = datsize - sect->vaddr; 892 gcaddsym(gcdata1, s, datsize - sect->vaddr); // gc 893 growdatsize(&datsize, s); 894 } 895 sect->len = datsize - sect->vaddr; 896 897 adduintxx(ctxt, gcdata1, GC_END, PtrSize); 898 setuintxx(ctxt, gcdata1, 0, sect->len, PtrSize); 899 900 /* bss */ 901 sect = addsection(&segdata, ".bss", 06); 902 sect->align = maxalign(s, SNOPTRBSS-1); 903 datsize = rnd(datsize, sect->align); 904 sect->vaddr = datsize; 905 linklookup(ctxt, "bss", 0)->sect = sect; 906 linklookup(ctxt, "ebss", 0)->sect = sect; 907 for(; s != nil && s->type < SNOPTRBSS; s = s->next) { 908 s->sect = sect; 909 datsize = aligndatsize(datsize, s); 910 s->value = datsize - sect->vaddr; 911 gcaddsym(gcbss1, s, datsize - sect->vaddr); // gc 912 growdatsize(&datsize, s); 913 } 914 sect->len = datsize - sect->vaddr; 915 916 adduintxx(ctxt, gcbss1, GC_END, PtrSize); 917 setuintxx(ctxt, gcbss1, 0, sect->len, PtrSize); 918 919 /* pointer-free bss */ 920 sect = addsection(&segdata, ".noptrbss", 06); 921 sect->align = maxalign(s, SNOPTRBSS); 922 datsize = rnd(datsize, sect->align); 923 sect->vaddr = datsize; 924 linklookup(ctxt, "noptrbss", 0)->sect = sect; 925 linklookup(ctxt, "enoptrbss", 0)->sect = sect; 926 for(; s != nil && s->type == SNOPTRBSS; s = s->next) { 927 datsize = aligndatsize(datsize, s); 928 s->sect = sect; 929 s->value = datsize - sect->vaddr; 930 growdatsize(&datsize, s); 931 } 932 sect->len = datsize - sect->vaddr; 933 linklookup(ctxt, "end", 0)->sect = sect; 934 935 // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits. 936 if(datsize != (uint32)datsize) { 937 diag("data or bss segment too large"); 938 } 939 940 if(iself && linkmode == LinkExternal && s != nil && s->type == STLSBSS && HEADTYPE != Hopenbsd) { 941 sect = addsection(&segdata, ".tbss", 06); 942 sect->align = PtrSize; 943 sect->vaddr = 0; 944 datsize = 0; 945 for(; s != nil && s->type == STLSBSS; s = s->next) { 946 datsize = aligndatsize(datsize, s); 947 s->sect = sect; 948 s->value = datsize - sect->vaddr; 949 growdatsize(&datsize, s); 950 } 951 sect->len = datsize; 952 } else { 953 // Might be internal linking but still using cgo. 954 // In that case, the only possible STLSBSS symbol is tlsgm. 955 // Give it offset 0, because it's the only thing here. 956 if(s != nil && s->type == STLSBSS && strcmp(s->name, "runtime.tlsgm") == 0) { 957 s->value = 0; 958 s = s->next; 959 } 960 } 961 962 if(s != nil) { 963 ctxt->cursym = nil; 964 diag("unexpected symbol type %d for %s", s->type, s->name); 965 } 966 967 /* 968 * We finished data, begin read-only data. 969 * Not all systems support a separate read-only non-executable data section. 970 * ELF systems do. 971 * OS X and Plan 9 do not. 972 * Windows PE may, but if so we have not implemented it. 973 * And if we're using external linking mode, the point is moot, 974 * since it's not our decision; that code expects the sections in 975 * segtext. 976 */ 977 if(iself && linkmode == LinkInternal) 978 segro = &segrodata; 979 else 980 segro = &segtext; 981 982 s = datap; 983 984 datsize = 0; 985 986 /* read-only executable ELF, Mach-O sections */ 987 for(; s != nil && s->type < STYPE; s = s->next) { 988 sect = addsection(&segtext, s->name, 04); 989 sect->align = symalign(s); 990 datsize = rnd(datsize, sect->align); 991 sect->vaddr = datsize; 992 s->sect = sect; 993 s->type = SRODATA; 994 s->value = datsize - sect->vaddr; 995 growdatsize(&datsize, s); 996 sect->len = datsize - sect->vaddr; 997 } 998 999 /* read-only data */ 1000 sect = addsection(segro, ".rodata", 04); 1001 sect->align = maxalign(s, STYPELINK-1); 1002 datsize = rnd(datsize, sect->align); 1003 sect->vaddr = 0; 1004 linklookup(ctxt, "rodata", 0)->sect = sect; 1005 linklookup(ctxt, "erodata", 0)->sect = sect; 1006 for(; s != nil && s->type < STYPELINK; s = s->next) { 1007 datsize = aligndatsize(datsize, s); 1008 s->sect = sect; 1009 s->type = SRODATA; 1010 s->value = datsize - sect->vaddr; 1011 growdatsize(&datsize, s); 1012 } 1013 sect->len = datsize - sect->vaddr; 1014 1015 /* typelink */ 1016 sect = addsection(segro, ".typelink", 04); 1017 sect->align = maxalign(s, STYPELINK); 1018 datsize = rnd(datsize, sect->align); 1019 sect->vaddr = datsize; 1020 linklookup(ctxt, "typelink", 0)->sect = sect; 1021 linklookup(ctxt, "etypelink", 0)->sect = sect; 1022 for(; s != nil && s->type == STYPELINK; s = s->next) { 1023 datsize = aligndatsize(datsize, s); 1024 s->sect = sect; 1025 s->type = SRODATA; 1026 s->value = datsize - sect->vaddr; 1027 growdatsize(&datsize, s); 1028 } 1029 sect->len = datsize - sect->vaddr; 1030 1031 /* gosymtab */ 1032 sect = addsection(segro, ".gosymtab", 04); 1033 sect->align = maxalign(s, SPCLNTAB-1); 1034 datsize = rnd(datsize, sect->align); 1035 sect->vaddr = datsize; 1036 linklookup(ctxt, "symtab", 0)->sect = sect; 1037 linklookup(ctxt, "esymtab", 0)->sect = sect; 1038 for(; s != nil && s->type < SPCLNTAB; s = s->next) { 1039 datsize = aligndatsize(datsize, s); 1040 s->sect = sect; 1041 s->type = SRODATA; 1042 s->value = datsize - sect->vaddr; 1043 growdatsize(&datsize, s); 1044 } 1045 sect->len = datsize - sect->vaddr; 1046 1047 /* gopclntab */ 1048 sect = addsection(segro, ".gopclntab", 04); 1049 sect->align = maxalign(s, SELFROSECT-1); 1050 datsize = rnd(datsize, sect->align); 1051 sect->vaddr = datsize; 1052 linklookup(ctxt, "pclntab", 0)->sect = sect; 1053 linklookup(ctxt, "epclntab", 0)->sect = sect; 1054 for(; s != nil && s->type < SELFROSECT; s = s->next) { 1055 datsize = aligndatsize(datsize, s); 1056 s->sect = sect; 1057 s->type = SRODATA; 1058 s->value = datsize - sect->vaddr; 1059 growdatsize(&datsize, s); 1060 } 1061 sect->len = datsize - sect->vaddr; 1062 1063 /* read-only ELF, Mach-O sections */ 1064 for(; s != nil && s->type < SELFSECT; s = s->next) { 1065 sect = addsection(segro, s->name, 04); 1066 sect->align = symalign(s); 1067 datsize = rnd(datsize, sect->align); 1068 sect->vaddr = datsize; 1069 s->sect = sect; 1070 s->type = SRODATA; 1071 s->value = datsize - sect->vaddr; 1072 growdatsize(&datsize, s); 1073 sect->len = datsize - sect->vaddr; 1074 } 1075 1076 // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits. 1077 if(datsize != (uint32)datsize) { 1078 diag("read-only data segment too large"); 1079 } 1080 1081 /* number the sections */ 1082 n = 1; 1083 for(sect = segtext.sect; sect != nil; sect = sect->next) 1084 sect->extnum = n++; 1085 for(sect = segrodata.sect; sect != nil; sect = sect->next) 1086 sect->extnum = n++; 1087 for(sect = segdata.sect; sect != nil; sect = sect->next) 1088 sect->extnum = n++; 1089 } 1090 1091 // assign addresses to text 1092 void 1093 textaddress(void) 1094 { 1095 uvlong va; 1096 Section *sect; 1097 LSym *sym, *sub; 1098 1099 addsection(&segtext, ".text", 05); 1100 1101 // Assign PCs in text segment. 1102 // Could parallelize, by assigning to text 1103 // and then letting threads copy down, but probably not worth it. 1104 sect = segtext.sect; 1105 sect->align = funcalign; 1106 linklookup(ctxt, "text", 0)->sect = sect; 1107 linklookup(ctxt, "etext", 0)->sect = sect; 1108 va = INITTEXT; 1109 sect->vaddr = va; 1110 for(sym = ctxt->textp; sym != nil; sym = sym->next) { 1111 sym->sect = sect; 1112 if(sym->type & SSUB) 1113 continue; 1114 if(sym->align != 0) 1115 va = rnd(va, sym->align); 1116 else 1117 va = rnd(va, funcalign); 1118 sym->value = 0; 1119 for(sub = sym; sub != S; sub = sub->sub) 1120 sub->value += va; 1121 if(sym->size == 0 && sym->sub != S) 1122 ctxt->cursym = sym; 1123 va += sym->size; 1124 } 1125 sect->len = va - sect->vaddr; 1126 } 1127 1128 // assign addresses 1129 void 1130 address(void) 1131 { 1132 Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss; 1133 Section *typelink; 1134 LSym *sym, *sub; 1135 uvlong va; 1136 vlong vlen; 1137 1138 va = INITTEXT; 1139 segtext.rwx = 05; 1140 segtext.vaddr = va; 1141 segtext.fileoff = HEADR; 1142 for(s=segtext.sect; s != nil; s=s->next) { 1143 va = rnd(va, s->align); 1144 s->vaddr = va; 1145 va += s->len; 1146 } 1147 segtext.len = va - INITTEXT; 1148 segtext.filelen = segtext.len; 1149 if(HEADTYPE == Hnacl) 1150 va += 32; // room for the "halt sled" 1151 1152 if(segrodata.sect != nil) { 1153 // align to page boundary so as not to mix 1154 // rodata and executable text. 1155 va = rnd(va, INITRND); 1156 1157 segrodata.rwx = 04; 1158 segrodata.vaddr = va; 1159 segrodata.fileoff = va - segtext.vaddr + segtext.fileoff; 1160 segrodata.filelen = 0; 1161 for(s=segrodata.sect; s != nil; s=s->next) { 1162 va = rnd(va, s->align); 1163 s->vaddr = va; 1164 va += s->len; 1165 } 1166 segrodata.len = va - segrodata.vaddr; 1167 segrodata.filelen = segrodata.len; 1168 } 1169 1170 va = rnd(va, INITRND); 1171 segdata.rwx = 06; 1172 segdata.vaddr = va; 1173 segdata.fileoff = va - segtext.vaddr + segtext.fileoff; 1174 segdata.filelen = 0; 1175 if(HEADTYPE == Hwindows) 1176 segdata.fileoff = segtext.fileoff + rnd(segtext.len, PEFILEALIGN); 1177 if(HEADTYPE == Hplan9) 1178 segdata.fileoff = segtext.fileoff + segtext.filelen; 1179 data = nil; 1180 noptr = nil; 1181 bss = nil; 1182 noptrbss = nil; 1183 for(s=segdata.sect; s != nil; s=s->next) { 1184 vlen = s->len; 1185 if(s->next) 1186 vlen = s->next->vaddr - s->vaddr; 1187 s->vaddr = va; 1188 va += vlen; 1189 segdata.len = va - segdata.vaddr; 1190 if(strcmp(s->name, ".data") == 0) 1191 data = s; 1192 if(strcmp(s->name, ".noptrdata") == 0) 1193 noptr = s; 1194 if(strcmp(s->name, ".bss") == 0) 1195 bss = s; 1196 if(strcmp(s->name, ".noptrbss") == 0) 1197 noptrbss = s; 1198 } 1199 segdata.filelen = bss->vaddr - segdata.vaddr; 1200 1201 text = segtext.sect; 1202 if(segrodata.sect) 1203 rodata = segrodata.sect; 1204 else 1205 rodata = text->next; 1206 typelink = rodata->next; 1207 symtab = typelink->next; 1208 pclntab = symtab->next; 1209 1210 for(sym = datap; sym != nil; sym = sym->next) { 1211 ctxt->cursym = sym; 1212 if(sym->sect != nil) 1213 sym->value += sym->sect->vaddr; 1214 for(sub = sym->sub; sub != nil; sub = sub->sub) 1215 sub->value += sym->value; 1216 } 1217 1218 xdefine("text", STEXT, text->vaddr); 1219 xdefine("etext", STEXT, text->vaddr + text->len); 1220 xdefine("rodata", SRODATA, rodata->vaddr); 1221 xdefine("erodata", SRODATA, rodata->vaddr + rodata->len); 1222 xdefine("typelink", SRODATA, typelink->vaddr); 1223 xdefine("etypelink", SRODATA, typelink->vaddr + typelink->len); 1224 1225 sym = linklookup(ctxt, "gcdata", 0); 1226 xdefine("egcdata", SRODATA, symaddr(sym) + sym->size); 1227 linklookup(ctxt, "egcdata", 0)->sect = sym->sect; 1228 1229 sym = linklookup(ctxt, "gcbss", 0); 1230 xdefine("egcbss", SRODATA, symaddr(sym) + sym->size); 1231 linklookup(ctxt, "egcbss", 0)->sect = sym->sect; 1232 1233 xdefine("symtab", SRODATA, symtab->vaddr); 1234 xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len); 1235 xdefine("pclntab", SRODATA, pclntab->vaddr); 1236 xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len); 1237 xdefine("noptrdata", SNOPTRDATA, noptr->vaddr); 1238 xdefine("enoptrdata", SNOPTRDATA, noptr->vaddr + noptr->len); 1239 xdefine("bss", SBSS, bss->vaddr); 1240 xdefine("ebss", SBSS, bss->vaddr + bss->len); 1241 xdefine("data", SDATA, data->vaddr); 1242 xdefine("edata", SDATA, data->vaddr + data->len); 1243 xdefine("noptrbss", SNOPTRBSS, noptrbss->vaddr); 1244 xdefine("enoptrbss", SNOPTRBSS, noptrbss->vaddr + noptrbss->len); 1245 xdefine("end", SBSS, segdata.vaddr + segdata.len); 1246 }