github.com/reiver/go@v0.0.0-20150109200633-1d0c7792f172/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 elfwritedynentsymplus(s, tag, t, 0); 311 } 312 313 void 314 elfwritedynentsymplus(LSym *s, int tag, LSym *t, vlong add) 315 { 316 if(elf64) 317 adduint64(ctxt, s, tag); 318 else 319 adduint32(ctxt, s, tag); 320 addaddrplus(ctxt, s, t, add); 321 } 322 323 void 324 elfwritedynentsymsize(LSym *s, int tag, LSym *t) 325 { 326 if(elf64) 327 adduint64(ctxt, s, tag); 328 else 329 adduint32(ctxt, s, tag); 330 addsize(ctxt, s, t); 331 } 332 333 int 334 elfinterp(ElfShdr *sh, uint64 startva, uint64 resoff, char *p) 335 { 336 int n; 337 338 interp = p; 339 n = strlen(interp)+1; 340 sh->addr = startva + resoff - n; 341 sh->off = resoff - n; 342 sh->size = n; 343 344 return n; 345 } 346 347 int 348 elfwriteinterp(void) 349 { 350 ElfShdr *sh; 351 352 sh = elfshname(".interp"); 353 cseek(sh->off); 354 cwrite(interp, sh->size); 355 return sh->size; 356 } 357 358 int 359 elfnote(ElfShdr *sh, uint64 startva, uint64 resoff, int sz) 360 { 361 uint64 n; 362 363 n = sizeof(Elf_Note) + sz + resoff % 4; 364 365 sh->type = SHT_NOTE; 366 sh->flags = SHF_ALLOC; 367 sh->addralign = 4; 368 sh->addr = startva + resoff - n; 369 sh->off = resoff - n; 370 sh->size = n - resoff % 4; 371 372 return n; 373 } 374 375 ElfShdr * 376 elfwritenotehdr(char *str, uint32 namesz, uint32 descsz, uint32 tag) 377 { 378 ElfShdr *sh; 379 380 sh = elfshname(str); 381 382 // Write Elf_Note header. 383 cseek(sh->off); 384 LPUT(namesz); 385 LPUT(descsz); 386 LPUT(tag); 387 388 return sh; 389 } 390 391 // NetBSD Signature (as per sys/exec_elf.h) 392 #define ELF_NOTE_NETBSD_NAMESZ 7 393 #define ELF_NOTE_NETBSD_DESCSZ 4 394 #define ELF_NOTE_NETBSD_TAG 1 395 #define ELF_NOTE_NETBSD_NAME "NetBSD\0\0" 396 #define ELF_NOTE_NETBSD_VERSION 599000000 /* NetBSD 5.99 */ 397 398 int 399 elfnetbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff) 400 { 401 int n; 402 403 n = rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + rnd(ELF_NOTE_NETBSD_DESCSZ, 4); 404 return elfnote(sh, startva, resoff, n); 405 } 406 407 int 408 elfwritenetbsdsig(void) 409 { 410 ElfShdr *sh; 411 412 // Write Elf_Note header. 413 sh = elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG); 414 if(sh == nil) 415 return 0; 416 417 // Followed by NetBSD string and version. 418 cwrite(ELF_NOTE_NETBSD_NAME, ELF_NOTE_NETBSD_NAMESZ + 1); 419 LPUT(ELF_NOTE_NETBSD_VERSION); 420 421 return sh->size; 422 } 423 424 // OpenBSD Signature 425 #define ELF_NOTE_OPENBSD_NAMESZ 8 426 #define ELF_NOTE_OPENBSD_DESCSZ 4 427 #define ELF_NOTE_OPENBSD_TAG 1 428 #define ELF_NOTE_OPENBSD_NAME "OpenBSD\0" 429 #define ELF_NOTE_OPENBSD_VERSION 0 430 431 int 432 elfopenbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff) 433 { 434 int n; 435 436 n = ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ; 437 return elfnote(sh, startva, resoff, n); 438 } 439 440 int 441 elfwriteopenbsdsig(void) 442 { 443 ElfShdr *sh; 444 445 // Write Elf_Note header. 446 sh = elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG); 447 if(sh == nil) 448 return 0; 449 450 // Followed by OpenBSD string and version. 451 cwrite(ELF_NOTE_OPENBSD_NAME, ELF_NOTE_OPENBSD_NAMESZ); 452 LPUT(ELF_NOTE_OPENBSD_VERSION); 453 454 return sh->size; 455 } 456 457 void 458 addbuildinfo(char *val) 459 { 460 char *ov; 461 int i, b, j; 462 463 if(val[0] != '0' || val[1] != 'x') { 464 fprint(2, "%s: -B argument must start with 0x: %s\n", argv0, val); 465 exits("usage"); 466 } 467 ov = val; 468 val += 2; 469 i = 0; 470 while(*val != '\0') { 471 if(val[1] == '\0') { 472 fprint(2, "%s: -B argument must have even number of digits: %s\n", argv0, ov); 473 exits("usage"); 474 } 475 b = 0; 476 for(j = 0; j < 2; j++, val++) { 477 b *= 16; 478 if(*val >= '0' && *val <= '9') 479 b += *val - '0'; 480 else if(*val >= 'a' && *val <= 'f') 481 b += *val - 'a' + 10; 482 else if(*val >= 'A' && *val <= 'F') 483 b += *val - 'A' + 10; 484 else { 485 fprint(2, "%s: -B argument contains invalid hex digit %c: %s\n", argv0, *val, ov); 486 exits("usage"); 487 } 488 } 489 if(i >= nelem(buildinfo)) { 490 fprint(2, "%s: -B option too long (max %d digits): %s\n", argv0, (int)nelem(buildinfo), ov); 491 exits("usage"); 492 } 493 buildinfo[i++] = b; 494 } 495 buildinfolen = i; 496 } 497 498 // Build info note 499 #define ELF_NOTE_BUILDINFO_NAMESZ 4 500 #define ELF_NOTE_BUILDINFO_TAG 3 501 #define ELF_NOTE_BUILDINFO_NAME "GNU\0" 502 503 int 504 elfbuildinfo(ElfShdr *sh, uint64 startva, uint64 resoff) 505 { 506 int n; 507 508 n = ELF_NOTE_BUILDINFO_NAMESZ + rnd(buildinfolen, 4); 509 return elfnote(sh, startva, resoff, n); 510 } 511 512 int 513 elfwritebuildinfo(void) 514 { 515 ElfShdr *sh; 516 517 sh = elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, buildinfolen, ELF_NOTE_BUILDINFO_TAG); 518 if(sh == nil) 519 return 0; 520 521 cwrite(ELF_NOTE_BUILDINFO_NAME, ELF_NOTE_BUILDINFO_NAMESZ); 522 cwrite(buildinfo, buildinfolen); 523 cwrite("\0\0\0", rnd(buildinfolen, 4) - buildinfolen); 524 525 return sh->size; 526 } 527 528 extern int nelfsym; 529 int elfverneed; 530 531 typedef struct Elfaux Elfaux; 532 typedef struct Elflib Elflib; 533 534 struct Elflib 535 { 536 Elflib *next; 537 Elfaux *aux; 538 char *file; 539 }; 540 541 struct Elfaux 542 { 543 Elfaux *next; 544 int num; 545 char *vers; 546 }; 547 548 Elfaux* 549 addelflib(Elflib **list, char *file, char *vers) 550 { 551 Elflib *lib; 552 Elfaux *aux; 553 554 for(lib=*list; lib; lib=lib->next) 555 if(strcmp(lib->file, file) == 0) 556 goto havelib; 557 lib = mal(sizeof *lib); 558 lib->next = *list; 559 lib->file = file; 560 *list = lib; 561 havelib: 562 for(aux=lib->aux; aux; aux=aux->next) 563 if(strcmp(aux->vers, vers) == 0) 564 goto haveaux; 565 aux = mal(sizeof *aux); 566 aux->next = lib->aux; 567 aux->vers = vers; 568 lib->aux = aux; 569 haveaux: 570 return aux; 571 } 572 573 void 574 elfdynhash(void) 575 { 576 LSym *s, *sy, *dynstr; 577 int i, j, nbucket, b, nfile; 578 uint32 hc, *chain, *buckets; 579 int nsym; 580 char *name; 581 Elfaux **need; 582 Elflib *needlib; 583 Elflib *l; 584 Elfaux *x; 585 586 if(!iself) 587 return; 588 589 nsym = nelfsym; 590 s = linklookup(ctxt, ".hash", 0); 591 s->type = SELFROSECT; 592 s->reachable = 1; 593 594 i = nsym; 595 nbucket = 1; 596 while(i > 0) { 597 ++nbucket; 598 i >>= 1; 599 } 600 601 needlib = nil; 602 need = malloc(nsym * sizeof need[0]); 603 chain = malloc(nsym * sizeof chain[0]); 604 buckets = malloc(nbucket * sizeof buckets[0]); 605 if(need == nil || chain == nil || buckets == nil) { 606 ctxt->cursym = nil; 607 diag("out of memory"); 608 errorexit(); 609 } 610 memset(need, 0, nsym * sizeof need[0]); 611 memset(chain, 0, nsym * sizeof chain[0]); 612 memset(buckets, 0, nbucket * sizeof buckets[0]); 613 for(sy=ctxt->allsym; sy!=S; sy=sy->allsym) { 614 if (sy->dynid <= 0) 615 continue; 616 617 if(sy->dynimpvers) 618 need[sy->dynid] = addelflib(&needlib, sy->dynimplib, sy->dynimpvers); 619 620 name = sy->extname; 621 hc = elfhash((uchar*)name); 622 623 b = hc % nbucket; 624 chain[sy->dynid] = buckets[b]; 625 buckets[b] = sy->dynid; 626 } 627 628 adduint32(ctxt, s, nbucket); 629 adduint32(ctxt, s, nsym); 630 for(i = 0; i<nbucket; i++) 631 adduint32(ctxt, s, buckets[i]); 632 for(i = 0; i<nsym; i++) 633 adduint32(ctxt, s, chain[i]); 634 635 free(chain); 636 free(buckets); 637 638 // version symbols 639 dynstr = linklookup(ctxt, ".dynstr", 0); 640 s = linklookup(ctxt, ".gnu.version_r", 0); 641 i = 2; 642 nfile = 0; 643 for(l=needlib; l; l=l->next) { 644 nfile++; 645 // header 646 adduint16(ctxt, s, 1); // table version 647 j = 0; 648 for(x=l->aux; x; x=x->next) 649 j++; 650 adduint16(ctxt, s, j); // aux count 651 adduint32(ctxt, s, addstring(dynstr, l->file)); // file string offset 652 adduint32(ctxt, s, 16); // offset from header to first aux 653 if(l->next) 654 adduint32(ctxt, s, 16+j*16); // offset from this header to next 655 else 656 adduint32(ctxt, s, 0); 657 658 for(x=l->aux; x; x=x->next) { 659 x->num = i++; 660 // aux struct 661 adduint32(ctxt, s, elfhash((uchar*)x->vers)); // hash 662 adduint16(ctxt, s, 0); // flags 663 adduint16(ctxt, s, x->num); // other - index we refer to this by 664 adduint32(ctxt, s, addstring(dynstr, x->vers)); // version string offset 665 if(x->next) 666 adduint32(ctxt, s, 16); // offset from this aux to next 667 else 668 adduint32(ctxt, s, 0); 669 } 670 } 671 672 // version references 673 s = linklookup(ctxt, ".gnu.version", 0); 674 for(i=0; i<nsym; i++) { 675 if(i == 0) 676 adduint16(ctxt, s, 0); // first entry - no symbol 677 else if(need[i] == nil) 678 adduint16(ctxt, s, 1); // global 679 else 680 adduint16(ctxt, s, need[i]->num); 681 } 682 683 free(need); 684 685 s = linklookup(ctxt, ".dynamic", 0); 686 elfverneed = nfile; 687 if(elfverneed) { 688 elfwritedynentsym(s, DT_VERNEED, linklookup(ctxt, ".gnu.version_r", 0)); 689 elfwritedynent(s, DT_VERNEEDNUM, nfile); 690 elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0)); 691 } 692 693 if(thechar == '6' || thechar == '9') { 694 sy = linklookup(ctxt, ".rela.plt", 0); 695 if(sy->size > 0) { 696 elfwritedynent(s, DT_PLTREL, DT_RELA); 697 elfwritedynentsymsize(s, DT_PLTRELSZ, sy); 698 elfwritedynentsym(s, DT_JMPREL, sy); 699 } 700 } else { 701 sy = linklookup(ctxt, ".rel.plt", 0); 702 if(sy->size > 0) { 703 elfwritedynent(s, DT_PLTREL, DT_REL); 704 elfwritedynentsymsize(s, DT_PLTRELSZ, sy); 705 elfwritedynentsym(s, DT_JMPREL, sy); 706 } 707 } 708 709 elfwritedynent(s, DT_NULL, 0); 710 } 711 712 ElfPhdr* 713 elfphload(Segment *seg) 714 { 715 ElfPhdr *ph; 716 717 ph = newElfPhdr(); 718 ph->type = PT_LOAD; 719 if(seg->rwx & 4) 720 ph->flags |= PF_R; 721 if(seg->rwx & 2) 722 ph->flags |= PF_W; 723 if(seg->rwx & 1) 724 ph->flags |= PF_X; 725 ph->vaddr = seg->vaddr; 726 ph->paddr = seg->vaddr; 727 ph->memsz = seg->len; 728 ph->off = seg->fileoff; 729 ph->filesz = seg->filelen; 730 ph->align = INITRND; 731 732 return ph; 733 } 734 735 ElfShdr* 736 elfshname(char *name) 737 { 738 int i, off; 739 ElfShdr *sh; 740 741 for(i=0; i<nelfstr; i++) { 742 if(strcmp(name, elfstr[i].s) == 0) { 743 off = elfstr[i].off; 744 goto found; 745 } 746 } 747 diag("cannot find elf name %s", name); 748 errorexit(); 749 return nil; 750 751 found: 752 for(i=0; i<hdr.shnum; i++) { 753 sh = shdr[i]; 754 if(sh->name == off) 755 return sh; 756 } 757 758 sh = newElfShdr(off); 759 return sh; 760 } 761 762 ElfShdr* 763 elfshalloc(Section *sect) 764 { 765 ElfShdr *sh; 766 767 sh = elfshname(sect->name); 768 sect->elfsect = sh; 769 return sh; 770 } 771 772 ElfShdr* 773 elfshbits(Section *sect) 774 { 775 ElfShdr *sh; 776 777 sh = elfshalloc(sect); 778 if(sh->type > 0) 779 return sh; 780 781 if(sect->vaddr < sect->seg->vaddr + sect->seg->filelen) 782 sh->type = SHT_PROGBITS; 783 else 784 sh->type = SHT_NOBITS; 785 sh->flags = SHF_ALLOC; 786 if(sect->rwx & 1) 787 sh->flags |= SHF_EXECINSTR; 788 if(sect->rwx & 2) 789 sh->flags |= SHF_WRITE; 790 if(strcmp(sect->name, ".tbss") == 0) { 791 if(strcmp(goos, "android") != 0) 792 sh->flags |= SHF_TLS; // no TLS on android 793 sh->type = SHT_NOBITS; 794 } 795 if(linkmode != LinkExternal) 796 sh->addr = sect->vaddr; 797 sh->addralign = sect->align; 798 sh->size = sect->len; 799 sh->off = sect->seg->fileoff + sect->vaddr - sect->seg->vaddr; 800 801 return sh; 802 } 803 804 ElfShdr* 805 elfshreloc(Section *sect) 806 { 807 int typ; 808 ElfShdr *sh; 809 char *prefix; 810 char buf[100]; 811 812 // If main section is SHT_NOBITS, nothing to relocate. 813 // Also nothing to relocate in .shstrtab. 814 if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen) 815 return nil; 816 if(strcmp(sect->name, ".shstrtab") == 0 || strcmp(sect->name, ".tbss") == 0) 817 return nil; 818 819 if(thechar == '6' || thechar == '9') { 820 prefix = ".rela"; 821 typ = SHT_RELA; 822 } else { 823 prefix = ".rel"; 824 typ = SHT_REL; 825 } 826 827 snprint(buf, sizeof buf, "%s%s", prefix, sect->name); 828 sh = elfshname(buf); 829 sh->type = typ; 830 sh->entsize = RegSize*(2+(typ==SHT_RELA)); 831 sh->link = elfshname(".symtab")->shnum; 832 sh->info = sect->elfsect->shnum; 833 sh->off = sect->reloff; 834 sh->size = sect->rellen; 835 sh->addralign = RegSize; 836 return sh; 837 } 838 839 void 840 elfrelocsect(Section *sect, LSym *first) 841 { 842 LSym *sym; 843 int32 eaddr; 844 Reloc *r; 845 846 // If main section is SHT_NOBITS, nothing to relocate. 847 // Also nothing to relocate in .shstrtab. 848 if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen) 849 return; 850 if(strcmp(sect->name, ".shstrtab") == 0) 851 return; 852 853 sect->reloff = cpos(); 854 for(sym = first; sym != nil; sym = sym->next) { 855 if(!sym->reachable) 856 continue; 857 if(sym->value >= sect->vaddr) 858 break; 859 } 860 861 eaddr = sect->vaddr + sect->len; 862 for(; sym != nil; sym = sym->next) { 863 if(!sym->reachable) 864 continue; 865 if(sym->value >= eaddr) 866 break; 867 ctxt->cursym = sym; 868 869 for(r = sym->r; r < sym->r+sym->nr; r++) { 870 if(r->done) 871 continue; 872 if(r->xsym == nil) { 873 diag("missing xsym in relocation"); 874 continue; 875 } 876 if(r->xsym->elfsym == 0) 877 diag("reloc %d to non-elf symbol %s (outer=%s) %d", r->type, r->sym->name, r->xsym->name, r->sym->type); 878 if(elfreloc1(r, sym->value+r->off - sect->vaddr) < 0) 879 diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name); 880 } 881 } 882 883 sect->rellen = cpos() - sect->reloff; 884 } 885 886 void 887 elfemitreloc(void) 888 { 889 Section *sect; 890 891 while(cpos()&7) 892 cput(0); 893 894 elfrelocsect(segtext.sect, ctxt->textp); 895 for(sect=segtext.sect->next; sect!=nil; sect=sect->next) 896 elfrelocsect(sect, datap); 897 for(sect=segrodata.sect; sect!=nil; sect=sect->next) 898 elfrelocsect(sect, datap); 899 for(sect=segdata.sect; sect!=nil; sect=sect->next) 900 elfrelocsect(sect, datap); 901 } 902 903 void 904 doelf(void) 905 { 906 LSym *s, *shstrtab, *dynstr; 907 908 if(!iself) 909 return; 910 911 /* predefine strings we need for section headers */ 912 shstrtab = linklookup(ctxt, ".shstrtab", 0); 913 shstrtab->type = SELFROSECT; 914 shstrtab->reachable = 1; 915 916 addstring(shstrtab, ""); 917 addstring(shstrtab, ".text"); 918 addstring(shstrtab, ".noptrdata"); 919 addstring(shstrtab, ".data"); 920 addstring(shstrtab, ".bss"); 921 addstring(shstrtab, ".noptrbss"); 922 // generate .tbss section (except for OpenBSD where it's not supported) 923 // for dynamic internal linker or external linking, so that various 924 // binutils could correctly calculate PT_TLS size. 925 // see http://golang.org/issue/5200. 926 if(HEADTYPE != Hopenbsd) 927 if(!debug['d'] || linkmode == LinkExternal) 928 addstring(shstrtab, ".tbss"); 929 if(HEADTYPE == Hnetbsd) 930 addstring(shstrtab, ".note.netbsd.ident"); 931 if(HEADTYPE == Hopenbsd) 932 addstring(shstrtab, ".note.openbsd.ident"); 933 if(buildinfolen > 0) 934 addstring(shstrtab, ".note.gnu.build-id"); 935 addstring(shstrtab, ".elfdata"); 936 addstring(shstrtab, ".rodata"); 937 addstring(shstrtab, ".typelink"); 938 addstring(shstrtab, ".gosymtab"); 939 addstring(shstrtab, ".gopclntab"); 940 941 if(linkmode == LinkExternal) { 942 debug_s = debug['s']; 943 debug['s'] = 0; 944 debug['d'] = 1; 945 946 if(thechar == '6' || thechar == '9') { 947 addstring(shstrtab, ".rela.text"); 948 addstring(shstrtab, ".rela.rodata"); 949 addstring(shstrtab, ".rela.typelink"); 950 addstring(shstrtab, ".rela.gosymtab"); 951 addstring(shstrtab, ".rela.gopclntab"); 952 addstring(shstrtab, ".rela.noptrdata"); 953 addstring(shstrtab, ".rela.data"); 954 } else { 955 addstring(shstrtab, ".rel.text"); 956 addstring(shstrtab, ".rel.rodata"); 957 addstring(shstrtab, ".rel.typelink"); 958 addstring(shstrtab, ".rel.gosymtab"); 959 addstring(shstrtab, ".rel.gopclntab"); 960 addstring(shstrtab, ".rel.noptrdata"); 961 addstring(shstrtab, ".rel.data"); 962 } 963 // add a .note.GNU-stack section to mark the stack as non-executable 964 addstring(shstrtab, ".note.GNU-stack"); 965 } 966 967 if(flag_shared) { 968 addstring(shstrtab, ".init_array"); 969 if(thechar == '6' || thechar == '9') 970 addstring(shstrtab, ".rela.init_array"); 971 else 972 addstring(shstrtab, ".rel.init_array"); 973 } 974 975 if(!debug['s']) { 976 addstring(shstrtab, ".symtab"); 977 addstring(shstrtab, ".strtab"); 978 dwarfaddshstrings(shstrtab); 979 } 980 addstring(shstrtab, ".shstrtab"); 981 982 if(!debug['d']) { /* -d suppresses dynamic loader format */ 983 addstring(shstrtab, ".interp"); 984 addstring(shstrtab, ".hash"); 985 addstring(shstrtab, ".got"); 986 if(thechar == '9') 987 addstring(shstrtab, ".glink"); 988 addstring(shstrtab, ".got.plt"); 989 addstring(shstrtab, ".dynamic"); 990 addstring(shstrtab, ".dynsym"); 991 addstring(shstrtab, ".dynstr"); 992 if(thechar == '6' || thechar == '9') { 993 addstring(shstrtab, ".rela"); 994 addstring(shstrtab, ".rela.plt"); 995 } else { 996 addstring(shstrtab, ".rel"); 997 addstring(shstrtab, ".rel.plt"); 998 } 999 addstring(shstrtab, ".plt"); 1000 addstring(shstrtab, ".gnu.version"); 1001 addstring(shstrtab, ".gnu.version_r"); 1002 1003 /* dynamic symbol table - first entry all zeros */ 1004 s = linklookup(ctxt, ".dynsym", 0); 1005 s->type = SELFROSECT; 1006 s->reachable = 1; 1007 if(thechar == '6' || thechar == '9') 1008 s->size += ELF64SYMSIZE; 1009 else 1010 s->size += ELF32SYMSIZE; 1011 1012 /* dynamic string table */ 1013 s = linklookup(ctxt, ".dynstr", 0); 1014 s->type = SELFROSECT; 1015 s->reachable = 1; 1016 if(s->size == 0) 1017 addstring(s, ""); 1018 dynstr = s; 1019 1020 /* relocation table */ 1021 if(thechar == '6' || thechar == '9') 1022 s = linklookup(ctxt, ".rela", 0); 1023 else 1024 s = linklookup(ctxt, ".rel", 0); 1025 s->reachable = 1; 1026 s->type = SELFROSECT; 1027 1028 /* global offset table */ 1029 s = linklookup(ctxt, ".got", 0); 1030 s->reachable = 1; 1031 s->type = SELFGOT; // writable 1032 1033 /* ppc64 glink resolver */ 1034 if(thechar == '9') { 1035 s = linklookup(ctxt, ".glink", 0); 1036 s->reachable = 1; 1037 s->type = SELFRXSECT; 1038 } 1039 1040 /* hash */ 1041 s = linklookup(ctxt, ".hash", 0); 1042 s->reachable = 1; 1043 s->type = SELFROSECT; 1044 1045 s = linklookup(ctxt, ".got.plt", 0); 1046 s->reachable = 1; 1047 s->type = SELFSECT; // writable 1048 1049 s = linklookup(ctxt, ".plt", 0); 1050 s->reachable = 1; 1051 if(thechar == '9') 1052 // In the ppc64 ABI, .plt is a data section 1053 // written by the dynamic linker. 1054 s->type = SELFSECT; 1055 else 1056 s->type = SELFRXSECT; 1057 1058 elfsetupplt(); 1059 1060 if(thechar == '6' || thechar == '9') 1061 s = linklookup(ctxt, ".rela.plt", 0); 1062 else 1063 s = linklookup(ctxt, ".rel.plt", 0); 1064 s->reachable = 1; 1065 s->type = SELFROSECT; 1066 1067 s = linklookup(ctxt, ".gnu.version", 0); 1068 s->reachable = 1; 1069 s->type = SELFROSECT; 1070 1071 s = linklookup(ctxt, ".gnu.version_r", 0); 1072 s->reachable = 1; 1073 s->type = SELFROSECT; 1074 1075 /* define dynamic elf table */ 1076 s = linklookup(ctxt, ".dynamic", 0); 1077 s->reachable = 1; 1078 s->type = SELFSECT; // writable 1079 1080 /* 1081 * .dynamic table 1082 */ 1083 elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0)); 1084 elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0)); 1085 if(thechar == '6' || thechar == '9') 1086 elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE); 1087 else 1088 elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); 1089 elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0)); 1090 elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0)); 1091 if(thechar == '6' || thechar == '9') { 1092 elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0)); 1093 elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0)); 1094 elfwritedynent(s, DT_RELAENT, ELF64RELASIZE); 1095 } else { 1096 elfwritedynentsym(s, DT_REL, linklookup(ctxt, ".rel", 0)); 1097 elfwritedynentsymsize(s, DT_RELSZ, linklookup(ctxt, ".rel", 0)); 1098 elfwritedynent(s, DT_RELENT, ELF32RELSIZE); 1099 } 1100 if(rpath) 1101 elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath)); 1102 1103 if(thechar == '9') 1104 elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".plt", 0)); 1105 else 1106 elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".got.plt", 0)); 1107 1108 if(thechar == '9') 1109 elfwritedynent(s, DT_PPC64_OPT, 0); 1110 1111 // Solaris dynamic linker can't handle an empty .rela.plt if 1112 // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL, 1113 // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the 1114 // size of .rel(a).plt section. 1115 elfwritedynent(s, DT_DEBUG, 0); 1116 1117 // Do not write DT_NULL. elfdynhash will finish it. 1118 } 1119 } 1120 1121 void 1122 shsym(ElfShdr *sh, LSym *s) 1123 { 1124 vlong addr; 1125 addr = symaddr(s); 1126 if(sh->flags&SHF_ALLOC) 1127 sh->addr = addr; 1128 sh->off = datoff(addr); 1129 sh->size = s->size; 1130 } 1131 1132 void 1133 phsh(ElfPhdr *ph, ElfShdr *sh) 1134 { 1135 ph->vaddr = sh->addr; 1136 ph->paddr = ph->vaddr; 1137 ph->off = sh->off; 1138 ph->filesz = sh->size; 1139 ph->memsz = sh->size; 1140 ph->align = sh->addralign; 1141 } 1142 1143 void 1144 asmbelfsetup(void) 1145 { 1146 Section *sect; 1147 1148 /* This null SHdr must appear before all others */ 1149 elfshname(""); 1150 1151 for(sect=segtext.sect; sect!=nil; sect=sect->next) 1152 elfshalloc(sect); 1153 for(sect=segrodata.sect; sect!=nil; sect=sect->next) 1154 elfshalloc(sect); 1155 for(sect=segdata.sect; sect!=nil; sect=sect->next) 1156 elfshalloc(sect); 1157 } 1158 1159 void 1160 asmbelf(vlong symo) 1161 { 1162 vlong a, o; 1163 vlong startva, resoff; 1164 ElfEhdr *eh; 1165 ElfPhdr *ph, *pph, *pnote; 1166 ElfShdr *sh; 1167 Section *sect; 1168 1169 eh = getElfEhdr(); 1170 switch(thechar) { 1171 default: 1172 diag("unknown architecture in asmbelf"); 1173 errorexit(); 1174 case '5': 1175 eh->machine = EM_ARM; 1176 break; 1177 case '6': 1178 eh->machine = EM_X86_64; 1179 break; 1180 case '8': 1181 eh->machine = EM_386; 1182 break; 1183 case '9': 1184 eh->machine = EM_PPC64; 1185 break; 1186 } 1187 1188 startva = INITTEXT - HEADR; 1189 resoff = ELFRESERVE; 1190 1191 pph = nil; 1192 if(linkmode == LinkExternal) { 1193 /* skip program headers */ 1194 eh->phoff = 0; 1195 eh->phentsize = 0; 1196 goto elfobj; 1197 } 1198 1199 /* program header info */ 1200 pph = newElfPhdr(); 1201 pph->type = PT_PHDR; 1202 pph->flags = PF_R; 1203 pph->off = eh->ehsize; 1204 pph->vaddr = INITTEXT - HEADR + pph->off; 1205 pph->paddr = INITTEXT - HEADR + pph->off; 1206 pph->align = INITRND; 1207 1208 /* 1209 * PHDR must be in a loaded segment. Adjust the text 1210 * segment boundaries downwards to include it. 1211 * Except on NaCl where it must not be loaded. 1212 */ 1213 if(HEADTYPE != Hnacl) { 1214 o = segtext.vaddr - pph->vaddr; 1215 segtext.vaddr -= o; 1216 segtext.len += o; 1217 o = segtext.fileoff - pph->off; 1218 segtext.fileoff -= o; 1219 segtext.filelen += o; 1220 } 1221 1222 if(!debug['d']) { 1223 /* interpreter */ 1224 sh = elfshname(".interp"); 1225 sh->type = SHT_PROGBITS; 1226 sh->flags = SHF_ALLOC; 1227 sh->addralign = 1; 1228 if(interpreter == nil) { 1229 switch(HEADTYPE) { 1230 case Hlinux: 1231 interpreter = linuxdynld; 1232 break; 1233 case Hfreebsd: 1234 interpreter = freebsddynld; 1235 break; 1236 case Hnetbsd: 1237 interpreter = netbsddynld; 1238 break; 1239 case Hopenbsd: 1240 interpreter = openbsddynld; 1241 break; 1242 case Hdragonfly: 1243 interpreter = dragonflydynld; 1244 break; 1245 case Hsolaris: 1246 interpreter = solarisdynld; 1247 break; 1248 } 1249 } 1250 resoff -= elfinterp(sh, startva, resoff, interpreter); 1251 1252 ph = newElfPhdr(); 1253 ph->type = PT_INTERP; 1254 ph->flags = PF_R; 1255 phsh(ph, sh); 1256 } 1257 1258 pnote = nil; 1259 if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) { 1260 sh = nil; 1261 switch(HEADTYPE) { 1262 case Hnetbsd: 1263 sh = elfshname(".note.netbsd.ident"); 1264 resoff -= elfnetbsdsig(sh, startva, resoff); 1265 break; 1266 case Hopenbsd: 1267 sh = elfshname(".note.openbsd.ident"); 1268 resoff -= elfopenbsdsig(sh, startva, resoff); 1269 break; 1270 } 1271 1272 pnote = newElfPhdr(); 1273 pnote->type = PT_NOTE; 1274 pnote->flags = PF_R; 1275 phsh(pnote, sh); 1276 } 1277 1278 if(buildinfolen > 0) { 1279 sh = elfshname(".note.gnu.build-id"); 1280 resoff -= elfbuildinfo(sh, startva, resoff); 1281 1282 if(pnote == nil) { 1283 pnote = newElfPhdr(); 1284 pnote->type = PT_NOTE; 1285 pnote->flags = PF_R; 1286 } 1287 phsh(pnote, sh); 1288 } 1289 1290 // Additions to the reserved area must be above this line. 1291 USED(resoff); 1292 1293 elfphload(&segtext); 1294 if(segrodata.sect != nil) 1295 elfphload(&segrodata); 1296 elfphload(&segdata); 1297 1298 /* Dynamic linking sections */ 1299 if(!debug['d']) { /* -d suppresses dynamic loader format */ 1300 sh = elfshname(".dynsym"); 1301 sh->type = SHT_DYNSYM; 1302 sh->flags = SHF_ALLOC; 1303 if(elf64) 1304 sh->entsize = ELF64SYMSIZE; 1305 else 1306 sh->entsize = ELF32SYMSIZE; 1307 sh->addralign = RegSize; 1308 sh->link = elfshname(".dynstr")->shnum; 1309 // sh->info = index of first non-local symbol (number of local symbols) 1310 shsym(sh, linklookup(ctxt, ".dynsym", 0)); 1311 1312 sh = elfshname(".dynstr"); 1313 sh->type = SHT_STRTAB; 1314 sh->flags = SHF_ALLOC; 1315 sh->addralign = 1; 1316 shsym(sh, linklookup(ctxt, ".dynstr", 0)); 1317 1318 if(elfverneed) { 1319 sh = elfshname(".gnu.version"); 1320 sh->type = SHT_GNU_VERSYM; 1321 sh->flags = SHF_ALLOC; 1322 sh->addralign = 2; 1323 sh->link = elfshname(".dynsym")->shnum; 1324 sh->entsize = 2; 1325 shsym(sh, linklookup(ctxt, ".gnu.version", 0)); 1326 1327 sh = elfshname(".gnu.version_r"); 1328 sh->type = SHT_GNU_VERNEED; 1329 sh->flags = SHF_ALLOC; 1330 sh->addralign = RegSize; 1331 sh->info = elfverneed; 1332 sh->link = elfshname(".dynstr")->shnum; 1333 shsym(sh, linklookup(ctxt, ".gnu.version_r", 0)); 1334 } 1335 1336 switch(eh->machine) { 1337 case EM_X86_64: 1338 case EM_PPC64: 1339 sh = elfshname(".rela.plt"); 1340 sh->type = SHT_RELA; 1341 sh->flags = SHF_ALLOC; 1342 sh->entsize = ELF64RELASIZE; 1343 sh->addralign = RegSize; 1344 sh->link = elfshname(".dynsym")->shnum; 1345 sh->info = elfshname(".plt")->shnum; 1346 shsym(sh, linklookup(ctxt, ".rela.plt", 0)); 1347 1348 sh = elfshname(".rela"); 1349 sh->type = SHT_RELA; 1350 sh->flags = SHF_ALLOC; 1351 sh->entsize = ELF64RELASIZE; 1352 sh->addralign = 8; 1353 sh->link = elfshname(".dynsym")->shnum; 1354 shsym(sh, linklookup(ctxt, ".rela", 0)); 1355 break; 1356 1357 default: 1358 sh = elfshname(".rel.plt"); 1359 sh->type = SHT_REL; 1360 sh->flags = SHF_ALLOC; 1361 sh->entsize = ELF32RELSIZE; 1362 sh->link = elfshname(".dynsym")->shnum; 1363 shsym(sh, linklookup(ctxt, ".rel.plt", 0)); 1364 1365 sh = elfshname(".rel"); 1366 sh->type = SHT_REL; 1367 sh->flags = SHF_ALLOC; 1368 sh->entsize = ELF32RELSIZE; 1369 sh->addralign = 4; 1370 sh->link = elfshname(".dynsym")->shnum; 1371 shsym(sh, linklookup(ctxt, ".rel", 0)); 1372 break; 1373 } 1374 1375 if(eh->machine == EM_PPC64) { 1376 sh = elfshname(".glink"); 1377 sh->type = SHT_PROGBITS; 1378 sh->flags = SHF_ALLOC+SHF_EXECINSTR; 1379 sh->addralign = 4; 1380 shsym(sh, linklookup(ctxt, ".glink", 0)); 1381 } 1382 1383 sh = elfshname(".plt"); 1384 sh->type = SHT_PROGBITS; 1385 sh->flags = SHF_ALLOC+SHF_EXECINSTR; 1386 if(eh->machine == EM_X86_64) 1387 sh->entsize = 16; 1388 else if(eh->machine == EM_PPC64) { 1389 // On ppc64, this is just a table of addresses 1390 // filled by the dynamic linker 1391 sh->type = SHT_NOBITS; 1392 sh->flags = SHF_ALLOC+SHF_WRITE; 1393 sh->entsize = 8; 1394 } else 1395 sh->entsize = 4; 1396 sh->addralign = sh->entsize; 1397 shsym(sh, linklookup(ctxt, ".plt", 0)); 1398 1399 // On ppc64, .got comes from the input files, so don't 1400 // create it here, and .got.plt is not used. 1401 if(eh->machine != EM_PPC64) { 1402 sh = elfshname(".got"); 1403 sh->type = SHT_PROGBITS; 1404 sh->flags = SHF_ALLOC+SHF_WRITE; 1405 sh->entsize = RegSize; 1406 sh->addralign = RegSize; 1407 shsym(sh, linklookup(ctxt, ".got", 0)); 1408 1409 sh = elfshname(".got.plt"); 1410 sh->type = SHT_PROGBITS; 1411 sh->flags = SHF_ALLOC+SHF_WRITE; 1412 sh->entsize = RegSize; 1413 sh->addralign = RegSize; 1414 shsym(sh, linklookup(ctxt, ".got.plt", 0)); 1415 } 1416 1417 sh = elfshname(".hash"); 1418 sh->type = SHT_HASH; 1419 sh->flags = SHF_ALLOC; 1420 sh->entsize = 4; 1421 sh->addralign = RegSize; 1422 sh->link = elfshname(".dynsym")->shnum; 1423 shsym(sh, linklookup(ctxt, ".hash", 0)); 1424 1425 /* sh and PT_DYNAMIC for .dynamic section */ 1426 sh = elfshname(".dynamic"); 1427 sh->type = SHT_DYNAMIC; 1428 sh->flags = SHF_ALLOC+SHF_WRITE; 1429 sh->entsize = 2*RegSize; 1430 sh->addralign = RegSize; 1431 sh->link = elfshname(".dynstr")->shnum; 1432 shsym(sh, linklookup(ctxt, ".dynamic", 0)); 1433 ph = newElfPhdr(); 1434 ph->type = PT_DYNAMIC; 1435 ph->flags = PF_R + PF_W; 1436 phsh(ph, sh); 1437 1438 /* 1439 * Thread-local storage segment (really just size). 1440 */ 1441 // Do not emit PT_TLS for OpenBSD since ld.so(1) does 1442 // not currently support it. This is handled 1443 // appropriately in runtime/cgo. 1444 if(ctxt->tlsoffset != 0 && HEADTYPE != Hopenbsd) { 1445 ph = newElfPhdr(); 1446 ph->type = PT_TLS; 1447 ph->flags = PF_R; 1448 ph->memsz = -ctxt->tlsoffset; 1449 ph->align = RegSize; 1450 } 1451 } 1452 1453 if(HEADTYPE == Hlinux) { 1454 ph = newElfPhdr(); 1455 ph->type = PT_GNU_STACK; 1456 ph->flags = PF_W+PF_R; 1457 ph->align = RegSize; 1458 1459 ph = newElfPhdr(); 1460 ph->type = PT_PAX_FLAGS; 1461 ph->flags = 0x2a00; // mprotect, randexec, emutramp disabled 1462 ph->align = RegSize; 1463 } 1464 1465 elfobj: 1466 sh = elfshname(".shstrtab"); 1467 sh->type = SHT_STRTAB; 1468 sh->addralign = 1; 1469 shsym(sh, linklookup(ctxt, ".shstrtab", 0)); 1470 eh->shstrndx = sh->shnum; 1471 1472 // put these sections early in the list 1473 if(!debug['s']) { 1474 elfshname(".symtab"); 1475 elfshname(".strtab"); 1476 } 1477 1478 for(sect=segtext.sect; sect!=nil; sect=sect->next) 1479 elfshbits(sect); 1480 for(sect=segrodata.sect; sect!=nil; sect=sect->next) 1481 elfshbits(sect); 1482 for(sect=segdata.sect; sect!=nil; sect=sect->next) 1483 elfshbits(sect); 1484 1485 if(linkmode == LinkExternal) { 1486 for(sect=segtext.sect; sect!=nil; sect=sect->next) 1487 elfshreloc(sect); 1488 for(sect=segrodata.sect; sect!=nil; sect=sect->next) 1489 elfshreloc(sect); 1490 for(sect=segdata.sect; sect!=nil; sect=sect->next) 1491 elfshreloc(sect); 1492 // add a .note.GNU-stack section to mark the stack as non-executable 1493 sh = elfshname(".note.GNU-stack"); 1494 sh->type = SHT_PROGBITS; 1495 sh->addralign = 1; 1496 sh->flags = 0; 1497 } 1498 1499 // generate .tbss section for dynamic internal linking (except for OpenBSD) 1500 // external linking generates .tbss in data.c 1501 if(linkmode == LinkInternal && !debug['d'] && HEADTYPE != Hopenbsd) { 1502 sh = elfshname(".tbss"); 1503 sh->type = SHT_NOBITS; 1504 sh->addralign = RegSize; 1505 sh->size = -ctxt->tlsoffset; 1506 sh->flags = SHF_ALLOC | SHF_TLS | SHF_WRITE; 1507 } 1508 1509 if(!debug['s']) { 1510 sh = elfshname(".symtab"); 1511 sh->type = SHT_SYMTAB; 1512 sh->off = symo; 1513 sh->size = symsize; 1514 sh->addralign = RegSize; 1515 sh->entsize = 8+2*RegSize; 1516 sh->link = elfshname(".strtab")->shnum; 1517 sh->info = elfglobalsymndx; 1518 1519 sh = elfshname(".strtab"); 1520 sh->type = SHT_STRTAB; 1521 sh->off = symo+symsize; 1522 sh->size = elfstrsize; 1523 sh->addralign = 1; 1524 1525 dwarfaddelfheaders(); 1526 } 1527 1528 /* Main header */ 1529 eh->ident[EI_MAG0] = '\177'; 1530 eh->ident[EI_MAG1] = 'E'; 1531 eh->ident[EI_MAG2] = 'L'; 1532 eh->ident[EI_MAG3] = 'F'; 1533 if(HEADTYPE == Hfreebsd) 1534 eh->ident[EI_OSABI] = ELFOSABI_FREEBSD; 1535 else if(HEADTYPE == Hnetbsd) 1536 eh->ident[EI_OSABI] = ELFOSABI_NETBSD; 1537 else if(HEADTYPE == Hopenbsd) 1538 eh->ident[EI_OSABI] = ELFOSABI_OPENBSD; 1539 else if(HEADTYPE == Hdragonfly) 1540 eh->ident[EI_OSABI] = ELFOSABI_NONE; 1541 if(elf64) 1542 eh->ident[EI_CLASS] = ELFCLASS64; 1543 else 1544 eh->ident[EI_CLASS] = ELFCLASS32; 1545 if(ctxt->arch->endian == BigEndian) 1546 eh->ident[EI_DATA] = ELFDATA2MSB; 1547 else 1548 eh->ident[EI_DATA] = ELFDATA2LSB; 1549 eh->ident[EI_VERSION] = EV_CURRENT; 1550 1551 if(linkmode == LinkExternal) 1552 eh->type = ET_REL; 1553 else 1554 eh->type = ET_EXEC; 1555 1556 if(linkmode != LinkExternal) 1557 eh->entry = entryvalue(); 1558 1559 eh->version = EV_CURRENT; 1560 1561 if(pph != nil) { 1562 pph->filesz = eh->phnum * eh->phentsize; 1563 pph->memsz = pph->filesz; 1564 } 1565 1566 cseek(0); 1567 a = 0; 1568 a += elfwritehdr(); 1569 a += elfwritephdrs(); 1570 a += elfwriteshdrs(); 1571 if(!debug['d']) 1572 a += elfwriteinterp(); 1573 if(linkmode != LinkExternal) { 1574 if(HEADTYPE == Hnetbsd) 1575 a += elfwritenetbsdsig(); 1576 if(HEADTYPE == Hopenbsd) 1577 a += elfwriteopenbsdsig(); 1578 if(buildinfolen > 0) 1579 a += elfwritebuildinfo(); 1580 } 1581 if(a > ELFRESERVE) 1582 diag("ELFRESERVE too small: %lld > %d", a, ELFRESERVE); 1583 }