github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/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 */
    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  	}
   440  
   441  	// load section list into memory.
   442  	obj->sect = mal(obj->shnum*sizeof obj->sect[0]);
   443  	obj->nsect = obj->shnum;
   444  	for(i=0; i<obj->nsect; i++) {
   445  		if(Bseek(f, base+obj->shoff+i*obj->shentsize, 0) < 0)
   446  			goto bad;
   447  		sect = &obj->sect[i];
   448  		if(is64) {
   449  			ElfSectBytes64 b;
   450  
   451  			werrstr("short read");
   452  			if(Bread(f, &b, sizeof b) != sizeof b)
   453  				goto bad;
   454  
   455  			sect->name = (char*)(uintptr)e->e32(b.name);
   456  			sect->type = e->e32(b.type);
   457  			sect->flags = e->e64(b.flags);
   458  			sect->addr = e->e64(b.addr);
   459  			sect->off = e->e64(b.off);
   460  			sect->size = e->e64(b.size);
   461  			sect->link = e->e32(b.link);
   462  			sect->info = e->e32(b.info);
   463  			sect->align = e->e64(b.align);
   464  			sect->entsize = e->e64(b.entsize);
   465  		} else {
   466  			ElfSectBytes b;
   467  
   468  			werrstr("short read");
   469  			if(Bread(f, &b, sizeof b) != sizeof b)
   470  				goto bad;
   471  		
   472  			sect->name = (char*)(uintptr)e->e32(b.name);
   473  			sect->type = e->e32(b.type);
   474  			sect->flags = e->e32(b.flags);
   475  			sect->addr = e->e32(b.addr);
   476  			sect->off = e->e32(b.off);
   477  			sect->size = e->e32(b.size);
   478  			sect->link = e->e32(b.link);
   479  			sect->info = e->e32(b.info);
   480  			sect->align = e->e32(b.align);
   481  			sect->entsize = e->e32(b.entsize);
   482  		}
   483  	}
   484  
   485  	// read section string table and translate names
   486  	if(obj->shstrndx >= obj->nsect) {
   487  		werrstr("shstrndx out of range %d >= %d", obj->shstrndx, obj->nsect);
   488  		goto bad;
   489  	}
   490  	sect = &obj->sect[obj->shstrndx];
   491  	if(map(obj, sect) < 0)
   492  		goto bad;
   493  	for(i=0; i<obj->nsect; i++)
   494  		if(obj->sect[i].name != nil)
   495  			obj->sect[i].name = (char*)sect->base + (uintptr)obj->sect[i].name;
   496  	
   497  	// load string table for symbols into memory.
   498  	obj->symtab = section(obj, ".symtab");
   499  	if(obj->symtab == nil) {
   500  		// our work is done here - no symbols means nothing can refer to this file
   501  		return;
   502  	}
   503  	if(obj->symtab->link <= 0 || obj->symtab->link >= obj->nsect) {
   504  		diag("%s: elf object has symbol table with invalid string table link", pn);
   505  		return;
   506  	}
   507  	obj->symstr = &obj->sect[obj->symtab->link];
   508  	if(is64)
   509  		obj->nsymtab = obj->symtab->size / sizeof(ElfSymBytes64);
   510  	else
   511  		obj->nsymtab = obj->symtab->size / sizeof(ElfSymBytes);
   512  	
   513  	if(map(obj, obj->symtab) < 0)
   514  		goto bad;
   515  	if(map(obj, obj->symstr) < 0)
   516  		goto bad;
   517  
   518  	// load text and data segments into memory.
   519  	// they are not as small as the section lists, but we'll need
   520  	// the memory anyway for the symbol images, so we might
   521  	// as well use one large chunk.
   522  	
   523  	// create symbols for mapped sections
   524  	for(i=0; i<obj->nsect; i++) {
   525  		sect = &obj->sect[i];
   526  		if((sect->type != ElfSectProgbits && sect->type != ElfSectNobits) || !(sect->flags&ElfSectFlagAlloc))
   527  			continue;
   528  		if(sect->type != ElfSectNobits && map(obj, sect) < 0)
   529  			goto bad;
   530  		
   531  		name = smprint("%s(%s)", pkg, sect->name);
   532  		s = linklookup(ctxt, name, ctxt->version);
   533  		free(name);
   534  		switch((int)sect->flags&(ElfSectFlagAlloc|ElfSectFlagWrite|ElfSectFlagExec)) {
   535  		default:
   536  			werrstr("unexpected flags for ELF section %s", sect->name);
   537  			goto bad;
   538  		case ElfSectFlagAlloc:
   539  			s->type = SRODATA;
   540  			break;
   541  		case ElfSectFlagAlloc + ElfSectFlagWrite:
   542  			if(sect->type == ElfSectNobits)
   543  				s->type = SNOPTRBSS;
   544  			else
   545  				s->type = SNOPTRDATA;
   546  			break;
   547  		case ElfSectFlagAlloc + ElfSectFlagExec:
   548  			s->type = STEXT;
   549  			break;
   550  		}
   551  		if(sect->type == ElfSectProgbits) {
   552  			s->p = sect->base;
   553  			s->np = sect->size;
   554  		}
   555  		s->size = sect->size;
   556  		s->align = sect->align;
   557  		sect->sym = s;
   558  	}
   559  
   560  	// enter sub-symbols into symbol table.
   561  	// symbol 0 is the null symbol.
   562  	symbols = malloc(obj->nsymtab * sizeof(symbols[0]));
   563  	if(symbols == nil) {
   564  		diag("out of memory");
   565  		errorexit();
   566  	}
   567  	for(i=1; i<obj->nsymtab; i++) {
   568  		if(readsym(obj, i, &sym, 1) < 0)
   569  			goto bad;
   570  		symbols[i] = sym.sym;
   571  		if(sym.type != ElfSymTypeFunc && sym.type != ElfSymTypeObject && sym.type != ElfSymTypeNone)
   572  			continue;
   573  		if(sym.shndx == ElfSymShnCommon) {
   574  			s = sym.sym;
   575  			if(s->size < sym.size)
   576  				s->size = sym.size;
   577  			if(s->type == 0 || s->type == SXREF)
   578  				s->type = SNOPTRBSS;
   579  			continue;
   580  		}
   581  		if(sym.shndx >= obj->nsect || sym.shndx == 0)
   582  			continue;
   583  		// even when we pass needSym == 1 to readsym, it might still return nil to skip some unwanted symbols
   584  		if(sym.sym == S)
   585  			continue;
   586  		sect = obj->sect+sym.shndx;
   587  		if(sect->sym == nil) {
   588  			if(strncmp(sym.name, ".Linfo_string", 13) == 0) // clang does this
   589  				continue;
   590  			diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type);
   591  			continue;
   592  		}
   593  		s = sym.sym;
   594  		if(s->outer != S) {
   595  			if(s->dupok)
   596  				continue;
   597  			diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
   598  			errorexit();
   599  		}
   600  		s->sub = sect->sym->sub;
   601  		sect->sym->sub = s;
   602  		s->type = sect->sym->type | (s->type&~SMASK) | SSUB;
   603  		if(!(s->cgoexport & CgoExportDynamic))
   604  			s->dynimplib = nil;  // satisfy dynimport
   605  		s->value = sym.value;
   606  		s->size = sym.size;
   607  		s->outer = sect->sym;
   608  		if(sect->sym->type == STEXT) {
   609  			if(s->external && !s->dupok)
   610  					diag("%s: duplicate definition of %s", pn, s->name);
   611  			s->external = 1;
   612  		}
   613  	}
   614  	
   615  	// Sort outer lists by address, adding to textp.
   616  	// This keeps textp in increasing address order.
   617  	for(i=0; i<obj->nsect; i++) {
   618  		s = obj->sect[i].sym;
   619  		if(s == S)
   620  			continue;
   621  		if(s->sub)
   622  			s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
   623  		if(s->type == STEXT) {
   624  			if(s->onlist)
   625  				sysfatal("symbol %s listed multiple times", s->name);
   626  			s->onlist = 1;
   627  			if(ctxt->etextp)
   628  				ctxt->etextp->next = s;
   629  			else
   630  				ctxt->textp = s;
   631  			ctxt->etextp = s;
   632  			for(s = s->sub; s != S; s = s->sub) {
   633  				if(s->onlist)
   634  					sysfatal("symbol %s listed multiple times", s->name);
   635  				s->onlist = 1;
   636  				ctxt->etextp->next = s;
   637  				ctxt->etextp = s;
   638  			}
   639  		}
   640  	}
   641  
   642  	// load relocations
   643  	for(i=0; i<obj->nsect; i++) {
   644  		rsect = &obj->sect[i];
   645  		if(rsect->type != ElfSectRela && rsect->type != ElfSectRel)
   646  			continue;
   647  		if(rsect->info >= obj->nsect || obj->sect[rsect->info].base == nil)
   648  			continue;
   649  		sect = &obj->sect[rsect->info];
   650  		if(map(obj, rsect) < 0)
   651  			goto bad;
   652  		rela = rsect->type == ElfSectRela;
   653  		n = rsect->size/(4+4*is64)/(2+rela);
   654  		r = mal(n*sizeof r[0]);
   655  		p = rsect->base;
   656  		for(j=0; j<n; j++) {
   657  			add = 0;
   658  			rp = &r[j];
   659  			if(is64) {
   660  				// 64-bit rel/rela
   661  				rp->off = e->e64(p);
   662  				p += 8;
   663  				info = e->e64(p);
   664  				p += 8;
   665  				if(rela) {
   666  					add = e->e64(p);
   667  					p += 8;
   668  				}
   669  			} else {
   670  				// 32-bit rel/rela
   671  				rp->off = e->e32(p);
   672  				p += 4;
   673  				info = e->e32(p);
   674  				info = info>>8<<32 | (info&0xff);	// convert to 64-bit info
   675  				p += 4;
   676  				if(rela) {
   677  					add = e->e32(p);
   678  					p += 4;
   679  				}
   680  			}
   681  			if((info & 0xffffffff) == 0) { // skip R_*_NONE relocation
   682  				j--;
   683  				n--;
   684  				continue;
   685  			}
   686  			if((info >> 32) == 0) { // absolute relocation, don't bother reading the null symbol
   687  				rp->sym = S;
   688  			} else {
   689  				if(readsym(obj, info>>32, &sym, 0) < 0)
   690  					goto bad;
   691  				sym.sym = symbols[info>>32];
   692  				if(sym.sym == nil) {
   693  					werrstr("%s#%d: reloc of invalid sym #%d %s shndx=%d type=%d",
   694  						sect->sym->name, j, (int)(info>>32), sym.name, sym.shndx, sym.type);
   695  					goto bad;
   696  				}
   697  				rp->sym = sym.sym;
   698  			}
   699  			rp->type = reltype(pn, (uint32)info, &rp->siz);
   700  			if(rela)
   701  				rp->add = add;
   702  			else {
   703  				// load addend from image
   704  				if(rp->siz == 4)
   705  					rp->add = e->e32(sect->base+rp->off);
   706  				else if(rp->siz == 8)
   707  					rp->add = e->e64(sect->base+rp->off);
   708  				else
   709  					diag("invalid rela size %d", rp->siz);
   710  			}
   711  			if(rp->siz == 4)
   712  				rp->add = (int32)rp->add;
   713  			//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
   714  		}
   715  		qsort(r, n, sizeof r[0], rbyoff);	// just in case
   716  		
   717  		s = sect->sym;
   718  		s->r = r;
   719  		s->nr = n;
   720  	}
   721  	free(symbols);
   722  
   723  	return;
   724  
   725  bad:
   726  	diag("%s: malformed elf file: %r", pn);
   727  	free(symbols);
   728  }
   729  
   730  static ElfSect*
   731  section(ElfObj *obj, char *name)
   732  {
   733  	int i;
   734  	
   735  	for(i=0; i<obj->nsect; i++)
   736  		if(obj->sect[i].name && name && strcmp(obj->sect[i].name, name) == 0)
   737  			return &obj->sect[i];
   738  	return nil;
   739  }
   740  
   741  static int
   742  map(ElfObj *obj, ElfSect *sect)
   743  {
   744  	if(sect->base != nil)
   745  		return 0;
   746  
   747  	if(sect->off+sect->size > obj->len) {
   748  		werrstr("elf section past end of file");
   749  		return -1;
   750  	}
   751  
   752  	sect->base = mal(sect->size);
   753  	werrstr("short read");
   754  	if(Bseek(obj->f, obj->base+sect->off, 0) < 0 || Bread(obj->f, sect->base, sect->size) != sect->size)
   755  		return -1;
   756  	
   757  	return 0;
   758  }
   759  
   760  static int
   761  readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
   762  {
   763  	LSym *s;
   764  
   765  	if(i >= obj->nsymtab || i < 0) {
   766  		werrstr("invalid elf symbol index");
   767  		return -1;
   768  	}
   769  	if(i == 0) {
   770  		diag("readym: read null symbol!");
   771  	}
   772  
   773  	if(obj->is64) {
   774  		ElfSymBytes64 *b;
   775  		
   776  		b = (ElfSymBytes64*)(obj->symtab->base + i*sizeof *b);
   777  		sym->name = (char*)obj->symstr->base + obj->e->e32(b->name);
   778  		sym->value = obj->e->e64(b->value);
   779  		sym->size = obj->e->e64(b->size);
   780  		sym->shndx = obj->e->e16(b->shndx);
   781  		sym->bind = b->info>>4;
   782  		sym->type = b->info&0xf;
   783  		sym->other = b->other;
   784  	} else {
   785  		ElfSymBytes *b;
   786  		
   787  		b = (ElfSymBytes*)(obj->symtab->base + i*sizeof *b);
   788  		sym->name = (char*)obj->symstr->base + obj->e->e32(b->name);
   789  		sym->value = obj->e->e32(b->value);
   790  		sym->size = obj->e->e32(b->size);
   791  		sym->shndx = obj->e->e16(b->shndx);
   792  		sym->bind = b->info>>4;
   793  		sym->type = b->info&0xf;
   794  		sym->other = b->other;
   795  	}
   796  
   797  	s = nil;
   798  	if(strcmp(sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
   799  		sym->name = ".got";
   800  	switch(sym->type) {
   801  	case ElfSymTypeSection:
   802  		s = obj->sect[sym->shndx].sym;
   803  		break;
   804  	case ElfSymTypeObject:
   805  	case ElfSymTypeFunc:
   806  	case ElfSymTypeNone:
   807  		switch(sym->bind) {
   808  		case ElfSymBindGlobal:
   809  			if(needSym) {
   810  				s = linklookup(ctxt, sym->name, 0);
   811  				// for global scoped hidden symbols we should insert it into
   812  				// symbol hash table, but mark them as hidden.
   813  				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
   814  				// workaround that we set dupok.
   815  				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
   816  				// set dupok generally. See http://codereview.appspot.com/5823055/
   817  				// comment #5 for details.
   818  				if(s && sym->other == 2) {
   819  					s->type |= SHIDDEN;
   820  					s->dupok = 1;
   821  				}
   822  			}
   823  			break;
   824  		case ElfSymBindLocal:
   825  			if(!(thechar == '5' && (strncmp(sym->name, "$a", 2) == 0 || strncmp(sym->name, "$d", 2) == 0))) // binutils for arm generate these mapping symbols, ignore these
   826  				if(needSym) {
   827  					// local names and hidden visiblity global names are unique
   828  					// and should only reference by its index, not name, so we
   829  					// don't bother to add them into hash table
   830  					s = linknewsym(ctxt, sym->name, ctxt->version);
   831  					s->type |= SHIDDEN;
   832  				}
   833  			break;
   834  		case ElfSymBindWeak:
   835  			if(needSym) {
   836  				s = linknewsym(ctxt, sym->name, 0);
   837  				if(sym->other == 2)
   838  					s->type |= SHIDDEN;
   839  			}
   840  			break;
   841  		default:
   842  			werrstr("%s: invalid symbol binding %d", sym->name, sym->bind);
   843  			return -1;
   844  		}
   845  		break;
   846  	}
   847  	if(s != nil && s->type == 0 && sym->type != ElfSymTypeSection)
   848  		s->type = SXREF;
   849  	sym->sym = s;
   850  
   851  	return 0;
   852  }
   853  
   854  int
   855  rbyoff(const void *va, const void *vb)
   856  {
   857  	Reloc *a, *b;
   858  	
   859  	a = (Reloc*)va;
   860  	b = (Reloc*)vb;
   861  	if(a->off < b->off)
   862  		return -1;
   863  	if(a->off > b->off)
   864  		return +1;
   865  	return 0;
   866  }
   867  
   868  #define R(x, y) ((x)|((y)<<24))
   869  
   870  static int
   871  reltype(char *pn, int elftype, uchar *siz)
   872  {
   873  	switch(R(thechar, elftype)) {
   874  	default:
   875  		diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype);
   876  	case R('5', R_ARM_ABS32):
   877  	case R('5', R_ARM_GOT32):
   878  	case R('5', R_ARM_PLT32):
   879  	case R('5', R_ARM_GOTOFF):
   880  	case R('5', R_ARM_GOTPC):
   881  	case R('5', R_ARM_THM_PC22):
   882  	case R('5', R_ARM_REL32):
   883  	case R('5', R_ARM_CALL):
   884  	case R('5', R_ARM_V4BX):
   885  	case R('5', R_ARM_GOT_PREL):
   886  	case R('5', R_ARM_PC24):
   887  	case R('5', R_ARM_JUMP24):
   888  	case R('6', R_X86_64_PC32):
   889  	case R('6', R_X86_64_PLT32):
   890  	case R('6', R_X86_64_GOTPCREL):
   891  	case R('6', R_X86_64_GOTPCRELX):
   892  	case R('6', R_X86_64_REX_GOTPCRELX):
   893  	case R('8', R_386_32):
   894  	case R('8', R_386_PC32):
   895  	case R('8', R_386_GOT32):
   896  	case R('8', R_386_PLT32):
   897  	case R('8', R_386_GOTOFF):
   898  	case R('8', R_386_GOTPC):
   899  	case R('8', R_386_GOT32X):
   900  		*siz = 4;
   901  		break;
   902  	case R('6', R_X86_64_64):
   903  		*siz = 8;
   904  		break;
   905  	}
   906  
   907  	return 256+elftype;
   908  }