github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/src/cmd/ld/ldelf.c (about)

     1  /*
     2  Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
     3  http://code.swtch.com/plan9port/src/tip/src/libmach/
     4  
     5  	Copyright © 2004 Russ Cox.
     6  	Portions Copyright © 2008-2010 Google Inc.
     7  	Portions Copyright © 2010 The Go Authors.
     8  
     9  Permission is hereby granted, free of charge, to any person obtaining a copy
    10  of this software and associated documentation files (the "Software"), to deal
    11  in the Software without restriction, including without limitation the rights
    12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    13  copies of the Software, and to permit persons to whom the Software is
    14  furnished to do so, subject to the following conditions:
    15  
    16  The above copyright notice and this permission notice shall be included in
    17  all copies or substantial portions of the Software.
    18  
    19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    25  THE SOFTWARE.
    26  */
    27  
    28  #include	"l.h"
    29  #include	"lib.h"
    30  #include	"../ld/elf.h"
    31  
    32  enum
    33  {
    34  	ElfClassNone = 0,
    35  	ElfClass32,
    36  	ElfClass64,
    37  
    38  	ElfDataNone = 0,
    39  	ElfDataLsb,
    40  	ElfDataMsb,
    41  
    42  	ElfTypeNone = 0,
    43  	ElfTypeRelocatable,
    44  	ElfTypeExecutable,
    45  	ElfTypeSharedObject,
    46  	ElfTypeCore,
    47  	/* 0xFF00 - 0xFFFF reserved for processor-specific types */
    48  
    49  	ElfMachNone = 0,
    50  	ElfMach32100,		/* AT&T WE 32100 */
    51  	ElfMachSparc,		/* SPARC */
    52  	ElfMach386,		/* Intel 80386 */
    53  	ElfMach68000,		/* Motorola 68000 */
    54  	ElfMach88000,		/* Motorola 88000 */
    55  	ElfMach486,		/* Intel 80486, no longer used */
    56  	ElfMach860,		/* Intel 80860 */
    57  	ElfMachMips,		/* MIPS RS3000 */
    58  	ElfMachS370,		/* IBM System/370 */
    59  	ElfMachMipsLe,	/* MIPS RS3000 LE */
    60  	ElfMachParisc = 15,		/* HP PA RISC */
    61  	ElfMachVpp500 = 17,	/* Fujitsu VPP500 */
    62  	ElfMachSparc32Plus,	/* SPARC V8+ */
    63  	ElfMach960,		/* Intel 80960 */
    64  	ElfMachPower,		/* PowerPC */
    65  	ElfMachPower64,	/* PowerPC 64-bit */
    66  	ElfMachS390,		/* IBM System/390 */
    67  	ElfMachV800 = 36,	/* NEC V800 */
    68  	ElfMachFr20,		/* Fujitsu FR20 */
    69  	ElfMachRh32,		/* TRW RH-32 */
    70  	ElfMachRce,		/* Motorola RCE */
    71  	ElfMachArm,		/* ARM */
    72  	ElfMachAlpha,		/* Digital Alpha */
    73  	ElfMachSH,		/* Hitachi SH */
    74  	ElfMachSparc9,		/* SPARC V9 */
    75  	ElfMachAmd64 = 62,
    76  	/* and the list goes on... */
    77  
    78  	ElfAbiNone = 0,
    79  	ElfAbiSystemV = 0,	/* [sic] */
    80  	ElfAbiHPUX,
    81  	ElfAbiNetBSD,
    82  	ElfAbiLinux,
    83  	ElfAbiSolaris = 6,
    84  	ElfAbiAix,
    85  	ElfAbiIrix,
    86  	ElfAbiFreeBSD,
    87  	ElfAbiTru64,
    88  	ElfAbiModesto,
    89  	ElfAbiOpenBSD,
    90  	ElfAbiARM = 97,
    91  	ElfAbiEmbedded = 255,
    92  
    93  	/* some of sections 0xFF00 - 0xFFFF reserved for various things */
    94  	ElfSectNone = 0,
    95  	ElfSectProgbits,
    96  	ElfSectSymtab,
    97  	ElfSectStrtab,
    98  	ElfSectRela,
    99  	ElfSectHash,
   100  	ElfSectDynamic,
   101  	ElfSectNote,
   102  	ElfSectNobits,
   103  	ElfSectRel,
   104  	ElfSectShlib,
   105  	ElfSectDynsym,
   106  
   107  	ElfSectFlagWrite = 0x1,
   108  	ElfSectFlagAlloc = 0x2,
   109  	ElfSectFlagExec = 0x4,
   110  	/* 0xF0000000 are reserved for processor specific */
   111  
   112  	ElfSymBindLocal = 0,
   113  	ElfSymBindGlobal,
   114  	ElfSymBindWeak,
   115  	/* 13-15 reserved */
   116  
   117  	ElfSymTypeNone = 0,
   118  	ElfSymTypeObject,
   119  	ElfSymTypeFunc,
   120  	ElfSymTypeSection,
   121  	ElfSymTypeFile,
   122  	/* 13-15 reserved */
   123  
   124  	ElfSymShnNone = 0,
   125  	ElfSymShnAbs = 0xFFF1,
   126  	ElfSymShnCommon = 0xFFF2,
   127  	/* 0xFF00-0xFF1F reserved for processors */
   128  	/* 0xFF20-0xFF3F reserved for operating systems */
   129  
   130  	ElfProgNone = 0,
   131  	ElfProgLoad,
   132  	ElfProgDynamic,
   133  	ElfProgInterp,
   134  	ElfProgNote,
   135  	ElfProgShlib,
   136  	ElfProgPhdr,
   137  
   138  	ElfProgFlagExec = 0x1,
   139  	ElfProgFlagWrite = 0x2,
   140  	ElfProgFlagRead = 0x4,
   141  
   142  	ElfNotePrStatus = 1,
   143  	ElfNotePrFpreg = 2,
   144  	ElfNotePrPsinfo = 3,
   145  	ElfNotePrTaskstruct = 4,
   146  	ElfNotePrAuxv = 6,
   147  	ElfNotePrXfpreg = 0x46e62b7f	/* for gdb/386 */
   148  };
   149  
   150  typedef struct ElfHdrBytes ElfHdrBytes;
   151  typedef struct ElfSectBytes ElfSectBytes;
   152  typedef struct ElfProgBytes ElfProgBytes;
   153  typedef struct ElfSymBytes ElfSymBytes;
   154  
   155  typedef struct ElfHdrBytes64 ElfHdrBytes64;
   156  typedef struct ElfSectBytes64 ElfSectBytes64;
   157  typedef struct ElfProgBytes64 ElfProgBytes64;
   158  typedef struct ElfSymBytes64 ElfSymBytes64;
   159  
   160  struct ElfHdrBytes
   161  {
   162  	uchar	ident[16];
   163  	uchar	type[2];
   164  	uchar	machine[2];
   165  	uchar	version[4];
   166  	uchar	entry[4];
   167  	uchar	phoff[4];
   168  	uchar	shoff[4];
   169  	uchar	flags[4];
   170  	uchar	ehsize[2];
   171  	uchar	phentsize[2];
   172  	uchar	phnum[2];
   173  	uchar	shentsize[2];
   174  	uchar	shnum[2];
   175  	uchar	shstrndx[2];
   176  };
   177  
   178  struct ElfHdrBytes64
   179  {
   180  	uchar	ident[16];
   181  	uchar	type[2];
   182  	uchar	machine[2];
   183  	uchar	version[4];
   184  	uchar	entry[8];
   185  	uchar	phoff[8];
   186  	uchar	shoff[8];
   187  	uchar	flags[4];
   188  	uchar	ehsize[2];
   189  	uchar	phentsize[2];
   190  	uchar	phnum[2];
   191  	uchar	shentsize[2];
   192  	uchar	shnum[2];
   193  	uchar	shstrndx[2];
   194  };
   195  
   196  struct ElfSectBytes
   197  {
   198  	uchar	name[4];
   199  	uchar	type[4];
   200  	uchar	flags[4];
   201  	uchar	addr[4];
   202  	uchar	off[4];
   203  	uchar	size[4];
   204  	uchar	link[4];
   205  	uchar	info[4];
   206  	uchar	align[4];
   207  	uchar	entsize[4];
   208  };
   209  
   210  struct ElfSectBytes64
   211  {
   212  	uchar	name[4];
   213  	uchar	type[4];
   214  	uchar	flags[8];
   215  	uchar	addr[8];
   216  	uchar	off[8];
   217  	uchar	size[8];
   218  	uchar	link[4];
   219  	uchar	info[4];
   220  	uchar	align[8];
   221  	uchar	entsize[8];
   222  };
   223  
   224  struct ElfSymBytes
   225  {
   226  	uchar	name[4];
   227  	uchar	value[4];
   228  	uchar	size[4];
   229  	uchar	info;	/* top4: bind, bottom4: type */
   230  	uchar	other;
   231  	uchar	shndx[2];
   232  };
   233  
   234  struct ElfSymBytes64
   235  {
   236  	uchar	name[4];
   237  	uchar	info;	/* top4: bind, bottom4: type */
   238  	uchar	other;
   239  	uchar	shndx[2];
   240  	uchar	value[8];
   241  	uchar	size[8];
   242  };
   243  
   244  typedef struct ElfSect ElfSect;
   245  typedef struct ElfObj ElfObj;
   246  typedef struct ElfSym ElfSym;
   247  
   248  struct ElfSect
   249  {
   250  	char		*name;
   251  	uint32	type;
   252  	uint64	flags;
   253  	uint64	addr;
   254  	uint64	off;
   255  	uint64	size;
   256  	uint32	link;
   257  	uint32	info;
   258  	uint64	align;
   259  	uint64	entsize;
   260  	uchar	*base;
   261  	LSym	*sym;
   262  };
   263  
   264  struct ElfObj
   265  {
   266  	Biobuf	*f;
   267  	int64	base;	// offset in f where ELF begins
   268  	int64	len;		// length of ELF
   269  	int	is64;
   270  	char	*name;
   271  
   272  	Endian	*e;
   273  	ElfSect	*sect;
   274  	uint		nsect;
   275  	char		*shstrtab;
   276  	int		nsymtab;
   277  	ElfSect	*symtab;
   278  	ElfSect	*symstr;
   279  
   280  	uint32	type;
   281  	uint32	machine;
   282  	uint32	version;
   283  	uint64	entry;
   284  	uint64	phoff;
   285  	uint64	shoff;
   286  	uint32	flags;
   287  	uint32	ehsize;
   288  	uint32	phentsize;
   289  	uint32	phnum;
   290  	uint32	shentsize;
   291  	uint32	shnum;
   292  	uint32	shstrndx;
   293  };
   294  
   295  struct ElfSym
   296  {
   297  	char*	name;
   298  	uint64	value;
   299  	uint64	size;
   300  	uchar	bind;
   301  	uchar	type;
   302  	uchar	other;
   303  	uint16	shndx;
   304  	LSym*	sym;
   305  };
   306  
   307  uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };
   308  
   309  static ElfSect*	section(ElfObj*, char*);
   310  static int	map(ElfObj*, ElfSect*);
   311  static int	readsym(ElfObj*, int i, ElfSym*, int);
   312  static int	reltype(char*, int, uchar*);
   313  
   314  int
   315  valuecmp(LSym *a, LSym *b)
   316  {
   317  	if(a->value < b->value)
   318  		return -1;
   319  	if(a->value > b->value)
   320  		return +1;
   321  	return 0;
   322  }
   323  
   324  void
   325  ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
   326  {
   327  	int32 base;
   328  	uint64 add, info;
   329  	char *name;
   330  	int i, j, rela, is64, n;
   331  	uchar hdrbuf[64];
   332  	uchar *p;
   333  	ElfHdrBytes *hdr;
   334  	ElfObj *obj;
   335  	ElfSect *sect, *rsect;
   336  	ElfSym sym;
   337  	Endian *e;
   338  	Reloc *r, *rp;
   339  	LSym *s;
   340  	LSym **symbols;
   341  
   342  	symbols = nil;
   343  
   344  	if(debug['v'])
   345  		Bprint(&bso, "%5.2f ldelf %s\n", cputime(), pn);
   346  
   347  	ctxt->version++;
   348  	base = Boffset(f);
   349  
   350  	if(Bread(f, hdrbuf, sizeof hdrbuf) != sizeof hdrbuf)
   351  		goto bad;
   352  	hdr = (ElfHdrBytes*)hdrbuf;
   353  	if(memcmp(hdr->ident, ElfMagic, 4) != 0)
   354  		goto bad;
   355  	switch(hdr->ident[5]) {
   356  	case ElfDataLsb:
   357  		e = &le;
   358  		break;
   359  	case ElfDataMsb:
   360  		e = &be;
   361  		break;
   362  	default:
   363  		goto bad;
   364  	}
   365  
   366  	// read header
   367  	obj = mal(sizeof *obj);
   368  	obj->e = e;
   369  	obj->f = f;
   370  	obj->base = base;
   371  	obj->len = len;
   372  	obj->name = pn;
   373  	
   374  	is64 = 0;
   375  	if(hdr->ident[4] == ElfClass64) {
   376  		ElfHdrBytes64* hdr;
   377  
   378  		is64 = 1;
   379  		hdr = (ElfHdrBytes64*)hdrbuf;
   380  		obj->type = e->e16(hdr->type);
   381  		obj->machine = e->e16(hdr->machine);
   382  		obj->version = e->e32(hdr->version);
   383  		obj->phoff = e->e64(hdr->phoff);
   384  		obj->shoff = e->e64(hdr->shoff);
   385  		obj->flags = e->e32(hdr->flags);
   386  		obj->ehsize = e->e16(hdr->ehsize);
   387  		obj->phentsize = e->e16(hdr->phentsize);
   388  		obj->phnum = e->e16(hdr->phnum);
   389  		obj->shentsize = e->e16(hdr->shentsize);
   390  		obj->shnum = e->e16(hdr->shnum);
   391  		obj->shstrndx = e->e16(hdr->shstrndx);
   392  	} else {
   393  		obj->type = e->e16(hdr->type);
   394  		obj->machine = e->e16(hdr->machine);
   395  		obj->version = e->e32(hdr->version);
   396  		obj->entry = e->e32(hdr->entry);
   397  		obj->phoff = e->e32(hdr->phoff);
   398  		obj->shoff = e->e32(hdr->shoff);
   399  		obj->flags = e->e32(hdr->flags);
   400  		obj->ehsize = e->e16(hdr->ehsize);
   401  		obj->phentsize = e->e16(hdr->phentsize);
   402  		obj->phnum = e->e16(hdr->phnum);
   403  		obj->shentsize = e->e16(hdr->shentsize);
   404  		obj->shnum = e->e16(hdr->shnum);
   405  		obj->shstrndx = e->e16(hdr->shstrndx);
   406  	}
   407  	obj->is64 = is64;
   408  	
   409  	if(hdr->ident[6] != obj->version)
   410  		goto bad;
   411  
   412  	if(e->e16(hdr->type) != ElfTypeRelocatable) {
   413  		diag("%s: elf but not elf relocatable object", pn);
   414  		return;
   415  	}
   416  
   417  	switch(thechar) {
   418  	default:
   419  		diag("%s: elf %s unimplemented", pn, thestring);
   420  		return;
   421  	case '5':
   422  		if(e != &le || obj->machine != ElfMachArm || hdr->ident[4] != ElfClass32) {
   423  			diag("%s: elf object but not arm", pn);
   424  			return;
   425  		}
   426  		break;
   427  	case '6':
   428  		if(e != &le || obj->machine != ElfMachAmd64 || hdr->ident[4] != ElfClass64) {
   429  			diag("%s: elf object but not amd64", pn);
   430  			return;
   431  		}
   432  		break;
   433  	case '8':
   434  		if(e != &le || obj->machine != ElfMach386 || hdr->ident[4] != ElfClass32) {
   435  			diag("%s: elf object but not 386", pn);
   436  			return;
   437  		}
   438  		break;
   439  	case '9':
   440  		if(obj->machine != ElfMachPower64 || hdr->ident[4] != ElfClass64) {
   441  			diag("%s: elf object but not ppc64", pn);
   442  			return;
   443  		}
   444  		break;
   445  	}
   446  
   447  	// load section list into memory.
   448  	obj->sect = mal(obj->shnum*sizeof obj->sect[0]);
   449  	obj->nsect = obj->shnum;
   450  	for(i=0; i<obj->nsect; i++) {
   451  		if(Bseek(f, base+obj->shoff+i*obj->shentsize, 0) < 0)
   452  			goto bad;
   453  		sect = &obj->sect[i];
   454  		if(is64) {
   455  			ElfSectBytes64 b;
   456  
   457  			werrstr("short read");
   458  			if(Bread(f, &b, sizeof b) != sizeof b)
   459  				goto bad;
   460  
   461  			sect->name = (char*)(uintptr)e->e32(b.name);
   462  			sect->type = e->e32(b.type);
   463  			sect->flags = e->e64(b.flags);
   464  			sect->addr = e->e64(b.addr);
   465  			sect->off = e->e64(b.off);
   466  			sect->size = e->e64(b.size);
   467  			sect->link = e->e32(b.link);
   468  			sect->info = e->e32(b.info);
   469  			sect->align = e->e64(b.align);
   470  			sect->entsize = e->e64(b.entsize);
   471  		} else {
   472  			ElfSectBytes b;
   473  
   474  			werrstr("short read");
   475  			if(Bread(f, &b, sizeof b) != sizeof b)
   476  				goto bad;
   477  		
   478  			sect->name = (char*)(uintptr)e->e32(b.name);
   479  			sect->type = e->e32(b.type);
   480  			sect->flags = e->e32(b.flags);
   481  			sect->addr = e->e32(b.addr);
   482  			sect->off = e->e32(b.off);
   483  			sect->size = e->e32(b.size);
   484  			sect->link = e->e32(b.link);
   485  			sect->info = e->e32(b.info);
   486  			sect->align = e->e32(b.align);
   487  			sect->entsize = e->e32(b.entsize);
   488  		}
   489  	}
   490  
   491  	// read section string table and translate names
   492  	if(obj->shstrndx >= obj->nsect) {
   493  		werrstr("shstrndx out of range %d >= %d", obj->shstrndx, obj->nsect);
   494  		goto bad;
   495  	}
   496  	sect = &obj->sect[obj->shstrndx];
   497  	if(map(obj, sect) < 0)
   498  		goto bad;
   499  	for(i=0; i<obj->nsect; i++)
   500  		if(obj->sect[i].name != nil)
   501  			obj->sect[i].name = (char*)sect->base + (uintptr)obj->sect[i].name;
   502  	
   503  	// load string table for symbols into memory.
   504  	obj->symtab = section(obj, ".symtab");
   505  	if(obj->symtab == nil) {
   506  		// our work is done here - no symbols means nothing can refer to this file
   507  		return;
   508  	}
   509  	if(obj->symtab->link <= 0 || obj->symtab->link >= obj->nsect) {
   510  		diag("%s: elf object has symbol table with invalid string table link", pn);
   511  		return;
   512  	}
   513  	obj->symstr = &obj->sect[obj->symtab->link];
   514  	if(is64)
   515  		obj->nsymtab = obj->symtab->size / sizeof(ElfSymBytes64);
   516  	else
   517  		obj->nsymtab = obj->symtab->size / sizeof(ElfSymBytes);
   518  	
   519  	if(map(obj, obj->symtab) < 0)
   520  		goto bad;
   521  	if(map(obj, obj->symstr) < 0)
   522  		goto bad;
   523  
   524  	// load text and data segments into memory.
   525  	// they are not as small as the section lists, but we'll need
   526  	// the memory anyway for the symbol images, so we might
   527  	// as well use one large chunk.
   528  	
   529  	// create symbols for mapped sections
   530  	for(i=0; i<obj->nsect; i++) {
   531  		sect = &obj->sect[i];
   532  		if((sect->type != ElfSectProgbits && sect->type != ElfSectNobits) || !(sect->flags&ElfSectFlagAlloc))
   533  			continue;
   534  		if(sect->type != ElfSectNobits && map(obj, sect) < 0)
   535  			goto bad;
   536  		
   537  		name = smprint("%s(%s)", pkg, sect->name);
   538  		s = linklookup(ctxt, name, ctxt->version);
   539  		free(name);
   540  		switch((int)sect->flags&(ElfSectFlagAlloc|ElfSectFlagWrite|ElfSectFlagExec)) {
   541  		default:
   542  			werrstr("unexpected flags for ELF section %s", sect->name);
   543  			goto bad;
   544  		case ElfSectFlagAlloc:
   545  			s->type = SRODATA;
   546  			break;
   547  		case ElfSectFlagAlloc + ElfSectFlagWrite:
   548  			if(sect->type == ElfSectNobits)
   549  				s->type = SNOPTRBSS;
   550  			else
   551  				s->type = SNOPTRDATA;
   552  			break;
   553  		case ElfSectFlagAlloc + ElfSectFlagExec:
   554  			s->type = STEXT;
   555  			break;
   556  		}
   557  		if(sect->type == ElfSectProgbits) {
   558  			s->p = sect->base;
   559  			s->np = sect->size;
   560  		}
   561  		s->size = sect->size;
   562  		s->align = sect->align;
   563  		sect->sym = s;
   564  	}
   565  
   566  	// enter sub-symbols into symbol table.
   567  	// symbol 0 is the null symbol.
   568  	symbols = malloc(obj->nsymtab * sizeof(symbols[0]));
   569  	if(symbols == nil) {
   570  		diag("out of memory");
   571  		errorexit();
   572  	}
   573  	for(i=1; i<obj->nsymtab; i++) {
   574  		if(readsym(obj, i, &sym, 1) < 0)
   575  			goto bad;
   576  		symbols[i] = sym.sym;
   577  		if(sym.type != ElfSymTypeFunc && sym.type != ElfSymTypeObject && sym.type != ElfSymTypeNone)
   578  			continue;
   579  		if(sym.shndx == ElfSymShnCommon) {
   580  			s = sym.sym;
   581  			if(s->size < sym.size)
   582  				s->size = sym.size;
   583  			if(s->type == 0 || s->type == SXREF)
   584  				s->type = SNOPTRBSS;
   585  			continue;
   586  		}
   587  		if(sym.shndx >= obj->nsect || sym.shndx == 0)
   588  			continue;
   589  		// even when we pass needSym == 1 to readsym, it might still return nil to skip some unwanted symbols
   590  		if(sym.sym == S)
   591  			continue;
   592  		sect = obj->sect+sym.shndx;
   593  		if(sect->sym == nil) {
   594  			if(strncmp(sym.name, ".Linfo_string", 13) == 0) // clang does this
   595  				continue;
   596  			diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type);
   597  			continue;
   598  		}
   599  		s = sym.sym;
   600  		if(s->outer != S) {
   601  			if(s->dupok)
   602  				continue;
   603  			diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
   604  			errorexit();
   605  		}
   606  		s->sub = sect->sym->sub;
   607  		sect->sym->sub = s;
   608  		s->type = sect->sym->type | (s->type&~SMASK) | SSUB;
   609  		if(!(s->cgoexport & CgoExportDynamic))
   610  			s->dynimplib = nil;  // satisfy dynimport
   611  		s->value = sym.value;
   612  		s->size = sym.size;
   613  		s->outer = sect->sym;
   614  		if(sect->sym->type == STEXT) {
   615  			if(s->external && !s->dupok)
   616  					diag("%s: duplicate definition of %s", pn, s->name);
   617  			s->external = 1;
   618  		}
   619  	}
   620  	
   621  	// Sort outer lists by address, adding to textp.
   622  	// This keeps textp in increasing address order.
   623  	for(i=0; i<obj->nsect; i++) {
   624  		s = obj->sect[i].sym;
   625  		if(s == S)
   626  			continue;
   627  		if(s->sub)
   628  			s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
   629  		if(s->type == STEXT) {
   630  			if(s->onlist)
   631  				sysfatal("symbol %s listed multiple times", s->name);
   632  			s->onlist = 1;
   633  			if(ctxt->etextp)
   634  				ctxt->etextp->next = s;
   635  			else
   636  				ctxt->textp = s;
   637  			ctxt->etextp = s;
   638  			for(s = s->sub; s != S; s = s->sub) {
   639  				if(s->onlist)
   640  					sysfatal("symbol %s listed multiple times", s->name);
   641  				s->onlist = 1;
   642  				ctxt->etextp->next = s;
   643  				ctxt->etextp = s;
   644  			}
   645  		}
   646  	}
   647  
   648  	// load relocations
   649  	for(i=0; i<obj->nsect; i++) {
   650  		rsect = &obj->sect[i];
   651  		if(rsect->type != ElfSectRela && rsect->type != ElfSectRel)
   652  			continue;
   653  		if(rsect->info >= obj->nsect || obj->sect[rsect->info].base == nil)
   654  			continue;
   655  		sect = &obj->sect[rsect->info];
   656  		if(map(obj, rsect) < 0)
   657  			goto bad;
   658  		rela = rsect->type == ElfSectRela;
   659  		n = rsect->size/(4+4*is64)/(2+rela);
   660  		r = mal(n*sizeof r[0]);
   661  		p = rsect->base;
   662  		for(j=0; j<n; j++) {
   663  			add = 0;
   664  			rp = &r[j];
   665  			if(is64) {
   666  				// 64-bit rel/rela
   667  				rp->off = e->e64(p);
   668  				p += 8;
   669  				info = e->e64(p);
   670  				p += 8;
   671  				if(rela) {
   672  					add = e->e64(p);
   673  					p += 8;
   674  				}
   675  			} else {
   676  				// 32-bit rel/rela
   677  				rp->off = e->e32(p);
   678  				p += 4;
   679  				info = e->e32(p);
   680  				info = info>>8<<32 | (info&0xff);	// convert to 64-bit info
   681  				p += 4;
   682  				if(rela) {
   683  					add = e->e32(p);
   684  					p += 4;
   685  				}
   686  			}
   687  			if((info & 0xffffffff) == 0) { // skip R_*_NONE relocation
   688  				j--;
   689  				n--;
   690  				continue;
   691  			}
   692  			if((info >> 32) == 0) { // absolute relocation, don't bother reading the null symbol
   693  				rp->sym = S;
   694  			} else {
   695  				if(readsym(obj, info>>32, &sym, 0) < 0)
   696  					goto bad;
   697  				sym.sym = symbols[info>>32];
   698  				if(sym.sym == nil) {
   699  					werrstr("%s#%d: reloc of invalid sym #%d %s shndx=%d type=%d",
   700  						sect->sym->name, j, (int)(info>>32), sym.name, sym.shndx, sym.type);
   701  					goto bad;
   702  				}
   703  				rp->sym = sym.sym;
   704  			}
   705  			rp->type = reltype(pn, (uint32)info, &rp->siz);
   706  			if(rela)
   707  				rp->add = add;
   708  			else {
   709  				// load addend from image
   710  				if(rp->siz == 4)
   711  					rp->add = e->e32(sect->base+rp->off);
   712  				else if(rp->siz == 8)
   713  					rp->add = e->e64(sect->base+rp->off);
   714  				else
   715  					diag("invalid rela size %d", rp->siz);
   716  			}
   717  			if(rp->siz == 4)
   718  				rp->add = (int32)rp->add;
   719  			//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
   720  		}
   721  		qsort(r, n, sizeof r[0], rbyoff);	// just in case
   722  		
   723  		s = sect->sym;
   724  		s->r = r;
   725  		s->nr = n;
   726  	}
   727  	free(symbols);
   728  
   729  	return;
   730  
   731  bad:
   732  	diag("%s: malformed elf file: %r", pn);
   733  	free(symbols);
   734  }
   735  
   736  static ElfSect*
   737  section(ElfObj *obj, char *name)
   738  {
   739  	int i;
   740  	
   741  	for(i=0; i<obj->nsect; i++)
   742  		if(obj->sect[i].name && name && strcmp(obj->sect[i].name, name) == 0)
   743  			return &obj->sect[i];
   744  	return nil;
   745  }
   746  
   747  static int
   748  map(ElfObj *obj, ElfSect *sect)
   749  {
   750  	if(sect->base != nil)
   751  		return 0;
   752  
   753  	if(sect->off+sect->size > obj->len) {
   754  		werrstr("elf section past end of file");
   755  		return -1;
   756  	}
   757  
   758  	sect->base = mal(sect->size);
   759  	werrstr("short read");
   760  	if(Bseek(obj->f, obj->base+sect->off, 0) < 0 || Bread(obj->f, sect->base, sect->size) != sect->size)
   761  		return -1;
   762  	
   763  	return 0;
   764  }
   765  
   766  static int
   767  readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
   768  {
   769  	LSym *s;
   770  
   771  	if(i >= obj->nsymtab || i < 0) {
   772  		werrstr("invalid elf symbol index");
   773  		return -1;
   774  	}
   775  	if(i == 0) {
   776  		diag("readym: read null symbol!");
   777  	}
   778  
   779  	if(obj->is64) {
   780  		ElfSymBytes64 *b;
   781  		
   782  		b = (ElfSymBytes64*)(obj->symtab->base + i*sizeof *b);
   783  		sym->name = (char*)obj->symstr->base + obj->e->e32(b->name);
   784  		sym->value = obj->e->e64(b->value);
   785  		sym->size = obj->e->e64(b->size);
   786  		sym->shndx = obj->e->e16(b->shndx);
   787  		sym->bind = b->info>>4;
   788  		sym->type = b->info&0xf;
   789  		sym->other = b->other;
   790  	} else {
   791  		ElfSymBytes *b;
   792  		
   793  		b = (ElfSymBytes*)(obj->symtab->base + i*sizeof *b);
   794  		sym->name = (char*)obj->symstr->base + obj->e->e32(b->name);
   795  		sym->value = obj->e->e32(b->value);
   796  		sym->size = obj->e->e32(b->size);
   797  		sym->shndx = obj->e->e16(b->shndx);
   798  		sym->bind = b->info>>4;
   799  		sym->type = b->info&0xf;
   800  		sym->other = b->other;
   801  	}
   802  
   803  	s = nil;
   804  	if(strcmp(sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
   805  		sym->name = ".got";
   806  	switch(sym->type) {
   807  	case ElfSymTypeSection:
   808  		s = obj->sect[sym->shndx].sym;
   809  		break;
   810  	case ElfSymTypeObject:
   811  	case ElfSymTypeFunc:
   812  	case ElfSymTypeNone:
   813  		switch(sym->bind) {
   814  		case ElfSymBindGlobal:
   815  			if(needSym) {
   816  				s = linklookup(ctxt, sym->name, 0);
   817  				// for global scoped hidden symbols we should insert it into
   818  				// symbol hash table, but mark them as hidden.
   819  				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
   820  				// workaround that we set dupok.
   821  				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
   822  				// set dupok generally. See http://codereview.appspot.com/5823055/
   823  				// comment #5 for details.
   824  				if(s && sym->other == 2) {
   825  					s->type |= SHIDDEN;
   826  					s->dupok = 1;
   827  				}
   828  			}
   829  			break;
   830  		case ElfSymBindLocal:
   831  			if(thechar == '5' && (strncmp(sym->name, "$a", 2) == 0 || strncmp(sym->name, "$d", 2) == 0)) {
   832  				// binutils for arm generate these mapping
   833  				// symbols, ignore these
   834  				break;
   835  			}
   836  			if(needSym) {
   837  				// local names and hidden visiblity global names are unique
   838  				// and should only reference by its index, not name, so we
   839  				// don't bother to add them into hash table
   840  				s = linknewsym(ctxt, sym->name, ctxt->version);
   841  				s->type |= SHIDDEN;
   842  			}
   843  			break;
   844  		case ElfSymBindWeak:
   845  			if(needSym) {
   846  				s = linknewsym(ctxt, sym->name, 0);
   847  				if(sym->other == 2)
   848  					s->type |= SHIDDEN;
   849  			}
   850  			break;
   851  		default:
   852  			werrstr("%s: invalid symbol binding %d", sym->name, sym->bind);
   853  			return -1;
   854  		}
   855  		break;
   856  	}
   857  	if(s != nil && s->type == 0 && sym->type != ElfSymTypeSection)
   858  		s->type = SXREF;
   859  	sym->sym = s;
   860  
   861  	return 0;
   862  }
   863  
   864  int
   865  rbyoff(const void *va, const void *vb)
   866  {
   867  	Reloc *a, *b;
   868  	
   869  	a = (Reloc*)va;
   870  	b = (Reloc*)vb;
   871  	if(a->off < b->off)
   872  		return -1;
   873  	if(a->off > b->off)
   874  		return +1;
   875  	return 0;
   876  }
   877  
   878  #define R(x, y) ((x)|((y)<<24))
   879  
   880  static int
   881  reltype(char *pn, int elftype, uchar *siz)
   882  {
   883  	switch(R(thechar, elftype)) {
   884  	default:
   885  		diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype);
   886  	case R('5', R_ARM_ABS32):
   887  	case R('5', R_ARM_GOT32):
   888  	case R('5', R_ARM_PLT32):
   889  	case R('5', R_ARM_GOTOFF):
   890  	case R('5', R_ARM_GOTPC):
   891  	case R('5', R_ARM_THM_PC22):
   892  	case R('5', R_ARM_REL32):
   893  	case R('5', R_ARM_CALL):
   894  	case R('5', R_ARM_V4BX):
   895  	case R('5', R_ARM_GOT_PREL):
   896  	case R('5', R_ARM_PC24):
   897  	case R('5', R_ARM_JUMP24):
   898  	case R('6', R_X86_64_PC32):
   899  	case R('6', R_X86_64_PLT32):
   900  	case R('6', R_X86_64_GOTPCREL):
   901  	case R('8', R_386_32):
   902  	case R('8', R_386_PC32):
   903  	case R('8', R_386_GOT32):
   904  	case R('8', R_386_PLT32):
   905  	case R('8', R_386_GOTOFF):
   906  	case R('8', R_386_GOTPC):
   907  		*siz = 4;
   908  		break;
   909  	case R('6', R_X86_64_64):
   910  		*siz = 8;
   911  		break;
   912  	}
   913  
   914  	return 256+elftype;
   915  }