github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/src/cmd/ld/elf.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "l.h" 6 #include "lib.h" 7 #include "../ld/elf.h" 8 9 /* 10 * We use the 64-bit data structures on both 32- and 64-bit machines 11 * in order to write the code just once. The 64-bit data structure is 12 * written in the 32-bit format on the 32-bit machines. 13 */ 14 #define NSECT 48 15 16 int iself; 17 18 static int elf64; 19 static ElfEhdr hdr; 20 static ElfPhdr *phdr[NSECT]; 21 static ElfShdr *shdr[NSECT]; 22 static char *interp; 23 24 typedef struct Elfstring Elfstring; 25 struct Elfstring 26 { 27 char *s; 28 int off; 29 }; 30 31 static Elfstring elfstr[100]; 32 static int nelfstr; 33 34 static char buildinfo[32]; 35 36 /* 37 Initialize the global variable that describes the ELF header. It will be updated as 38 we write section and prog headers. 39 */ 40 void 41 elfinit(void) 42 { 43 iself = 1; 44 45 switch(thechar) { 46 // 64-bit architectures 47 case '9': 48 if(ctxt->arch->endian == BigEndian) 49 hdr.flags = 1; /* Version 1 ABI */ 50 else 51 hdr.flags = 2; /* Version 2 ABI */ 52 // fallthrough 53 case '6': 54 elf64 = 1; 55 hdr.phoff = ELF64HDRSIZE; /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */ 56 hdr.shoff = ELF64HDRSIZE; /* Will move as we add PHeaders */ 57 hdr.ehsize = ELF64HDRSIZE; /* Must be ELF64HDRSIZE */ 58 hdr.phentsize = ELF64PHDRSIZE; /* Must be ELF64PHDRSIZE */ 59 hdr.shentsize = ELF64SHDRSIZE; /* Must be ELF64SHDRSIZE */ 60 break; 61 62 // 32-bit architectures 63 case '5': 64 // we use EABI on both linux/arm and freebsd/arm. 65 if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd) 66 hdr.flags = 0x5000002; // has entry point, Version5 EABI 67 // fallthrough 68 default: 69 hdr.phoff = ELF32HDRSIZE; /* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */ 70 hdr.shoff = ELF32HDRSIZE; /* Will move as we add PHeaders */ 71 hdr.ehsize = ELF32HDRSIZE; /* Must be ELF32HDRSIZE */ 72 hdr.phentsize = ELF32PHDRSIZE; /* Must be ELF32PHDRSIZE */ 73 hdr.shentsize = ELF32SHDRSIZE; /* Must be ELF32SHDRSIZE */ 74 } 75 } 76 77 void 78 elf64phdr(ElfPhdr *e) 79 { 80 LPUT(e->type); 81 LPUT(e->flags); 82 VPUT(e->off); 83 VPUT(e->vaddr); 84 VPUT(e->paddr); 85 VPUT(e->filesz); 86 VPUT(e->memsz); 87 VPUT(e->align); 88 } 89 90 void 91 elf32phdr(ElfPhdr *e) 92 { 93 int frag; 94 95 if(e->type == PT_LOAD) { 96 // Correct ELF loaders will do this implicitly, 97 // but buggy ELF loaders like the one in some 98 // versions of QEMU won't. 99 frag = e->vaddr&(e->align-1); 100 e->off -= frag; 101 e->vaddr -= frag; 102 e->paddr -= frag; 103 e->filesz += frag; 104 e->memsz += frag; 105 } 106 LPUT(e->type); 107 LPUT(e->off); 108 LPUT(e->vaddr); 109 LPUT(e->paddr); 110 LPUT(e->filesz); 111 LPUT(e->memsz); 112 LPUT(e->flags); 113 LPUT(e->align); 114 } 115 116 void 117 elf64shdr(ElfShdr *e) 118 { 119 LPUT(e->name); 120 LPUT(e->type); 121 VPUT(e->flags); 122 VPUT(e->addr); 123 VPUT(e->off); 124 VPUT(e->size); 125 LPUT(e->link); 126 LPUT(e->info); 127 VPUT(e->addralign); 128 VPUT(e->entsize); 129 } 130 131 void 132 elf32shdr(ElfShdr *e) 133 { 134 LPUT(e->name); 135 LPUT(e->type); 136 LPUT(e->flags); 137 LPUT(e->addr); 138 LPUT(e->off); 139 LPUT(e->size); 140 LPUT(e->link); 141 LPUT(e->info); 142 LPUT(e->addralign); 143 LPUT(e->entsize); 144 } 145 146 uint32 147 elfwriteshdrs(void) 148 { 149 int i; 150 151 if (elf64) { 152 for (i = 0; i < hdr.shnum; i++) 153 elf64shdr(shdr[i]); 154 return hdr.shnum * ELF64SHDRSIZE; 155 } 156 for (i = 0; i < hdr.shnum; i++) 157 elf32shdr(shdr[i]); 158 return hdr.shnum * ELF32SHDRSIZE; 159 } 160 161 void 162 elfsetstring(char *s, int off) 163 { 164 if(nelfstr >= nelem(elfstr)) { 165 diag("too many elf strings"); 166 errorexit(); 167 } 168 elfstr[nelfstr].s = s; 169 elfstr[nelfstr].off = off; 170 nelfstr++; 171 } 172 173 uint32 174 elfwritephdrs(void) 175 { 176 int i; 177 178 if (elf64) { 179 for (i = 0; i < hdr.phnum; i++) 180 elf64phdr(phdr[i]); 181 return hdr.phnum * ELF64PHDRSIZE; 182 } 183 for (i = 0; i < hdr.phnum; i++) 184 elf32phdr(phdr[i]); 185 return hdr.phnum * ELF32PHDRSIZE; 186 } 187 188 ElfPhdr* 189 newElfPhdr(void) 190 { 191 ElfPhdr *e; 192 193 e = mal(sizeof *e); 194 if (hdr.phnum >= NSECT) 195 diag("too many phdrs"); 196 else 197 phdr[hdr.phnum++] = e; 198 if (elf64) 199 hdr.shoff += ELF64PHDRSIZE; 200 else 201 hdr.shoff += ELF32PHDRSIZE; 202 return e; 203 } 204 205 ElfShdr* 206 newElfShdr(vlong name) 207 { 208 ElfShdr *e; 209 210 e = mal(sizeof *e); 211 e->name = name; 212 e->shnum = hdr.shnum; 213 if (hdr.shnum >= NSECT) { 214 diag("too many shdrs"); 215 } else { 216 shdr[hdr.shnum++] = e; 217 } 218 return e; 219 } 220 221 ElfEhdr* 222 getElfEhdr(void) 223 { 224 return &hdr; 225 } 226 227 uint32 228 elf64writehdr(void) 229 { 230 int i; 231 232 for (i = 0; i < EI_NIDENT; i++) 233 cput(hdr.ident[i]); 234 WPUT(hdr.type); 235 WPUT(hdr.machine); 236 LPUT(hdr.version); 237 VPUT(hdr.entry); 238 VPUT(hdr.phoff); 239 VPUT(hdr.shoff); 240 LPUT(hdr.flags); 241 WPUT(hdr.ehsize); 242 WPUT(hdr.phentsize); 243 WPUT(hdr.phnum); 244 WPUT(hdr.shentsize); 245 WPUT(hdr.shnum); 246 WPUT(hdr.shstrndx); 247 return ELF64HDRSIZE; 248 } 249 250 uint32 251 elf32writehdr(void) 252 { 253 int i; 254 255 for (i = 0; i < EI_NIDENT; i++) 256 cput(hdr.ident[i]); 257 WPUT(hdr.type); 258 WPUT(hdr.machine); 259 LPUT(hdr.version); 260 LPUT(hdr.entry); 261 LPUT(hdr.phoff); 262 LPUT(hdr.shoff); 263 LPUT(hdr.flags); 264 WPUT(hdr.ehsize); 265 WPUT(hdr.phentsize); 266 WPUT(hdr.phnum); 267 WPUT(hdr.shentsize); 268 WPUT(hdr.shnum); 269 WPUT(hdr.shstrndx); 270 return ELF32HDRSIZE; 271 } 272 273 uint32 274 elfwritehdr(void) 275 { 276 if(elf64) 277 return elf64writehdr(); 278 return elf32writehdr(); 279 } 280 281 /* Taken directly from the definition document for ELF64 */ 282 uint32 283 elfhash(uchar *name) 284 { 285 uint32 h = 0, g; 286 while (*name) { 287 h = (h << 4) + *name++; 288 if (g = h & 0xf0000000) 289 h ^= g >> 24; 290 h &= 0x0fffffff; 291 } 292 return h; 293 } 294 295 void 296 elfwritedynent(LSym *s, int tag, uint64 val) 297 { 298 if(elf64) { 299 adduint64(ctxt, s, tag); 300 adduint64(ctxt, s, val); 301 } else { 302 adduint32(ctxt, s, tag); 303 adduint32(ctxt, s, val); 304 } 305 } 306 307 void 308 elfwritedynentsym(LSym *s, int tag, LSym *t) 309 { 310 if(elf64) 311 adduint64(ctxt, s, tag); 312 else 313 adduint32(ctxt, s, tag); 314 addaddr(ctxt, s, t); 315 } 316 317 void 318 elfwritedynentsymsize(LSym *s, int tag, LSym *t) 319 { 320 if(elf64) 321 adduint64(ctxt, s, tag); 322 else 323 adduint32(ctxt, s, tag); 324 addsize(ctxt, s, t); 325 } 326 327 int 328 elfinterp(ElfShdr *sh, uint64 startva, uint64 resoff, char *p) 329 { 330 int n; 331 332 interp = p; 333 n = strlen(interp)+1; 334 sh->addr = startva + resoff - n; 335 sh->off = resoff - n; 336 sh->size = n; 337 338 return n; 339 } 340 341 int 342 elfwriteinterp(void) 343 { 344 ElfShdr *sh; 345 346 sh = elfshname(".interp"); 347 cseek(sh->off); 348 cwrite(interp, sh->size); 349 return sh->size; 350 } 351 352 int 353 elfnote(ElfShdr *sh, uint64 startva, uint64 resoff, int sz) 354 { 355 uint64 n; 356 357 n = sizeof(Elf_Note) + sz + resoff % 4; 358 359 sh->type = SHT_NOTE; 360 sh->flags = SHF_ALLOC; 361 sh->addralign = 4; 362 sh->addr = startva + resoff - n; 363 sh->off = resoff - n; 364 sh->size = n - resoff % 4; 365 366 return n; 367 } 368 369 ElfShdr * 370 elfwritenotehdr(char *str, uint32 namesz, uint32 descsz, uint32 tag) 371 { 372 ElfShdr *sh; 373 374 sh = elfshname(str); 375 376 // Write Elf_Note header. 377 cseek(sh->off); 378 LPUT(namesz); 379 LPUT(descsz); 380 LPUT(tag); 381 382 return sh; 383 } 384 385 // NetBSD Signature (as per sys/exec_elf.h) 386 #define ELF_NOTE_NETBSD_NAMESZ 7 387 #define ELF_NOTE_NETBSD_DESCSZ 4 388 #define ELF_NOTE_NETBSD_TAG 1 389 #define ELF_NOTE_NETBSD_NAME "NetBSD\0\0" 390 #define ELF_NOTE_NETBSD_VERSION 599000000 /* NetBSD 5.99 */ 391 392 int 393 elfnetbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff) 394 { 395 int n; 396 397 n = rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + rnd(ELF_NOTE_NETBSD_DESCSZ, 4); 398 return elfnote(sh, startva, resoff, n); 399 } 400 401 int 402 elfwritenetbsdsig(void) 403 { 404 ElfShdr *sh; 405 406 // Write Elf_Note header. 407 sh = elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG); 408 if(sh == nil) 409 return 0; 410 411 // Followed by NetBSD string and version. 412 cwrite(ELF_NOTE_NETBSD_NAME, ELF_NOTE_NETBSD_NAMESZ + 1); 413 LPUT(ELF_NOTE_NETBSD_VERSION); 414 415 return sh->size; 416 } 417 418 // OpenBSD Signature 419 #define ELF_NOTE_OPENBSD_NAMESZ 8 420 #define ELF_NOTE_OPENBSD_DESCSZ 4 421 #define ELF_NOTE_OPENBSD_TAG 1 422 #define ELF_NOTE_OPENBSD_NAME "OpenBSD\0" 423 #define ELF_NOTE_OPENBSD_VERSION 0 424 425 int 426 elfopenbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff) 427 { 428 int n; 429 430 n = ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ; 431 return elfnote(sh, startva, resoff, n); 432 } 433 434 int 435 elfwriteopenbsdsig(void) 436 { 437 ElfShdr *sh; 438 439 // Write Elf_Note header. 440 sh = elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG); 441 if(sh == nil) 442 return 0; 443 444 // Followed by OpenBSD string and version. 445 cwrite(ELF_NOTE_OPENBSD_NAME, ELF_NOTE_OPENBSD_NAMESZ); 446 LPUT(ELF_NOTE_OPENBSD_VERSION); 447 448 return sh->size; 449 } 450 451 void 452 addbuildinfo(char *val) 453 { 454 char *ov; 455 int i, b, j; 456 457 if(val[0] != '0' || val[1] != 'x') { 458 fprint(2, "%s: -B argument must start with 0x: %s\n", argv0, val); 459 exits("usage"); 460 } 461 ov = val; 462 val += 2; 463 i = 0; 464 while(*val != '\0') { 465 if(val[1] == '\0') { 466 fprint(2, "%s: -B argument must have even number of digits: %s\n", argv0, ov); 467 exits("usage"); 468 } 469 b = 0; 470 for(j = 0; j < 2; j++, val++) { 471 b *= 16; 472 if(*val >= '0' && *val <= '9') 473 b += *val - '0'; 474 else if(*val >= 'a' && *val <= 'f') 475 b += *val - 'a' + 10; 476 else if(*val >= 'A' && *val <= 'F') 477 b += *val - 'A' + 10; 478 else { 479 fprint(2, "%s: -B argument contains invalid hex digit %c: %s\n", argv0, *val, ov); 480 exits("usage"); 481 } 482 } 483 if(i >= nelem(buildinfo)) { 484 fprint(2, "%s: -B option too long (max %d digits): %s\n", argv0, (int)nelem(buildinfo), ov); 485 exits("usage"); 486 } 487 buildinfo[i++] = b; 488 } 489 buildinfolen = i; 490 } 491 492 // Build info note 493 #define ELF_NOTE_BUILDINFO_NAMESZ 4 494 #define ELF_NOTE_BUILDINFO_TAG 3 495 #define ELF_NOTE_BUILDINFO_NAME "GNU\0" 496 497 int 498 elfbuildinfo(ElfShdr *sh, uint64 startva, uint64 resoff) 499 { 500 int n; 501 502 n = ELF_NOTE_BUILDINFO_NAMESZ + rnd(buildinfolen, 4); 503 return elfnote(sh, startva, resoff, n); 504 } 505 506 int 507 elfwritebuildinfo(void) 508 { 509 ElfShdr *sh; 510 511 sh = elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, buildinfolen, ELF_NOTE_BUILDINFO_TAG); 512 if(sh == nil) 513 return 0; 514 515 cwrite(ELF_NOTE_BUILDINFO_NAME, ELF_NOTE_BUILDINFO_NAMESZ); 516 cwrite(buildinfo, buildinfolen); 517 cwrite("\0\0\0", rnd(buildinfolen, 4) - buildinfolen); 518 519 return sh->size; 520 } 521 522 extern int nelfsym; 523 int elfverneed; 524 525 typedef struct Elfaux Elfaux; 526 typedef struct Elflib Elflib; 527 528 struct Elflib 529 { 530 Elflib *next; 531 Elfaux *aux; 532 char *file; 533 }; 534 535 struct Elfaux 536 { 537 Elfaux *next; 538 int num; 539 char *vers; 540 }; 541 542 Elfaux* 543 addelflib(Elflib **list, char *file, char *vers) 544 { 545 Elflib *lib; 546 Elfaux *aux; 547 548 for(lib=*list; lib; lib=lib->next) 549 if(strcmp(lib->file, file) == 0) 550 goto havelib; 551 lib = mal(sizeof *lib); 552 lib->next = *list; 553 lib->file = file; 554 *list = lib; 555 havelib: 556 for(aux=lib->aux; aux; aux=aux->next) 557 if(strcmp(aux->vers, vers) == 0) 558 goto haveaux; 559 aux = mal(sizeof *aux); 560 aux->next = lib->aux; 561 aux->vers = vers; 562 lib->aux = aux; 563 haveaux: 564 return aux; 565 } 566 567 void 568 elfdynhash(void) 569 { 570 LSym *s, *sy, *dynstr; 571 int i, j, nbucket, b, nfile; 572 uint32 hc, *chain, *buckets; 573 int nsym; 574 char *name; 575 Elfaux **need; 576 Elflib *needlib; 577 Elflib *l; 578 Elfaux *x; 579 580 if(!iself) 581 return; 582 583 nsym = nelfsym; 584 s = linklookup(ctxt, ".hash", 0); 585 s->type = SELFROSECT; 586 s->reachable = 1; 587 588 i = nsym; 589 nbucket = 1; 590 while(i > 0) { 591 ++nbucket; 592 i >>= 1; 593 } 594 595 needlib = nil; 596 need = malloc(nsym * sizeof need[0]); 597 chain = malloc(nsym * sizeof chain[0]); 598 buckets = malloc(nbucket * sizeof buckets[0]); 599 if(need == nil || chain == nil || buckets == nil) { 600 ctxt->cursym = nil; 601 diag("out of memory"); 602 errorexit(); 603 } 604 memset(need, 0, nsym * sizeof need[0]); 605 memset(chain, 0, nsym * sizeof chain[0]); 606 memset(buckets, 0, nbucket * sizeof buckets[0]); 607 for(sy=ctxt->allsym; sy!=S; sy=sy->allsym) { 608 if (sy->dynid <= 0) 609 continue; 610 611 if(sy->dynimpvers) 612 need[sy->dynid] = addelflib(&needlib, sy->dynimplib, sy->dynimpvers); 613 614 name = sy->extname; 615 hc = elfhash((uchar*)name); 616 617 b = hc % nbucket; 618 chain[sy->dynid] = buckets[b]; 619 buckets[b] = sy->dynid; 620 } 621 622 adduint32(ctxt, s, nbucket); 623 adduint32(ctxt, s, nsym); 624 for(i = 0; i<nbucket; i++) 625 adduint32(ctxt, s, buckets[i]); 626 for(i = 0; i<nsym; i++) 627 adduint32(ctxt, s, chain[i]); 628 629 free(chain); 630 free(buckets); 631 632 // version symbols 633 dynstr = linklookup(ctxt, ".dynstr", 0); 634 s = linklookup(ctxt, ".gnu.version_r", 0); 635 i = 2; 636 nfile = 0; 637 for(l=needlib; l; l=l->next) { 638 nfile++; 639 // header 640 adduint16(ctxt, s, 1); // table version 641 j = 0; 642 for(x=l->aux; x; x=x->next) 643 j++; 644 adduint16(ctxt, s, j); // aux count 645 adduint32(ctxt, s, addstring(dynstr, l->file)); // file string offset 646 adduint32(ctxt, s, 16); // offset from header to first aux 647 if(l->next) 648 adduint32(ctxt, s, 16+j*16); // offset from this header to next 649 else 650 adduint32(ctxt, s, 0); 651 652 for(x=l->aux; x; x=x->next) { 653 x->num = i++; 654 // aux struct 655 adduint32(ctxt, s, elfhash((uchar*)x->vers)); // hash 656 adduint16(ctxt, s, 0); // flags 657 adduint16(ctxt, s, x->num); // other - index we refer to this by 658 adduint32(ctxt, s, addstring(dynstr, x->vers)); // version string offset 659 if(x->next) 660 adduint32(ctxt, s, 16); // offset from this aux to next 661 else 662 adduint32(ctxt, s, 0); 663 } 664 } 665 666 // version references 667 s = linklookup(ctxt, ".gnu.version", 0); 668 for(i=0; i<nsym; i++) { 669 if(i == 0) 670 adduint16(ctxt, s, 0); // first entry - no symbol 671 else if(need[i] == nil) 672 adduint16(ctxt, s, 1); // global 673 else 674 adduint16(ctxt, s, need[i]->num); 675 } 676 677 free(need); 678 679 s = linklookup(ctxt, ".dynamic", 0); 680 elfverneed = nfile; 681 if(elfverneed) { 682 elfwritedynentsym(s, DT_VERNEED, linklookup(ctxt, ".gnu.version_r", 0)); 683 elfwritedynent(s, DT_VERNEEDNUM, nfile); 684 elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0)); 685 } 686 687 if(thechar == '6' || thechar == '9') { 688 sy = linklookup(ctxt, ".rela.plt", 0); 689 if(sy->size > 0) { 690 elfwritedynent(s, DT_PLTREL, DT_RELA); 691 elfwritedynentsymsize(s, DT_PLTRELSZ, sy); 692 elfwritedynentsym(s, DT_JMPREL, sy); 693 } 694 } else { 695 sy = linklookup(ctxt, ".rel.plt", 0); 696 if(sy->size > 0) { 697 elfwritedynent(s, DT_PLTREL, DT_REL); 698 elfwritedynentsymsize(s, DT_PLTRELSZ, sy); 699 elfwritedynentsym(s, DT_JMPREL, sy); 700 } 701 } 702 703 elfwritedynent(s, DT_NULL, 0); 704 } 705 706 ElfPhdr* 707 elfphload(Segment *seg) 708 { 709 ElfPhdr *ph; 710 711 ph = newElfPhdr(); 712 ph->type = PT_LOAD; 713 if(seg->rwx & 4) 714 ph->flags |= PF_R; 715 if(seg->rwx & 2) 716 ph->flags |= PF_W; 717 if(seg->rwx & 1) 718 ph->flags |= PF_X; 719 ph->vaddr = seg->vaddr; 720 ph->paddr = seg->vaddr; 721 ph->memsz = seg->len; 722 ph->off = seg->fileoff; 723 ph->filesz = seg->filelen; 724 ph->align = INITRND; 725 726 return ph; 727 } 728 729 ElfShdr* 730 elfshname(char *name) 731 { 732 int i, off; 733 ElfShdr *sh; 734 735 for(i=0; i<nelfstr; i++) { 736 if(strcmp(name, elfstr[i].s) == 0) { 737 off = elfstr[i].off; 738 goto found; 739 } 740 } 741 diag("cannot find elf name %s", name); 742 errorexit(); 743 return nil; 744 745 found: 746 for(i=0; i<hdr.shnum; i++) { 747 sh = shdr[i]; 748 if(sh->name == off) 749 return sh; 750 } 751 752 sh = newElfShdr(off); 753 return sh; 754 } 755 756 ElfShdr* 757 elfshalloc(Section *sect) 758 { 759 ElfShdr *sh; 760 761 sh = elfshname(sect->name); 762 sect->elfsect = sh; 763 return sh; 764 } 765 766 ElfShdr* 767 elfshbits(Section *sect) 768 { 769 ElfShdr *sh; 770 771 sh = elfshalloc(sect); 772 if(sh->type > 0) 773 return sh; 774 775 if(sect->vaddr < sect->seg->vaddr + sect->seg->filelen) 776 sh->type = SHT_PROGBITS; 777 else 778 sh->type = SHT_NOBITS; 779 sh->flags = SHF_ALLOC; 780 if(sect->rwx & 1) 781 sh->flags |= SHF_EXECINSTR; 782 if(sect->rwx & 2) 783 sh->flags |= SHF_WRITE; 784 if(strcmp(sect->name, ".tbss") == 0) { 785 if(strcmp(goos, "android") != 0) 786 sh->flags |= SHF_TLS; // no TLS on android 787 sh->type = SHT_NOBITS; 788 } 789 if(linkmode != LinkExternal) 790 sh->addr = sect->vaddr; 791 sh->addralign = sect->align; 792 sh->size = sect->len; 793 sh->off = sect->seg->fileoff + sect->vaddr - sect->seg->vaddr; 794 795 return sh; 796 } 797 798 ElfShdr* 799 elfshreloc(Section *sect) 800 { 801 int typ; 802 ElfShdr *sh; 803 char *prefix; 804 char buf[100]; 805 806 // If main section is SHT_NOBITS, nothing to relocate. 807 // Also nothing to relocate in .shstrtab. 808 if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen) 809 return nil; 810 if(strcmp(sect->name, ".shstrtab") == 0 || strcmp(sect->name, ".tbss") == 0) 811 return nil; 812 813 if(thechar == '6' || thechar == '9') { 814 prefix = ".rela"; 815 typ = SHT_RELA; 816 } else { 817 prefix = ".rel"; 818 typ = SHT_REL; 819 } 820 821 snprint(buf, sizeof buf, "%s%s", prefix, sect->name); 822 sh = elfshname(buf); 823 sh->type = typ; 824 sh->entsize = RegSize*(2+(typ==SHT_RELA)); 825 sh->link = elfshname(".symtab")->shnum; 826 sh->info = sect->elfsect->shnum; 827 sh->off = sect->reloff; 828 sh->size = sect->rellen; 829 sh->addralign = RegSize; 830 return sh; 831 } 832 833 void 834 elfrelocsect(Section *sect, LSym *first) 835 { 836 LSym *sym; 837 int32 eaddr; 838 Reloc *r; 839 840 // If main section is SHT_NOBITS, nothing to relocate. 841 // Also nothing to relocate in .shstrtab. 842 if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen) 843 return; 844 if(strcmp(sect->name, ".shstrtab") == 0) 845 return; 846 847 sect->reloff = cpos(); 848 for(sym = first; sym != nil; sym = sym->next) { 849 if(!sym->reachable) 850 continue; 851 if(sym->value >= sect->vaddr) 852 break; 853 } 854 855 eaddr = sect->vaddr + sect->len; 856 for(; sym != nil; sym = sym->next) { 857 if(!sym->reachable) 858 continue; 859 if(sym->value >= eaddr) 860 break; 861 ctxt->cursym = sym; 862 863 for(r = sym->r; r < sym->r+sym->nr; r++) { 864 if(r->done) 865 continue; 866 if(r->xsym == nil) { 867 diag("missing xsym in relocation"); 868 continue; 869 } 870 if(r->xsym->elfsym == 0) 871 diag("reloc %d to non-elf symbol %s (outer=%s) %d", r->type, r->sym->name, r->xsym->name, r->sym->type); 872 if(elfreloc1(r, sym->value+r->off - sect->vaddr) < 0) 873 diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name); 874 } 875 } 876 877 sect->rellen = cpos() - sect->reloff; 878 } 879 880 void 881 elfemitreloc(void) 882 { 883 Section *sect; 884 885 while(cpos()&7) 886 cput(0); 887 888 elfrelocsect(segtext.sect, ctxt->textp); 889 for(sect=segtext.sect->next; sect!=nil; sect=sect->next) 890 elfrelocsect(sect, datap); 891 for(sect=segrodata.sect; sect!=nil; sect=sect->next) 892 elfrelocsect(sect, datap); 893 for(sect=segdata.sect; sect!=nil; sect=sect->next) 894 elfrelocsect(sect, datap); 895 } 896 897 void 898 doelf(void) 899 { 900 LSym *s, *shstrtab, *dynstr; 901 902 if(!iself) 903 return; 904 905 /* predefine strings we need for section headers */ 906 shstrtab = linklookup(ctxt, ".shstrtab", 0); 907 shstrtab->type = SELFROSECT; 908 shstrtab->reachable = 1; 909 910 addstring(shstrtab, ""); 911 addstring(shstrtab, ".text"); 912 addstring(shstrtab, ".noptrdata"); 913 addstring(shstrtab, ".data"); 914 addstring(shstrtab, ".bss"); 915 addstring(shstrtab, ".noptrbss"); 916 // generate .tbss section (except for OpenBSD where it's not supported) 917 // for dynamic internal linker or external linking, so that various 918 // binutils could correctly calculate PT_TLS size. 919 // see http://golang.org/issue/5200. 920 if(HEADTYPE != Hopenbsd) 921 if(!debug['d'] || linkmode == LinkExternal) 922 addstring(shstrtab, ".tbss"); 923 if(HEADTYPE == Hnetbsd) 924 addstring(shstrtab, ".note.netbsd.ident"); 925 if(HEADTYPE == Hopenbsd) 926 addstring(shstrtab, ".note.openbsd.ident"); 927 if(buildinfolen > 0) 928 addstring(shstrtab, ".note.gnu.build-id"); 929 addstring(shstrtab, ".elfdata"); 930 addstring(shstrtab, ".rodata"); 931 addstring(shstrtab, ".typelink"); 932 addstring(shstrtab, ".gosymtab"); 933 addstring(shstrtab, ".gopclntab"); 934 935 if(linkmode == LinkExternal) { 936 debug_s = debug['s']; 937 debug['s'] = 0; 938 debug['d'] = 1; 939 940 if(thechar == '6' || thechar == '9') { 941 addstring(shstrtab, ".rela.text"); 942 addstring(shstrtab, ".rela.rodata"); 943 addstring(shstrtab, ".rela.typelink"); 944 addstring(shstrtab, ".rela.gosymtab"); 945 addstring(shstrtab, ".rela.gopclntab"); 946 addstring(shstrtab, ".rela.noptrdata"); 947 addstring(shstrtab, ".rela.data"); 948 } else { 949 addstring(shstrtab, ".rel.text"); 950 addstring(shstrtab, ".rel.rodata"); 951 addstring(shstrtab, ".rel.typelink"); 952 addstring(shstrtab, ".rel.gosymtab"); 953 addstring(shstrtab, ".rel.gopclntab"); 954 addstring(shstrtab, ".rel.noptrdata"); 955 addstring(shstrtab, ".rel.data"); 956 } 957 // add a .note.GNU-stack section to mark the stack as non-executable 958 addstring(shstrtab, ".note.GNU-stack"); 959 } 960 961 if(flag_shared) { 962 addstring(shstrtab, ".init_array"); 963 if(thechar == '6' || thechar == '9') 964 addstring(shstrtab, ".rela.init_array"); 965 else 966 addstring(shstrtab, ".rel.init_array"); 967 } 968 969 if(!debug['s']) { 970 addstring(shstrtab, ".symtab"); 971 addstring(shstrtab, ".strtab"); 972 dwarfaddshstrings(shstrtab); 973 } 974 addstring(shstrtab, ".shstrtab"); 975 976 if(!debug['d']) { /* -d suppresses dynamic loader format */ 977 addstring(shstrtab, ".interp"); 978 addstring(shstrtab, ".hash"); 979 addstring(shstrtab, ".got"); 980 addstring(shstrtab, ".got.plt"); 981 addstring(shstrtab, ".dynamic"); 982 addstring(shstrtab, ".dynsym"); 983 addstring(shstrtab, ".dynstr"); 984 if(thechar == '6' || thechar == '9') { 985 addstring(shstrtab, ".rela"); 986 addstring(shstrtab, ".rela.plt"); 987 } else { 988 addstring(shstrtab, ".rel"); 989 addstring(shstrtab, ".rel.plt"); 990 } 991 addstring(shstrtab, ".plt"); 992 addstring(shstrtab, ".gnu.version"); 993 addstring(shstrtab, ".gnu.version_r"); 994 995 /* dynamic symbol table - first entry all zeros */ 996 s = linklookup(ctxt, ".dynsym", 0); 997 s->type = SELFROSECT; 998 s->reachable = 1; 999 if(thechar == '6' || thechar == '9') 1000 s->size += ELF64SYMSIZE; 1001 else 1002 s->size += ELF32SYMSIZE; 1003 1004 /* dynamic string table */ 1005 s = linklookup(ctxt, ".dynstr", 0); 1006 s->type = SELFROSECT; 1007 s->reachable = 1; 1008 if(s->size == 0) 1009 addstring(s, ""); 1010 dynstr = s; 1011 1012 /* relocation table */ 1013 if(thechar == '6' || thechar == '9') 1014 s = linklookup(ctxt, ".rela", 0); 1015 else 1016 s = linklookup(ctxt, ".rel", 0); 1017 s->reachable = 1; 1018 s->type = SELFROSECT; 1019 1020 /* global offset table */ 1021 s = linklookup(ctxt, ".got", 0); 1022 s->reachable = 1; 1023 s->type = SELFSECT; // writable 1024 1025 /* hash */ 1026 s = linklookup(ctxt, ".hash", 0); 1027 s->reachable = 1; 1028 s->type = SELFROSECT; 1029 1030 s = linklookup(ctxt, ".got.plt", 0); 1031 s->reachable = 1; 1032 s->type = SELFSECT; // writable 1033 1034 s = linklookup(ctxt, ".plt", 0); 1035 s->reachable = 1; 1036 s->type = SELFRXSECT; 1037 1038 elfsetupplt(); 1039 1040 if(thechar == '6' || thechar == '9') 1041 s = linklookup(ctxt, ".rela.plt", 0); 1042 else 1043 s = linklookup(ctxt, ".rel.plt", 0); 1044 s->reachable = 1; 1045 s->type = SELFROSECT; 1046 1047 s = linklookup(ctxt, ".gnu.version", 0); 1048 s->reachable = 1; 1049 s->type = SELFROSECT; 1050 1051 s = linklookup(ctxt, ".gnu.version_r", 0); 1052 s->reachable = 1; 1053 s->type = SELFROSECT; 1054 1055 /* define dynamic elf table */ 1056 s = linklookup(ctxt, ".dynamic", 0); 1057 s->reachable = 1; 1058 s->type = SELFSECT; // writable 1059 1060 /* 1061 * .dynamic table 1062 */ 1063 elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0)); 1064 elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0)); 1065 if(thechar == '6' || thechar == '9') 1066 elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE); 1067 else 1068 elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); 1069 elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0)); 1070 elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0)); 1071 if(thechar == '6' || thechar == '9') { 1072 elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0)); 1073 elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0)); 1074 elfwritedynent(s, DT_RELAENT, ELF64RELASIZE); 1075 } else { 1076 elfwritedynentsym(s, DT_REL, linklookup(ctxt, ".rel", 0)); 1077 elfwritedynentsymsize(s, DT_RELSZ, linklookup(ctxt, ".rel", 0)); 1078 elfwritedynent(s, DT_RELENT, ELF32RELSIZE); 1079 } 1080 if(rpath) 1081 elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath)); 1082 1083 elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".got.plt", 0)); 1084 1085 // Solaris dynamic linker can't handle an empty .rela.plt if 1086 // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL, 1087 // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the 1088 // size of .rel(a).plt section. 1089 elfwritedynent(s, DT_DEBUG, 0); 1090 1091 // Do not write DT_NULL. elfdynhash will finish it. 1092 } 1093 } 1094 1095 void 1096 shsym(ElfShdr *sh, LSym *s) 1097 { 1098 vlong addr; 1099 addr = symaddr(s); 1100 if(sh->flags&SHF_ALLOC) 1101 sh->addr = addr; 1102 sh->off = datoff(addr); 1103 sh->size = s->size; 1104 } 1105 1106 void 1107 phsh(ElfPhdr *ph, ElfShdr *sh) 1108 { 1109 ph->vaddr = sh->addr; 1110 ph->paddr = ph->vaddr; 1111 ph->off = sh->off; 1112 ph->filesz = sh->size; 1113 ph->memsz = sh->size; 1114 ph->align = sh->addralign; 1115 } 1116 1117 void 1118 asmbelfsetup(void) 1119 { 1120 Section *sect; 1121 1122 /* This null SHdr must appear before all others */ 1123 elfshname(""); 1124 1125 for(sect=segtext.sect; sect!=nil; sect=sect->next) 1126 elfshalloc(sect); 1127 for(sect=segrodata.sect; sect!=nil; sect=sect->next) 1128 elfshalloc(sect); 1129 for(sect=segdata.sect; sect!=nil; sect=sect->next) 1130 elfshalloc(sect); 1131 } 1132 1133 void 1134 asmbelf(vlong symo) 1135 { 1136 vlong a, o; 1137 vlong startva, resoff; 1138 ElfEhdr *eh; 1139 ElfPhdr *ph, *pph, *pnote; 1140 ElfShdr *sh; 1141 Section *sect; 1142 1143 eh = getElfEhdr(); 1144 switch(thechar) { 1145 default: 1146 diag("unknown architecture in asmbelf"); 1147 errorexit(); 1148 case '5': 1149 eh->machine = EM_ARM; 1150 break; 1151 case '6': 1152 eh->machine = EM_X86_64; 1153 break; 1154 case '8': 1155 eh->machine = EM_386; 1156 break; 1157 case '9': 1158 eh->machine = EM_PPC64; 1159 break; 1160 } 1161 1162 startva = INITTEXT - HEADR; 1163 resoff = ELFRESERVE; 1164 1165 pph = nil; 1166 if(linkmode == LinkExternal) { 1167 /* skip program headers */ 1168 eh->phoff = 0; 1169 eh->phentsize = 0; 1170 goto elfobj; 1171 } 1172 1173 /* program header info */ 1174 pph = newElfPhdr(); 1175 pph->type = PT_PHDR; 1176 pph->flags = PF_R; 1177 pph->off = eh->ehsize; 1178 pph->vaddr = INITTEXT - HEADR + pph->off; 1179 pph->paddr = INITTEXT - HEADR + pph->off; 1180 pph->align = INITRND; 1181 1182 /* 1183 * PHDR must be in a loaded segment. Adjust the text 1184 * segment boundaries downwards to include it. 1185 * Except on NaCl where it must not be loaded. 1186 */ 1187 if(HEADTYPE != Hnacl) { 1188 o = segtext.vaddr - pph->vaddr; 1189 segtext.vaddr -= o; 1190 segtext.len += o; 1191 o = segtext.fileoff - pph->off; 1192 segtext.fileoff -= o; 1193 segtext.filelen += o; 1194 } 1195 1196 if(!debug['d']) { 1197 /* interpreter */ 1198 sh = elfshname(".interp"); 1199 sh->type = SHT_PROGBITS; 1200 sh->flags = SHF_ALLOC; 1201 sh->addralign = 1; 1202 if(interpreter == nil) { 1203 switch(HEADTYPE) { 1204 case Hlinux: 1205 interpreter = linuxdynld; 1206 break; 1207 case Hfreebsd: 1208 interpreter = freebsddynld; 1209 break; 1210 case Hnetbsd: 1211 interpreter = netbsddynld; 1212 break; 1213 case Hopenbsd: 1214 interpreter = openbsddynld; 1215 break; 1216 case Hdragonfly: 1217 interpreter = dragonflydynld; 1218 break; 1219 case Hsolaris: 1220 interpreter = solarisdynld; 1221 break; 1222 } 1223 } 1224 resoff -= elfinterp(sh, startva, resoff, interpreter); 1225 1226 ph = newElfPhdr(); 1227 ph->type = PT_INTERP; 1228 ph->flags = PF_R; 1229 phsh(ph, sh); 1230 } 1231 1232 pnote = nil; 1233 if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) { 1234 sh = nil; 1235 switch(HEADTYPE) { 1236 case Hnetbsd: 1237 sh = elfshname(".note.netbsd.ident"); 1238 resoff -= elfnetbsdsig(sh, startva, resoff); 1239 break; 1240 case Hopenbsd: 1241 sh = elfshname(".note.openbsd.ident"); 1242 resoff -= elfopenbsdsig(sh, startva, resoff); 1243 break; 1244 } 1245 1246 pnote = newElfPhdr(); 1247 pnote->type = PT_NOTE; 1248 pnote->flags = PF_R; 1249 phsh(pnote, sh); 1250 } 1251 1252 if(buildinfolen > 0) { 1253 sh = elfshname(".note.gnu.build-id"); 1254 resoff -= elfbuildinfo(sh, startva, resoff); 1255 1256 if(pnote == nil) { 1257 pnote = newElfPhdr(); 1258 pnote->type = PT_NOTE; 1259 pnote->flags = PF_R; 1260 } 1261 phsh(pnote, sh); 1262 } 1263 1264 // Additions to the reserved area must be above this line. 1265 USED(resoff); 1266 1267 elfphload(&segtext); 1268 if(segrodata.sect != nil) 1269 elfphload(&segrodata); 1270 elfphload(&segdata); 1271 1272 /* Dynamic linking sections */ 1273 if(!debug['d']) { /* -d suppresses dynamic loader format */ 1274 sh = elfshname(".dynsym"); 1275 sh->type = SHT_DYNSYM; 1276 sh->flags = SHF_ALLOC; 1277 if(elf64) 1278 sh->entsize = ELF64SYMSIZE; 1279 else 1280 sh->entsize = ELF32SYMSIZE; 1281 sh->addralign = RegSize; 1282 sh->link = elfshname(".dynstr")->shnum; 1283 // sh->info = index of first non-local symbol (number of local symbols) 1284 shsym(sh, linklookup(ctxt, ".dynsym", 0)); 1285 1286 sh = elfshname(".dynstr"); 1287 sh->type = SHT_STRTAB; 1288 sh->flags = SHF_ALLOC; 1289 sh->addralign = 1; 1290 shsym(sh, linklookup(ctxt, ".dynstr", 0)); 1291 1292 if(elfverneed) { 1293 sh = elfshname(".gnu.version"); 1294 sh->type = SHT_GNU_VERSYM; 1295 sh->flags = SHF_ALLOC; 1296 sh->addralign = 2; 1297 sh->link = elfshname(".dynsym")->shnum; 1298 sh->entsize = 2; 1299 shsym(sh, linklookup(ctxt, ".gnu.version", 0)); 1300 1301 sh = elfshname(".gnu.version_r"); 1302 sh->type = SHT_GNU_VERNEED; 1303 sh->flags = SHF_ALLOC; 1304 sh->addralign = RegSize; 1305 sh->info = elfverneed; 1306 sh->link = elfshname(".dynstr")->shnum; 1307 shsym(sh, linklookup(ctxt, ".gnu.version_r", 0)); 1308 } 1309 1310 switch(eh->machine) { 1311 case EM_X86_64: 1312 sh = elfshname(".rela.plt"); 1313 sh->type = SHT_RELA; 1314 sh->flags = SHF_ALLOC; 1315 sh->entsize = ELF64RELASIZE; 1316 sh->addralign = RegSize; 1317 sh->link = elfshname(".dynsym")->shnum; 1318 sh->info = elfshname(".plt")->shnum; 1319 shsym(sh, linklookup(ctxt, ".rela.plt", 0)); 1320 1321 sh = elfshname(".rela"); 1322 sh->type = SHT_RELA; 1323 sh->flags = SHF_ALLOC; 1324 sh->entsize = ELF64RELASIZE; 1325 sh->addralign = 8; 1326 sh->link = elfshname(".dynsym")->shnum; 1327 shsym(sh, linklookup(ctxt, ".rela", 0)); 1328 break; 1329 1330 default: 1331 sh = elfshname(".rel.plt"); 1332 sh->type = SHT_REL; 1333 sh->flags = SHF_ALLOC; 1334 sh->entsize = ELF32RELSIZE; 1335 sh->link = elfshname(".dynsym")->shnum; 1336 shsym(sh, linklookup(ctxt, ".rel.plt", 0)); 1337 1338 sh = elfshname(".rel"); 1339 sh->type = SHT_REL; 1340 sh->flags = SHF_ALLOC; 1341 sh->entsize = ELF32RELSIZE; 1342 sh->addralign = 4; 1343 sh->link = elfshname(".dynsym")->shnum; 1344 shsym(sh, linklookup(ctxt, ".rel", 0)); 1345 break; 1346 } 1347 1348 sh = elfshname(".plt"); 1349 sh->type = SHT_PROGBITS; 1350 sh->flags = SHF_ALLOC+SHF_EXECINSTR; 1351 if(eh->machine == EM_X86_64) 1352 sh->entsize = 16; 1353 else 1354 sh->entsize = 4; 1355 sh->addralign = 4; 1356 shsym(sh, linklookup(ctxt, ".plt", 0)); 1357 1358 sh = elfshname(".got"); 1359 sh->type = SHT_PROGBITS; 1360 sh->flags = SHF_ALLOC+SHF_WRITE; 1361 sh->entsize = RegSize; 1362 sh->addralign = RegSize; 1363 shsym(sh, linklookup(ctxt, ".got", 0)); 1364 1365 sh = elfshname(".got.plt"); 1366 sh->type = SHT_PROGBITS; 1367 sh->flags = SHF_ALLOC+SHF_WRITE; 1368 sh->entsize = RegSize; 1369 sh->addralign = RegSize; 1370 shsym(sh, linklookup(ctxt, ".got.plt", 0)); 1371 1372 sh = elfshname(".hash"); 1373 sh->type = SHT_HASH; 1374 sh->flags = SHF_ALLOC; 1375 sh->entsize = 4; 1376 sh->addralign = RegSize; 1377 sh->link = elfshname(".dynsym")->shnum; 1378 shsym(sh, linklookup(ctxt, ".hash", 0)); 1379 1380 /* sh and PT_DYNAMIC for .dynamic section */ 1381 sh = elfshname(".dynamic"); 1382 sh->type = SHT_DYNAMIC; 1383 sh->flags = SHF_ALLOC+SHF_WRITE; 1384 sh->entsize = 2*RegSize; 1385 sh->addralign = RegSize; 1386 sh->link = elfshname(".dynstr")->shnum; 1387 shsym(sh, linklookup(ctxt, ".dynamic", 0)); 1388 ph = newElfPhdr(); 1389 ph->type = PT_DYNAMIC; 1390 ph->flags = PF_R + PF_W; 1391 phsh(ph, sh); 1392 1393 /* 1394 * Thread-local storage segment (really just size). 1395 */ 1396 // Do not emit PT_TLS for OpenBSD since ld.so(1) does 1397 // not currently support it. This is handled 1398 // appropriately in runtime/cgo. 1399 if(ctxt->tlsoffset != 0 && HEADTYPE != Hopenbsd) { 1400 ph = newElfPhdr(); 1401 ph->type = PT_TLS; 1402 ph->flags = PF_R; 1403 ph->memsz = -ctxt->tlsoffset; 1404 ph->align = RegSize; 1405 } 1406 } 1407 1408 if(HEADTYPE == Hlinux) { 1409 ph = newElfPhdr(); 1410 ph->type = PT_GNU_STACK; 1411 ph->flags = PF_W+PF_R; 1412 ph->align = RegSize; 1413 1414 ph = newElfPhdr(); 1415 ph->type = PT_PAX_FLAGS; 1416 ph->flags = 0x2a00; // mprotect, randexec, emutramp disabled 1417 ph->align = RegSize; 1418 } 1419 1420 elfobj: 1421 sh = elfshname(".shstrtab"); 1422 sh->type = SHT_STRTAB; 1423 sh->addralign = 1; 1424 shsym(sh, linklookup(ctxt, ".shstrtab", 0)); 1425 eh->shstrndx = sh->shnum; 1426 1427 // put these sections early in the list 1428 if(!debug['s']) { 1429 elfshname(".symtab"); 1430 elfshname(".strtab"); 1431 } 1432 1433 for(sect=segtext.sect; sect!=nil; sect=sect->next) 1434 elfshbits(sect); 1435 for(sect=segrodata.sect; sect!=nil; sect=sect->next) 1436 elfshbits(sect); 1437 for(sect=segdata.sect; sect!=nil; sect=sect->next) 1438 elfshbits(sect); 1439 1440 if(linkmode == LinkExternal) { 1441 for(sect=segtext.sect; sect!=nil; sect=sect->next) 1442 elfshreloc(sect); 1443 for(sect=segrodata.sect; sect!=nil; sect=sect->next) 1444 elfshreloc(sect); 1445 for(sect=segdata.sect; sect!=nil; sect=sect->next) 1446 elfshreloc(sect); 1447 // add a .note.GNU-stack section to mark the stack as non-executable 1448 sh = elfshname(".note.GNU-stack"); 1449 sh->type = SHT_PROGBITS; 1450 sh->addralign = 1; 1451 sh->flags = 0; 1452 } 1453 1454 // generate .tbss section for dynamic internal linking (except for OpenBSD) 1455 // external linking generates .tbss in data.c 1456 if(linkmode == LinkInternal && !debug['d'] && HEADTYPE != Hopenbsd) { 1457 sh = elfshname(".tbss"); 1458 sh->type = SHT_NOBITS; 1459 sh->addralign = RegSize; 1460 sh->size = -ctxt->tlsoffset; 1461 sh->flags = SHF_ALLOC | SHF_TLS | SHF_WRITE; 1462 } 1463 1464 if(!debug['s']) { 1465 sh = elfshname(".symtab"); 1466 sh->type = SHT_SYMTAB; 1467 sh->off = symo; 1468 sh->size = symsize; 1469 sh->addralign = RegSize; 1470 sh->entsize = 8+2*RegSize; 1471 sh->link = elfshname(".strtab")->shnum; 1472 sh->info = elfglobalsymndx; 1473 1474 sh = elfshname(".strtab"); 1475 sh->type = SHT_STRTAB; 1476 sh->off = symo+symsize; 1477 sh->size = elfstrsize; 1478 sh->addralign = 1; 1479 1480 dwarfaddelfheaders(); 1481 } 1482 1483 /* Main header */ 1484 eh->ident[EI_MAG0] = '\177'; 1485 eh->ident[EI_MAG1] = 'E'; 1486 eh->ident[EI_MAG2] = 'L'; 1487 eh->ident[EI_MAG3] = 'F'; 1488 if(HEADTYPE == Hfreebsd) 1489 eh->ident[EI_OSABI] = ELFOSABI_FREEBSD; 1490 else if(HEADTYPE == Hnetbsd) 1491 eh->ident[EI_OSABI] = ELFOSABI_NETBSD; 1492 else if(HEADTYPE == Hopenbsd) 1493 eh->ident[EI_OSABI] = ELFOSABI_OPENBSD; 1494 else if(HEADTYPE == Hdragonfly) 1495 eh->ident[EI_OSABI] = ELFOSABI_NONE; 1496 if(elf64) 1497 eh->ident[EI_CLASS] = ELFCLASS64; 1498 else 1499 eh->ident[EI_CLASS] = ELFCLASS32; 1500 if(ctxt->arch->endian == BigEndian) 1501 eh->ident[EI_DATA] = ELFDATA2MSB; 1502 else 1503 eh->ident[EI_DATA] = ELFDATA2LSB; 1504 eh->ident[EI_VERSION] = EV_CURRENT; 1505 1506 if(linkmode == LinkExternal) 1507 eh->type = ET_REL; 1508 else 1509 eh->type = ET_EXEC; 1510 1511 if(linkmode != LinkExternal) 1512 eh->entry = entryvalue(); 1513 1514 eh->version = EV_CURRENT; 1515 1516 if(pph != nil) { 1517 pph->filesz = eh->phnum * eh->phentsize; 1518 pph->memsz = pph->filesz; 1519 } 1520 1521 cseek(0); 1522 a = 0; 1523 a += elfwritehdr(); 1524 a += elfwritephdrs(); 1525 a += elfwriteshdrs(); 1526 if(!debug['d']) 1527 a += elfwriteinterp(); 1528 if(linkmode != LinkExternal) { 1529 if(HEADTYPE == Hnetbsd) 1530 a += elfwritenetbsdsig(); 1531 if(HEADTYPE == Hopenbsd) 1532 a += elfwriteopenbsdsig(); 1533 if(buildinfolen > 0) 1534 a += elfwritebuildinfo(); 1535 } 1536 if(a > ELFRESERVE) 1537 diag("ELFRESERVE too small: %lld > %d", a, ELFRESERVE); 1538 }