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