github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/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 = ≤ 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 s->type = SNOPTRDATA; 549 break; 550 case ElfSectFlagAlloc + ElfSectFlagExec: 551 s->type = STEXT; 552 break; 553 } 554 if(sect->type == ElfSectProgbits) { 555 s->p = sect->base; 556 s->np = sect->size; 557 } 558 s->size = sect->size; 559 s->align = sect->align; 560 sect->sym = s; 561 } 562 563 // enter sub-symbols into symbol table. 564 // symbol 0 is the null symbol. 565 symbols = malloc(obj->nsymtab * sizeof(symbols[0])); 566 if(symbols == nil) { 567 diag("out of memory"); 568 errorexit(); 569 } 570 for(i=1; i<obj->nsymtab; i++) { 571 if(readsym(obj, i, &sym, 1) < 0) 572 goto bad; 573 symbols[i] = sym.sym; 574 if(sym.type != ElfSymTypeFunc && sym.type != ElfSymTypeObject && sym.type != ElfSymTypeNone) 575 continue; 576 if(sym.shndx == ElfSymShnCommon) { 577 s = sym.sym; 578 if(s->size < sym.size) 579 s->size = sym.size; 580 if(s->type == 0 || s->type == SXREF) 581 s->type = SNOPTRBSS; 582 continue; 583 } 584 if(sym.shndx >= obj->nsect || sym.shndx == 0) 585 continue; 586 // even when we pass needSym == 1 to readsym, it might still return nil to skip some unwanted symbols 587 if(sym.sym == S) 588 continue; 589 sect = obj->sect+sym.shndx; 590 if(sect->sym == nil) { 591 if(strncmp(sym.name, ".Linfo_string", 13) == 0) // clang does this 592 continue; 593 diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type); 594 continue; 595 } 596 s = sym.sym; 597 if(s->outer != S) { 598 if(s->dupok) 599 continue; 600 diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name); 601 errorexit(); 602 } 603 s->sub = sect->sym->sub; 604 sect->sym->sub = s; 605 s->type = sect->sym->type | (s->type&~SMASK) | SSUB; 606 if(!(s->cgoexport & CgoExportDynamic)) 607 s->dynimplib = nil; // satisfy dynimport 608 s->value = sym.value; 609 s->size = sym.size; 610 s->outer = sect->sym; 611 if(sect->sym->type == STEXT) { 612 if(s->external && !s->dupok) 613 diag("%s: duplicate definition of %s", pn, s->name); 614 s->external = 1; 615 } 616 } 617 618 // Sort outer lists by address, adding to textp. 619 // This keeps textp in increasing address order. 620 for(i=0; i<obj->nsect; i++) { 621 s = obj->sect[i].sym; 622 if(s == S) 623 continue; 624 if(s->sub) 625 s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub)); 626 if(s->type == STEXT) { 627 if(s->onlist) 628 sysfatal("symbol %s listed multiple times", s->name); 629 s->onlist = 1; 630 if(ctxt->etextp) 631 ctxt->etextp->next = s; 632 else 633 ctxt->textp = s; 634 ctxt->etextp = s; 635 for(s = s->sub; s != S; s = s->sub) { 636 if(s->onlist) 637 sysfatal("symbol %s listed multiple times", s->name); 638 s->onlist = 1; 639 ctxt->etextp->next = s; 640 ctxt->etextp = s; 641 } 642 } 643 } 644 645 // load relocations 646 for(i=0; i<obj->nsect; i++) { 647 rsect = &obj->sect[i]; 648 if(rsect->type != ElfSectRela && rsect->type != ElfSectRel) 649 continue; 650 if(rsect->info >= obj->nsect || obj->sect[rsect->info].base == nil) 651 continue; 652 sect = &obj->sect[rsect->info]; 653 if(map(obj, rsect) < 0) 654 goto bad; 655 rela = rsect->type == ElfSectRela; 656 n = rsect->size/(4+4*is64)/(2+rela); 657 r = mal(n*sizeof r[0]); 658 p = rsect->base; 659 for(j=0; j<n; j++) { 660 add = 0; 661 rp = &r[j]; 662 if(is64) { 663 // 64-bit rel/rela 664 rp->off = e->e64(p); 665 p += 8; 666 info = e->e64(p); 667 p += 8; 668 if(rela) { 669 add = e->e64(p); 670 p += 8; 671 } 672 } else { 673 // 32-bit rel/rela 674 rp->off = e->e32(p); 675 p += 4; 676 info = e->e32(p); 677 info = info>>8<<32 | (info&0xff); // convert to 64-bit info 678 p += 4; 679 if(rela) { 680 add = e->e32(p); 681 p += 4; 682 } 683 } 684 if((info & 0xffffffff) == 0) { // skip R_*_NONE relocation 685 j--; 686 n--; 687 continue; 688 } 689 if((info >> 32) == 0) { // absolute relocation, don't bother reading the null symbol 690 rp->sym = S; 691 } else { 692 if(readsym(obj, info>>32, &sym, 0) < 0) 693 goto bad; 694 sym.sym = symbols[info>>32]; 695 if(sym.sym == nil) { 696 werrstr("%s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", 697 sect->sym->name, j, (int)(info>>32), sym.name, sym.shndx, sym.type); 698 goto bad; 699 } 700 rp->sym = sym.sym; 701 } 702 rp->type = reltype(pn, (uint32)info, &rp->siz); 703 if(rela) 704 rp->add = add; 705 else { 706 // load addend from image 707 if(rp->siz == 4) 708 rp->add = e->e32(sect->base+rp->off); 709 else if(rp->siz == 8) 710 rp->add = e->e64(sect->base+rp->off); 711 else 712 diag("invalid rela size %d", rp->siz); 713 } 714 if(rp->siz == 4) 715 rp->add = (int32)rp->add; 716 //print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add); 717 } 718 qsort(r, n, sizeof r[0], rbyoff); // just in case 719 720 s = sect->sym; 721 s->r = r; 722 s->nr = n; 723 } 724 free(symbols); 725 726 return; 727 728 bad: 729 diag("%s: malformed elf file: %r", pn); 730 free(symbols); 731 } 732 733 static ElfSect* 734 section(ElfObj *obj, char *name) 735 { 736 int i; 737 738 for(i=0; i<obj->nsect; i++) 739 if(obj->sect[i].name && name && strcmp(obj->sect[i].name, name) == 0) 740 return &obj->sect[i]; 741 return nil; 742 } 743 744 static int 745 map(ElfObj *obj, ElfSect *sect) 746 { 747 if(sect->base != nil) 748 return 0; 749 750 if(sect->off+sect->size > obj->len) { 751 werrstr("elf section past end of file"); 752 return -1; 753 } 754 755 sect->base = mal(sect->size); 756 werrstr("short read"); 757 if(Bseek(obj->f, obj->base+sect->off, 0) < 0 || Bread(obj->f, sect->base, sect->size) != sect->size) 758 return -1; 759 760 return 0; 761 } 762 763 static int 764 readsym(ElfObj *obj, int i, ElfSym *sym, int needSym) 765 { 766 LSym *s; 767 768 if(i >= obj->nsymtab || i < 0) { 769 werrstr("invalid elf symbol index"); 770 return -1; 771 } 772 if(i == 0) { 773 diag("readym: read null symbol!"); 774 } 775 776 if(obj->is64) { 777 ElfSymBytes64 *b; 778 779 b = (ElfSymBytes64*)(obj->symtab->base + i*sizeof *b); 780 sym->name = (char*)obj->symstr->base + obj->e->e32(b->name); 781 sym->value = obj->e->e64(b->value); 782 sym->size = obj->e->e64(b->size); 783 sym->shndx = obj->e->e16(b->shndx); 784 sym->bind = b->info>>4; 785 sym->type = b->info&0xf; 786 sym->other = b->other; 787 } else { 788 ElfSymBytes *b; 789 790 b = (ElfSymBytes*)(obj->symtab->base + i*sizeof *b); 791 sym->name = (char*)obj->symstr->base + obj->e->e32(b->name); 792 sym->value = obj->e->e32(b->value); 793 sym->size = obj->e->e32(b->size); 794 sym->shndx = obj->e->e16(b->shndx); 795 sym->bind = b->info>>4; 796 sym->type = b->info&0xf; 797 sym->other = b->other; 798 } 799 800 s = nil; 801 if(strcmp(sym->name, "_GLOBAL_OFFSET_TABLE_") == 0) 802 sym->name = ".got"; 803 switch(sym->type) { 804 case ElfSymTypeSection: 805 s = obj->sect[sym->shndx].sym; 806 break; 807 case ElfSymTypeObject: 808 case ElfSymTypeFunc: 809 case ElfSymTypeNone: 810 switch(sym->bind) { 811 case ElfSymBindGlobal: 812 if(needSym) { 813 s = linklookup(ctxt, sym->name, 0); 814 // for global scoped hidden symbols we should insert it into 815 // symbol hash table, but mark them as hidden. 816 // __i686.get_pc_thunk.bx is allowed to be duplicated, to 817 // workaround that we set dupok. 818 // TODO(minux): correctly handle __i686.get_pc_thunk.bx without 819 // set dupok generally. See http://codereview.appspot.com/5823055/ 820 // comment #5 for details. 821 if(s && sym->other == 2) { 822 s->type |= SHIDDEN; 823 s->dupok = 1; 824 } 825 } 826 break; 827 case ElfSymBindLocal: 828 if(!(thechar == '5' && (strncmp(sym->name, "$a", 2) == 0 || strncmp(sym->name, "$d", 2) == 0))) // binutils for arm generate these mapping symbols, ignore these 829 if(needSym) { 830 // local names and hidden visiblity global names are unique 831 // and should only reference by its index, not name, so we 832 // don't bother to add them into hash table 833 s = linknewsym(ctxt, sym->name, ctxt->version); 834 s->type |= SHIDDEN; 835 } 836 break; 837 case ElfSymBindWeak: 838 if(needSym) { 839 s = linknewsym(ctxt, sym->name, 0); 840 if(sym->other == 2) 841 s->type |= SHIDDEN; 842 } 843 break; 844 default: 845 werrstr("%s: invalid symbol binding %d", sym->name, sym->bind); 846 return -1; 847 } 848 break; 849 } 850 if(s != nil && s->type == 0 && sym->type != ElfSymTypeSection) 851 s->type = SXREF; 852 sym->sym = s; 853 854 return 0; 855 } 856 857 int 858 rbyoff(const void *va, const void *vb) 859 { 860 Reloc *a, *b; 861 862 a = (Reloc*)va; 863 b = (Reloc*)vb; 864 if(a->off < b->off) 865 return -1; 866 if(a->off > b->off) 867 return +1; 868 return 0; 869 } 870 871 #define R(x, y) ((x)|((y)<<24)) 872 873 static int 874 reltype(char *pn, int elftype, uchar *siz) 875 { 876 switch(R(thechar, elftype)) { 877 default: 878 diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype); 879 case R('5', R_ARM_ABS32): 880 case R('5', R_ARM_GOT32): 881 case R('5', R_ARM_PLT32): 882 case R('5', R_ARM_GOTOFF): 883 case R('5', R_ARM_GOTPC): 884 case R('5', R_ARM_THM_PC22): 885 case R('5', R_ARM_REL32): 886 case R('5', R_ARM_CALL): 887 case R('5', R_ARM_V4BX): 888 case R('5', R_ARM_GOT_PREL): 889 case R('5', R_ARM_PC24): 890 case R('5', R_ARM_JUMP24): 891 case R('6', R_X86_64_PC32): 892 case R('6', R_X86_64_PLT32): 893 case R('6', R_X86_64_GOTPCREL): 894 case R('8', R_386_32): 895 case R('8', R_386_PC32): 896 case R('8', R_386_GOT32): 897 case R('8', R_386_PLT32): 898 case R('8', R_386_GOTOFF): 899 case R('8', R_386_GOTPC): 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 }