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 = ≤ 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 }