| author | |
| committer | |
| log | 38aed5af8bdefd13a355fc0728c6ad57e5efa3ff |
| tree | 79eb22695fd67db1bf3253a2b1ffe70a975342c8 |
| parent | aa043a633904b6685a201000a0ab2a62fc3bdb91 |
31 files changed, 856 insertions(+), 45 deletions(-)
deps/lld-prebuilt/ELF/Options.inc+2-2| ... | @@ -230,6 +230,8 @@ OPTION(prefix_2, "no-merge-exidx-entries", no_merge_exidx_entries, Flag, INVALID | ... | @@ -230,6 +230,8 @@ OPTION(prefix_2, "no-merge-exidx-entries", no_merge_exidx_entries, Flag, INVALID |
| 230 | OPTION(prefix_2, "no-mmap-output-file", no_mmap_output_file, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 230 | OPTION(prefix_2, "no-mmap-output-file", no_mmap_output_file, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 231 | OPTION(prefix_3, "no-omagic", no_omagic, Flag, INVALID, INVALID, nullptr, 0, 0, | 231 | OPTION(prefix_3, "no-omagic", no_omagic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 232 | "Do not set the text data sections to be writable", "<magic>", nullptr) | 232 | "Do not set the text data sections to be writable", "<magic>", nullptr) |
| 233 | OPTION(prefix_2, "no-pie", no_pie, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 234 | "Do not create a position independent executable", nullptr, nullptr) | ||
| 233 | OPTION(prefix_2, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | 235 | OPTION(prefix_2, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 234 | "Do not list removed unused sections", nullptr, nullptr) | 236 | "Do not list removed unused sections", nullptr, nullptr) |
| 235 | OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr, 0, 0, | 237 | OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -247,8 +249,6 @@ OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, n | ... | @@ -247,8 +249,6 @@ OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, n |
| 247 | OPTION(prefix_2, "noinhibit-exec", noinhibit_exec, Flag, INVALID, INVALID, nullptr, 0, 0, | 249 | OPTION(prefix_2, "noinhibit-exec", noinhibit_exec, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 248 | "Retain the executable output file whenever it is still usable", nullptr, nullptr) | 250 | "Retain the executable output file whenever it is still usable", nullptr, nullptr) |
| 249 | OPTION(prefix_2, "non_shared", alias_Bstatic_non_shared, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 251 | OPTION(prefix_2, "non_shared", alias_Bstatic_non_shared, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 250 | OPTION(prefix_2, "nopie", nopie, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 251 | "Do not create a position independent executable", nullptr, nullptr) | ||
| 252 | OPTION(prefix_2, "nostdlib", nostdlib, Flag, INVALID, INVALID, nullptr, 0, 0, | 252 | OPTION(prefix_2, "nostdlib", nostdlib, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 253 | "Only search directories specified on the command line", nullptr, nullptr) | 253 | "Only search directories specified on the command line", nullptr, nullptr) |
| 254 | OPTION(prefix_1, "N", alias_omagic, Flag, INVALID, omagic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 254 | OPTION(prefix_1, "N", alias_omagic, Flag, INVALID, omagic, nullptr, 0, 0, nullptr, nullptr, nullptr) |
deps/lld/ELF/AArch64ErrataFix.cpp+2-1| ... | @@ -47,6 +47,7 @@ | ... | @@ -47,6 +47,7 @@ |
| 47 | using namespace llvm; | 47 | using namespace llvm; |
| 48 | using namespace llvm::ELF; | 48 | using namespace llvm::ELF; |
| 49 | using namespace llvm::object; | 49 | using namespace llvm::object; |
| 50 | using namespace llvm::support; | ||
| 50 | using namespace llvm::support::endian; | 51 | using namespace llvm::support::endian; |
| 51 | 52 | ||
| 52 | using namespace lld; | 53 | using namespace lld; |
| ... | @@ -357,7 +358,7 @@ static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off, | ... | @@ -357,7 +358,7 @@ static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off, |
| 357 | 358 | ||
| 358 | uint64_t PatchOff = 0; | 359 | uint64_t PatchOff = 0; |
| 359 | const uint8_t *Buf = IS->Data.begin(); | 360 | const uint8_t *Buf = IS->Data.begin(); |
| 360 | const uint32_t *InstBuf = reinterpret_cast<const uint32_t *>(Buf + Off); | 361 | const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off); |
| 361 | uint32_t Instr1 = *InstBuf++; | 362 | uint32_t Instr1 = *InstBuf++; |
| 362 | uint32_t Instr2 = *InstBuf++; | 363 | uint32_t Instr2 = *InstBuf++; |
| 363 | uint32_t Instr3 = *InstBuf++; | 364 | uint32_t Instr3 = *InstBuf++; |
deps/lld/ELF/Arch/X86.cpp+141-3| ... | @@ -21,7 +21,7 @@ using namespace lld; | ... | @@ -21,7 +21,7 @@ using namespace lld; |
| 21 | using namespace lld::elf; | 21 | using namespace lld::elf; |
| 22 | 22 | ||
| 23 | namespace { | 23 | namespace { |
| 24 | class X86 final : public TargetInfo { | 24 | class X86 : public TargetInfo { |
| 25 | public: | 25 | public: |
| 26 | X86(); | 26 | X86(); |
| 27 | RelExpr getRelExpr(RelType Type, const Symbol &S, | 27 | RelExpr getRelExpr(RelType Type, const Symbol &S, |
| ... | @@ -399,7 +399,145 @@ void X86::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -399,7 +399,145 @@ void X86::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 399 | memcpy(Loc - 2, Inst, sizeof(Inst)); | 399 | memcpy(Loc - 2, Inst, sizeof(Inst)); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | namespace { | ||
| 403 | class RetpolinePic : public X86 { | ||
| 404 | public: | ||
| 405 | RetpolinePic(); | ||
| 406 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | ||
| 407 | void writePltHeader(uint8_t *Buf) const override; | ||
| 408 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | ||
| 409 | int32_t Index, unsigned RelOff) const override; | ||
| 410 | }; | ||
| 411 | |||
| 412 | class RetpolineNoPic : public X86 { | ||
| 413 | public: | ||
| 414 | RetpolineNoPic(); | ||
| 415 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | ||
| 416 | void writePltHeader(uint8_t *Buf) const override; | ||
| 417 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | ||
| 418 | int32_t Index, unsigned RelOff) const override; | ||
| 419 | }; | ||
| 420 | } // namespace | ||
| 421 | |||
| 422 | RetpolinePic::RetpolinePic() { | ||
| 423 | PltHeaderSize = 48; | ||
| 424 | PltEntrySize = 32; | ||
| 425 | } | ||
| 426 | |||
| 427 | void RetpolinePic::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | ||
| 428 | write32le(Buf, S.getPltVA() + 17); | ||
| 429 | } | ||
| 430 | |||
| 431 | void RetpolinePic::writePltHeader(uint8_t *Buf) const { | ||
| 432 | const uint8_t Insn[] = { | ||
| 433 | 0xff, 0xb3, 0, 0, 0, 0, // 0: pushl GOTPLT+4(%ebx) | ||
| 434 | 0x50, // 6: pushl %eax | ||
| 435 | 0x8b, 0x83, 0, 0, 0, 0, // 7: mov GOTPLT+8(%ebx), %eax | ||
| 436 | 0xe8, 0x0e, 0x00, 0x00, 0x00, // d: call next | ||
| 437 | 0xf3, 0x90, // 12: loop: pause | ||
| 438 | 0x0f, 0xae, 0xe8, // 14: lfence | ||
| 439 | 0xeb, 0xf9, // 17: jmp loop | ||
| 440 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 19: int3; .align 16 | ||
| 441 | 0x89, 0x0c, 0x24, // 20: next: mov %ecx, (%esp) | ||
| 442 | 0x8b, 0x4c, 0x24, 0x04, // 23: mov 0x4(%esp), %ecx | ||
| 443 | 0x89, 0x44, 0x24, 0x04, // 27: mov %eax ,0x4(%esp) | ||
| 444 | 0x89, 0xc8, // 2b: mov %ecx, %eax | ||
| 445 | 0x59, // 2d: pop %ecx | ||
| 446 | 0xc3, // 2e: ret | ||
| 447 | }; | ||
| 448 | memcpy(Buf, Insn, sizeof(Insn)); | ||
| 449 | |||
| 450 | uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); | ||
| 451 | uint32_t GotPlt = InX::GotPlt->getVA() - Ebx; | ||
| 452 | write32le(Buf + 2, GotPlt + 4); | ||
| 453 | write32le(Buf + 9, GotPlt + 8); | ||
| 454 | } | ||
| 455 | |||
| 456 | void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ||
| 457 | uint64_t PltEntryAddr, int32_t Index, | ||
| 458 | unsigned RelOff) const { | ||
| 459 | const uint8_t Insn[] = { | ||
| 460 | 0x50, // pushl %eax | ||
| 461 | 0x8b, 0x83, 0, 0, 0, 0, // mov foo@GOT(%ebx), %eax | ||
| 462 | 0xe8, 0, 0, 0, 0, // call plt+0x20 | ||
| 463 | 0xe9, 0, 0, 0, 0, // jmp plt+0x12 | ||
| 464 | 0x68, 0, 0, 0, 0, // pushl $reloc_offset | ||
| 465 | 0xe9, 0, 0, 0, 0, // jmp plt+0 | ||
| 466 | }; | ||
| 467 | memcpy(Buf, Insn, sizeof(Insn)); | ||
| 468 | |||
| 469 | uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); | ||
| 470 | write32le(Buf + 3, GotPltEntryAddr - Ebx); | ||
| 471 | write32le(Buf + 8, -Index * PltEntrySize - PltHeaderSize - 12 + 32); | ||
| 472 | write32le(Buf + 13, -Index * PltEntrySize - PltHeaderSize - 17 + 18); | ||
| 473 | write32le(Buf + 18, RelOff); | ||
| 474 | write32le(Buf + 23, -Index * PltEntrySize - PltHeaderSize - 27); | ||
| 475 | } | ||
| 476 | |||
| 477 | RetpolineNoPic::RetpolineNoPic() { | ||
| 478 | PltHeaderSize = 48; | ||
| 479 | PltEntrySize = 32; | ||
| 480 | } | ||
| 481 | |||
| 482 | void RetpolineNoPic::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | ||
| 483 | write32le(Buf, S.getPltVA() + 16); | ||
| 484 | } | ||
| 485 | |||
| 486 | void RetpolineNoPic::writePltHeader(uint8_t *Buf) const { | ||
| 487 | const uint8_t PltData[] = { | ||
| 488 | 0xff, 0x35, 0, 0, 0, 0, // 0: pushl GOTPLT+4 | ||
| 489 | 0x50, // 6: pushl %eax | ||
| 490 | 0xa1, 0, 0, 0, 0, // 7: mov GOTPLT+8, %eax | ||
| 491 | 0xe8, 0x0f, 0x00, 0x00, 0x00, // c: call next | ||
| 492 | 0xf3, 0x90, // 11: loop: pause | ||
| 493 | 0x0f, 0xae, 0xe8, // 13: lfence | ||
| 494 | 0xeb, 0xf9, // 16: jmp loop | ||
| 495 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 18: int3 | ||
| 496 | 0xcc, 0xcc, 0xcc, // 1f: int3; .align 16 | ||
| 497 | 0x89, 0x0c, 0x24, // 20: next: mov %ecx, (%esp) | ||
| 498 | 0x8b, 0x4c, 0x24, 0x04, // 23: mov 0x4(%esp), %ecx | ||
| 499 | 0x89, 0x44, 0x24, 0x04, // 27: mov %eax ,0x4(%esp) | ||
| 500 | 0x89, 0xc8, // 2b: mov %ecx, %eax | ||
| 501 | 0x59, // 2d: pop %ecx | ||
| 502 | 0xc3, // 2e: ret | ||
| 503 | }; | ||
| 504 | memcpy(Buf, PltData, sizeof(PltData)); | ||
| 505 | |||
| 506 | uint32_t GotPlt = InX::GotPlt->getVA(); | ||
| 507 | write32le(Buf + 2, GotPlt + 4); | ||
| 508 | write32le(Buf + 8, GotPlt + 8); | ||
| 509 | } | ||
| 510 | |||
| 511 | void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ||
| 512 | uint64_t PltEntryAddr, int32_t Index, | ||
| 513 | unsigned RelOff) const { | ||
| 514 | const uint8_t Insn[] = { | ||
| 515 | 0x50, // 0: pushl %eax | ||
| 516 | 0xa1, 0, 0, 0, 0, // 1: mov foo_in_GOT, %eax | ||
| 517 | 0xe8, 0, 0, 0, 0, // 6: call plt+0x20 | ||
| 518 | 0xe9, 0, 0, 0, 0, // b: jmp plt+0x11 | ||
| 519 | 0x68, 0, 0, 0, 0, // 10: pushl $reloc_offset | ||
| 520 | 0xe9, 0, 0, 0, 0, // 15: jmp plt+0 | ||
| 521 | }; | ||
| 522 | memcpy(Buf, Insn, sizeof(Insn)); | ||
| 523 | |||
| 524 | write32le(Buf + 2, GotPltEntryAddr); | ||
| 525 | write32le(Buf + 7, -Index * PltEntrySize - PltHeaderSize - 11 + 32); | ||
| 526 | write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16 + 17); | ||
| 527 | write32le(Buf + 17, RelOff); | ||
| 528 | write32le(Buf + 22, -Index * PltEntrySize - PltHeaderSize - 26); | ||
| 529 | } | ||
| 530 | |||
| 402 | TargetInfo *elf::getX86TargetInfo() { | 531 | TargetInfo *elf::getX86TargetInfo() { |
| 403 | static X86 Target; | 532 | if (Config->ZRetpolineplt) { |
| 404 | return &Target; | 533 | if (Config->Pic) { |
| 534 | static RetpolinePic T; | ||
| 535 | return &T; | ||
| 536 | } | ||
| 537 | static RetpolineNoPic T; | ||
| 538 | return &T; | ||
| 539 | } | ||
| 540 | |||
| 541 | static X86 T; | ||
| 542 | return &T; | ||
| 405 | } | 543 | } |
deps/lld/ELF/Arch/X86_64.cpp+120-7| ... | @@ -23,7 +23,7 @@ using namespace lld; | ... | @@ -23,7 +23,7 @@ using namespace lld; |
| 23 | using namespace lld::elf; | 23 | using namespace lld::elf; |
| 24 | 24 | ||
| 25 | namespace { | 25 | namespace { |
| 26 | template <class ELFT> class X86_64 final : public TargetInfo { | 26 | template <class ELFT> class X86_64 : public TargetInfo { |
| 27 | public: | 27 | public: |
| 28 | X86_64(); | 28 | X86_64(); |
| 29 | RelExpr getRelExpr(RelType Type, const Symbol &S, | 29 | RelExpr getRelExpr(RelType Type, const Symbol &S, |
| ... | @@ -460,12 +460,125 @@ void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const { | ... | @@ -460,12 +460,125 @@ void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const { |
| 460 | write32le(Loc - 1, Val + 1); | 460 | write32le(Loc - 1, Val + 1); |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | TargetInfo *elf::getX32TargetInfo() { | 463 | namespace { |
| 464 | static X86_64<ELF32LE> Target; | 464 | template <class ELFT> class Retpoline : public X86_64<ELFT> { |
| 465 | return &Target; | 465 | public: |
| 466 | Retpoline(); | ||
| 467 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | ||
| 468 | void writePltHeader(uint8_t *Buf) const override; | ||
| 469 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | ||
| 470 | int32_t Index, unsigned RelOff) const override; | ||
| 471 | }; | ||
| 472 | |||
| 473 | template <class ELFT> class RetpolineZNow : public X86_64<ELFT> { | ||
| 474 | public: | ||
| 475 | RetpolineZNow(); | ||
| 476 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override {} | ||
| 477 | void writePltHeader(uint8_t *Buf) const override; | ||
| 478 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | ||
| 479 | int32_t Index, unsigned RelOff) const override; | ||
| 480 | }; | ||
| 481 | } // namespace | ||
| 482 | |||
| 483 | template <class ELFT> Retpoline<ELFT>::Retpoline() { | ||
| 484 | TargetInfo::PltHeaderSize = 48; | ||
| 485 | TargetInfo::PltEntrySize = 32; | ||
| 486 | } | ||
| 487 | |||
| 488 | template <class ELFT> | ||
| 489 | void Retpoline<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | ||
| 490 | write32le(Buf, S.getPltVA() + 17); | ||
| 491 | } | ||
| 492 | |||
| 493 | template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const { | ||
| 494 | const uint8_t Insn[] = { | ||
| 495 | 0xff, 0x35, 0, 0, 0, 0, // 0: pushq GOTPLT+8(%rip) | ||
| 496 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 6: mov GOTPLT+16(%rip), %r11 | ||
| 497 | 0xe8, 0x0e, 0x00, 0x00, 0x00, // d: callq next | ||
| 498 | 0xf3, 0x90, // 12: loop: pause | ||
| 499 | 0x0f, 0xae, 0xe8, // 14: lfence | ||
| 500 | 0xeb, 0xf9, // 17: jmp loop | ||
| 501 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 19: int3; .align 16 | ||
| 502 | 0x4c, 0x89, 0x1c, 0x24, // 20: next: mov %r11, (%rsp) | ||
| 503 | 0xc3, // 24: ret | ||
| 504 | }; | ||
| 505 | memcpy(Buf, Insn, sizeof(Insn)); | ||
| 506 | |||
| 507 | uint64_t GotPlt = InX::GotPlt->getVA(); | ||
| 508 | uint64_t Plt = InX::Plt->getVA(); | ||
| 509 | write32le(Buf + 2, GotPlt - Plt - 6 + 8); | ||
| 510 | write32le(Buf + 9, GotPlt - Plt - 13 + 16); | ||
| 511 | } | ||
| 512 | |||
| 513 | template <class ELFT> | ||
| 514 | void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ||
| 515 | uint64_t PltEntryAddr, int32_t Index, | ||
| 516 | unsigned RelOff) const { | ||
| 517 | const uint8_t Insn[] = { | ||
| 518 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0: mov foo@GOTPLT(%rip), %r11 | ||
| 519 | 0xe8, 0, 0, 0, 0, // 7: callq plt+0x20 | ||
| 520 | 0xe9, 0, 0, 0, 0, // c: jmp plt+0x12 | ||
| 521 | 0x68, 0, 0, 0, 0, // 11: pushq <relocation index> | ||
| 522 | 0xe9, 0, 0, 0, 0, // 16: jmp plt+0 | ||
| 523 | }; | ||
| 524 | memcpy(Buf, Insn, sizeof(Insn)); | ||
| 525 | |||
| 526 | uint64_t Off = TargetInfo::PltHeaderSize + TargetInfo::PltEntrySize * Index; | ||
| 527 | |||
| 528 | write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7); | ||
| 529 | write32le(Buf + 8, -Off - 12 + 32); | ||
| 530 | write32le(Buf + 13, -Off - 17 + 18); | ||
| 531 | write32le(Buf + 18, Index); | ||
| 532 | write32le(Buf + 23, -Off - 27); | ||
| 533 | } | ||
| 534 | |||
| 535 | template <class ELFT> RetpolineZNow<ELFT>::RetpolineZNow() { | ||
| 536 | TargetInfo::PltHeaderSize = 32; | ||
| 537 | TargetInfo::PltEntrySize = 16; | ||
| 538 | } | ||
| 539 | |||
| 540 | template <class ELFT> | ||
| 541 | void RetpolineZNow<ELFT>::writePltHeader(uint8_t *Buf) const { | ||
| 542 | const uint8_t Insn[] = { | ||
| 543 | 0xe8, 0x0b, 0x00, 0x00, 0x00, // 0: call next | ||
| 544 | 0xf3, 0x90, // 5: loop: pause | ||
| 545 | 0x0f, 0xae, 0xe8, // 7: lfence | ||
| 546 | 0xeb, 0xf9, // a: jmp loop | ||
| 547 | 0xcc, 0xcc, 0xcc, 0xcc, // c: int3; .align 16 | ||
| 548 | 0x4c, 0x89, 0x1c, 0x24, // 10: next: mov %r11, (%rsp) | ||
| 549 | 0xc3, // 14: ret | ||
| 550 | }; | ||
| 551 | memcpy(Buf, Insn, sizeof(Insn)); | ||
| 466 | } | 552 | } |
| 467 | 553 | ||
| 468 | TargetInfo *elf::getX86_64TargetInfo() { | 554 | template <class ELFT> |
| 469 | static X86_64<ELF64LE> Target; | 555 | void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 470 | return &Target; | 556 | uint64_t PltEntryAddr, int32_t Index, |
| 557 | unsigned RelOff) const { | ||
| 558 | const uint8_t Insn[] = { | ||
| 559 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // mov foo@GOTPLT(%rip), %r11 | ||
| 560 | 0xe9, 0, 0, 0, 0, // jmp plt+0 | ||
| 561 | }; | ||
| 562 | memcpy(Buf, Insn, sizeof(Insn)); | ||
| 563 | |||
| 564 | write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7); | ||
| 565 | write32le(Buf + 8, | ||
| 566 | -Index * TargetInfo::PltEntrySize - TargetInfo::PltHeaderSize - 12); | ||
| 471 | } | 567 | } |
| 568 | |||
| 569 | template <class ELFT> TargetInfo *getTargetInfo() { | ||
| 570 | if (Config->ZRetpolineplt) { | ||
| 571 | if (Config->ZNow) { | ||
| 572 | static RetpolineZNow<ELFT> T; | ||
| 573 | return &T; | ||
| 574 | } | ||
| 575 | static Retpoline<ELFT> T; | ||
| 576 | return &T; | ||
| 577 | } | ||
| 578 | |||
| 579 | static X86_64<ELFT> T; | ||
| 580 | return &T; | ||
| 581 | } | ||
| 582 | |||
| 583 | TargetInfo *elf::getX32TargetInfo() { return getTargetInfo<ELF32LE>(); } | ||
| 584 | TargetInfo *elf::getX86_64TargetInfo() { return getTargetInfo<ELF64LE>(); } |
deps/lld/ELF/Config.h+1| ... | @@ -159,6 +159,7 @@ struct Configuration { | ... | @@ -159,6 +159,7 @@ struct Configuration { |
| 159 | bool ZRelro; | 159 | bool ZRelro; |
| 160 | bool ZRodynamic; | 160 | bool ZRodynamic; |
| 161 | bool ZText; | 161 | bool ZText; |
| 162 | bool ZRetpolineplt; | ||
| 162 | bool ExitEarly; | 163 | bool ExitEarly; |
| 163 | bool ZWxneeded; | 164 | bool ZWxneeded; |
| 164 | DiscardPolicy Discard; | 165 | DiscardPolicy Discard; |
deps/lld/ELF/Driver.cpp+2-1| ... | @@ -638,7 +638,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { | ... | @@ -638,7 +638,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 638 | Config->Optimize = args::getInteger(Args, OPT_O, 1); | 638 | Config->Optimize = args::getInteger(Args, OPT_O, 1); |
| 639 | Config->OrphanHandling = getOrphanHandling(Args); | 639 | Config->OrphanHandling = getOrphanHandling(Args); |
| 640 | Config->OutputFile = Args.getLastArgValue(OPT_o); | 640 | Config->OutputFile = Args.getLastArgValue(OPT_o); |
| 641 | Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false); | 641 | Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false); |
| 642 | Config->PrintGcSections = | 642 | Config->PrintGcSections = |
| 643 | Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); | 643 | Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); |
| 644 | Config->Rpath = getRpath(Args); | 644 | Config->Rpath = getRpath(Args); |
| ... | @@ -674,6 +674,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { | ... | @@ -674,6 +674,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 674 | Config->ZNow = hasZOption(Args, "now"); | 674 | Config->ZNow = hasZOption(Args, "now"); |
| 675 | Config->ZOrigin = hasZOption(Args, "origin"); | 675 | Config->ZOrigin = hasZOption(Args, "origin"); |
| 676 | Config->ZRelro = !hasZOption(Args, "norelro"); | 676 | Config->ZRelro = !hasZOption(Args, "norelro"); |
| 677 | Config->ZRetpolineplt = hasZOption(Args, "retpolineplt"); | ||
| 677 | Config->ZRodynamic = hasZOption(Args, "rodynamic"); | 678 | Config->ZRodynamic = hasZOption(Args, "rodynamic"); |
| 678 | Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0); | 679 | Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0); |
| 679 | Config->ZText = !hasZOption(Args, "notext"); | 680 | Config->ZText = !hasZOption(Args, "notext"); |
deps/lld/ELF/InputFiles.cpp+8| ... | @@ -856,6 +856,14 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() { | ... | @@ -856,6 +856,14 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() { |
| 856 | continue; | 856 | continue; |
| 857 | } | 857 | } |
| 858 | 858 | ||
| 859 | if (Config->EMachine == EM_MIPS) { | ||
| 860 | // FIXME: MIPS BFD linker puts _gp_disp symbol into DSO files | ||
| 861 | // and incorrectly assigns VER_NDX_LOCAL to this section global | ||
| 862 | // symbol. Here is a workaround for this bug. | ||
| 863 | if (Versym && VersymIndex == VER_NDX_LOCAL && Name == "_gp_disp") | ||
| 864 | continue; | ||
| 865 | } | ||
| 866 | |||
| 859 | const Elf_Verdef *Ver = nullptr; | 867 | const Elf_Verdef *Ver = nullptr; |
| 860 | if (VersymIndex != VER_NDX_GLOBAL) { | 868 | if (VersymIndex != VER_NDX_GLOBAL) { |
| 861 | if (VersymIndex >= Verdefs.size() || VersymIndex == VER_NDX_LOCAL) { | 869 | if (VersymIndex >= Verdefs.size() || VersymIndex == VER_NDX_LOCAL) { |
deps/lld/ELF/LinkerScript.cpp+33-20| ... | @@ -589,8 +589,12 @@ void LinkerScript::output(InputSection *S) { | ... | @@ -589,8 +589,12 @@ void LinkerScript::output(InputSection *S) { |
| 589 | 589 | ||
| 590 | // If there is a memory region associated with this input section, then | 590 | // If there is a memory region associated with this input section, then |
| 591 | // place the section in that region and update the region index. | 591 | // place the section in that region and update the region index. |
| 592 | if (Ctx->LMARegion) | ||
| 593 | Ctx->LMARegion->CurPos += Pos - Before; | ||
| 594 | // FIXME: should we also produce overflow errors for LMARegion? | ||
| 595 | |||
| 592 | if (Ctx->MemRegion) { | 596 | if (Ctx->MemRegion) { |
| 593 | uint64_t &CurOffset = Ctx->MemRegionOffset[Ctx->MemRegion]; | 597 | uint64_t &CurOffset = Ctx->MemRegion->CurPos; |
| 594 | CurOffset += Pos - Before; | 598 | CurOffset += Pos - Before; |
| 595 | uint64_t CurSize = CurOffset - Ctx->MemRegion->Origin; | 599 | uint64_t CurSize = CurOffset - Ctx->MemRegion->Origin; |
| 596 | if (CurSize > Ctx->MemRegion->Length) { | 600 | if (CurSize > Ctx->MemRegion->Length) { |
| ... | @@ -608,13 +612,6 @@ void LinkerScript::switchTo(OutputSection *Sec) { | ... | @@ -608,13 +612,6 @@ void LinkerScript::switchTo(OutputSection *Sec) { |
| 608 | 612 | ||
| 609 | Ctx->OutSec = Sec; | 613 | Ctx->OutSec = Sec; |
| 610 | Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment); | 614 | Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment); |
| 611 | |||
| 612 | // If neither AT nor AT> is specified for an allocatable section, the linker | ||
| 613 | // will set the LMA such that the difference between VMA and LMA for the | ||
| 614 | // section is the same as the preceding output section in the same region | ||
| 615 | // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html | ||
| 616 | if (Ctx->LMAOffset) | ||
| 617 | Ctx->OutSec->LMAOffset = Ctx->LMAOffset(); | ||
| 618 | } | 615 | } |
| 619 | 616 | ||
| 620 | // This function searches for a memory region to place the given output | 617 | // This function searches for a memory region to place the given output |
| ... | @@ -624,9 +621,8 @@ MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) { | ... | @@ -624,9 +621,8 @@ MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) { |
| 624 | // If a memory region name was specified in the output section command, | 621 | // If a memory region name was specified in the output section command, |
| 625 | // then try to find that region first. | 622 | // then try to find that region first. |
| 626 | if (!Sec->MemoryRegionName.empty()) { | 623 | if (!Sec->MemoryRegionName.empty()) { |
| 627 | auto It = MemoryRegions.find(Sec->MemoryRegionName); | 624 | if (MemoryRegion *M = MemoryRegions.lookup(Sec->MemoryRegionName)) |
| 628 | if (It != MemoryRegions.end()) | 625 | return M; |
| 629 | return It->second; | ||
| 630 | error("memory region '" + Sec->MemoryRegionName + "' not declared"); | 626 | error("memory region '" + Sec->MemoryRegionName + "' not declared"); |
| 631 | return nullptr; | 627 | return nullptr; |
| 632 | } | 628 | } |
| ... | @@ -659,16 +655,25 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { | ... | @@ -659,16 +655,25 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { |
| 659 | setDot(Sec->AddrExpr, Sec->Location, false); | 655 | setDot(Sec->AddrExpr, Sec->Location, false); |
| 660 | 656 | ||
| 661 | Ctx->MemRegion = Sec->MemRegion; | 657 | Ctx->MemRegion = Sec->MemRegion; |
| 658 | Ctx->LMARegion = Sec->LMARegion; | ||
| 662 | if (Ctx->MemRegion) | 659 | if (Ctx->MemRegion) |
| 663 | Dot = Ctx->MemRegionOffset[Ctx->MemRegion]; | 660 | Dot = Ctx->MemRegion->CurPos; |
| 664 | |||
| 665 | if (Sec->LMAExpr) { | ||
| 666 | uint64_t D = Dot; | ||
| 667 | Ctx->LMAOffset = [=] { return Sec->LMAExpr().getValue() - D; }; | ||
| 668 | } | ||
| 669 | 661 | ||
| 670 | switchTo(Sec); | 662 | switchTo(Sec); |
| 671 | 663 | ||
| 664 | if (Sec->LMAExpr) | ||
| 665 | Ctx->LMAOffset = Sec->LMAExpr().getValue() - Dot; | ||
| 666 | |||
| 667 | if (MemoryRegion *MR = Sec->LMARegion) | ||
| 668 | Ctx->LMAOffset = MR->CurPos - Dot; | ||
| 669 | |||
| 670 | // If neither AT nor AT> is specified for an allocatable section, the linker | ||
| 671 | // will set the LMA such that the difference between VMA and LMA for the | ||
| 672 | // section is the same as the preceding output section in the same region | ||
| 673 | // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html | ||
| 674 | if (PhdrEntry *L = Ctx->OutSec->PtLoad) | ||
| 675 | L->LMAOffset = Ctx->LMAOffset; | ||
| 676 | |||
| 672 | // The Size previously denoted how many InputSections had been added to this | 677 | // The Size previously denoted how many InputSections had been added to this |
| 673 | // section, and was used for sorting SHF_LINK_ORDER sections. Reset it to | 678 | // section, and was used for sorting SHF_LINK_ORDER sections. Reset it to |
| 674 | // compute the actual size value. | 679 | // compute the actual size value. |
| ... | @@ -689,7 +694,9 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { | ... | @@ -689,7 +694,9 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { |
| 689 | Cmd->Offset = Dot - Ctx->OutSec->Addr; | 694 | Cmd->Offset = Dot - Ctx->OutSec->Addr; |
| 690 | Dot += Cmd->Size; | 695 | Dot += Cmd->Size; |
| 691 | if (Ctx->MemRegion) | 696 | if (Ctx->MemRegion) |
| 692 | Ctx->MemRegionOffset[Ctx->MemRegion] += Cmd->Size; | 697 | Ctx->MemRegion->CurPos += Cmd->Size; |
| 698 | if (Ctx->LMARegion) | ||
| 699 | Ctx->LMARegion->CurPos += Cmd->Size; | ||
| 693 | Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr; | 700 | Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr; |
| 694 | continue; | 701 | continue; |
| 695 | } | 702 | } |
| ... | @@ -788,6 +795,12 @@ void LinkerScript::adjustSectionsAfterSorting() { | ... | @@ -788,6 +795,12 @@ void LinkerScript::adjustSectionsAfterSorting() { |
| 788 | if (auto *Sec = dyn_cast<OutputSection>(Base)) { | 795 | if (auto *Sec = dyn_cast<OutputSection>(Base)) { |
| 789 | if (!Sec->Live) | 796 | if (!Sec->Live) |
| 790 | continue; | 797 | continue; |
| 798 | if (!Sec->LMARegionName.empty()) { | ||
| 799 | if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName)) | ||
| 800 | Sec->LMARegion = M; | ||
| 801 | else | ||
| 802 | error("memory region '" + Sec->LMARegionName + "' not declared"); | ||
| 803 | } | ||
| 791 | Sec->MemRegion = findMemoryRegion(Sec); | 804 | Sec->MemRegion = findMemoryRegion(Sec); |
| 792 | // Handle align (e.g. ".foo : ALIGN(16) { ... }"). | 805 | // Handle align (e.g. ".foo : ALIGN(16) { ... }"). |
| 793 | if (Sec->AlignExpr) | 806 | if (Sec->AlignExpr) |
| ... | @@ -878,8 +891,8 @@ void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) { | ... | @@ -878,8 +891,8 @@ void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) { |
| 878 | 891 | ||
| 879 | LinkerScript::AddressState::AddressState() { | 892 | LinkerScript::AddressState::AddressState() { |
| 880 | for (auto &MRI : Script->MemoryRegions) { | 893 | for (auto &MRI : Script->MemoryRegions) { |
| 881 | const MemoryRegion *MR = MRI.second; | 894 | MemoryRegion *MR = MRI.second; |
| 882 | MemRegionOffset[MR] = MR->Origin; | 895 | MR->CurPos = MR->Origin; |
| 883 | } | 896 | } |
| 884 | } | 897 | } |
| 885 | 898 |
deps/lld/ELF/LinkerScript.h+8-2| ... | @@ -118,11 +118,17 @@ enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; | ... | @@ -118,11 +118,17 @@ enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite }; |
| 118 | // target memory. Instances of the struct are created by parsing the | 118 | // target memory. Instances of the struct are created by parsing the |
| 119 | // MEMORY command. | 119 | // MEMORY command. |
| 120 | struct MemoryRegion { | 120 | struct MemoryRegion { |
| 121 | MemoryRegion(StringRef Name, uint64_t Origin, uint64_t Length, uint32_t Flags, | ||
| 122 | uint32_t NegFlags) | ||
| 123 | : Name(Name), Origin(Origin), Length(Length), Flags(Flags), | ||
| 124 | NegFlags(NegFlags) {} | ||
| 125 | |||
| 121 | std::string Name; | 126 | std::string Name; |
| 122 | uint64_t Origin; | 127 | uint64_t Origin; |
| 123 | uint64_t Length; | 128 | uint64_t Length; |
| 124 | uint32_t Flags; | 129 | uint32_t Flags; |
| 125 | uint32_t NegFlags; | 130 | uint32_t NegFlags; |
| 131 | uint64_t CurPos = 0; | ||
| 126 | }; | 132 | }; |
| 127 | 133 | ||
| 128 | // This struct represents one section match pattern in SECTIONS() command. | 134 | // This struct represents one section match pattern in SECTIONS() command. |
| ... | @@ -200,8 +206,8 @@ class LinkerScript final { | ... | @@ -200,8 +206,8 @@ class LinkerScript final { |
| 200 | uint64_t ThreadBssOffset = 0; | 206 | uint64_t ThreadBssOffset = 0; |
| 201 | OutputSection *OutSec = nullptr; | 207 | OutputSection *OutSec = nullptr; |
| 202 | MemoryRegion *MemRegion = nullptr; | 208 | MemoryRegion *MemRegion = nullptr; |
| 203 | llvm::DenseMap<const MemoryRegion *, uint64_t> MemRegionOffset; | 209 | MemoryRegion *LMARegion = nullptr; |
| 204 | std::function<uint64_t()> LMAOffset; | 210 | uint64_t LMAOffset = 0; |
| 205 | }; | 211 | }; |
| 206 | 212 | ||
| 207 | llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection; | 213 | llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection; |
deps/lld/ELF/Options.td+2-2| ... | @@ -202,6 +202,8 @@ def no_gnu_unique: F<"no-gnu-unique">, | ... | @@ -202,6 +202,8 @@ def no_gnu_unique: F<"no-gnu-unique">, |
| 202 | def no_merge_exidx_entries: F<"no-merge-exidx-entries">, | 202 | def no_merge_exidx_entries: F<"no-merge-exidx-entries">, |
| 203 | HelpText<"Disable merging .ARM.exidx entries">; | 203 | HelpText<"Disable merging .ARM.exidx entries">; |
| 204 | 204 | ||
| 205 | def no_pie: F<"no-pie">, HelpText<"Do not create a position independent executable">; | ||
| 206 | |||
| 205 | def no_threads: F<"no-threads">, | 207 | def no_threads: F<"no-threads">, |
| 206 | HelpText<"Do not run the linker multi-threaded">; | 208 | HelpText<"Do not run the linker multi-threaded">; |
| 207 | 209 | ||
| ... | @@ -211,8 +213,6 @@ def no_whole_archive: F<"no-whole-archive">, | ... | @@ -211,8 +213,6 @@ def no_whole_archive: F<"no-whole-archive">, |
| 211 | def noinhibit_exec: F<"noinhibit-exec">, | 213 | def noinhibit_exec: F<"noinhibit-exec">, |
| 212 | HelpText<"Retain the executable output file whenever it is still usable">; | 214 | HelpText<"Retain the executable output file whenever it is still usable">; |
| 213 | 215 | ||
| 214 | def nopie: F<"nopie">, HelpText<"Do not create a position independent executable">; | ||
| 215 | |||
| 216 | def no_omagic: Flag<["--"], "no-omagic">, MetaVarName<"<magic>">, | 216 | def no_omagic: Flag<["--"], "no-omagic">, MetaVarName<"<magic>">, |
| 217 | HelpText<"Do not set the text data sections to be writable">; | 217 | HelpText<"Do not set the text data sections to be writable">; |
| 218 | 218 |
deps/lld/ELF/OutputSections.h+3-2| ... | @@ -49,7 +49,7 @@ public: | ... | @@ -49,7 +49,7 @@ public: |
| 49 | 49 | ||
| 50 | static bool classof(const BaseCommand *C); | 50 | static bool classof(const BaseCommand *C); |
| 51 | 51 | ||
| 52 | uint64_t getLMA() const { return Addr + LMAOffset; } | 52 | uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; } |
| 53 | template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr); | 53 | template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr); |
| 54 | 54 | ||
| 55 | unsigned SectionIndex; | 55 | unsigned SectionIndex; |
| ... | @@ -78,7 +78,6 @@ public: | ... | @@ -78,7 +78,6 @@ public: |
| 78 | 78 | ||
| 79 | // The following fields correspond to Elf_Shdr members. | 79 | // The following fields correspond to Elf_Shdr members. |
| 80 | uint64_t Offset = 0; | 80 | uint64_t Offset = 0; |
| 81 | uint64_t LMAOffset = 0; | ||
| 82 | uint64_t Addr = 0; | 81 | uint64_t Addr = 0; |
| 83 | uint32_t ShName = 0; | 82 | uint32_t ShName = 0; |
| 84 | 83 | ||
| ... | @@ -89,6 +88,7 @@ public: | ... | @@ -89,6 +88,7 @@ public: |
| 89 | 88 | ||
| 90 | // The following members are normally only used in linker scripts. | 89 | // The following members are normally only used in linker scripts. |
| 91 | MemoryRegion *MemRegion = nullptr; | 90 | MemoryRegion *MemRegion = nullptr; |
| 91 | MemoryRegion *LMARegion = nullptr; | ||
| 92 | Expr AddrExpr; | 92 | Expr AddrExpr; |
| 93 | Expr AlignExpr; | 93 | Expr AlignExpr; |
| 94 | Expr LMAExpr; | 94 | Expr LMAExpr; |
| ... | @@ -99,6 +99,7 @@ public: | ... | @@ -99,6 +99,7 @@ public: |
| 99 | ConstraintKind Constraint = ConstraintKind::NoConstraint; | 99 | ConstraintKind Constraint = ConstraintKind::NoConstraint; |
| 100 | std::string Location; | 100 | std::string Location; |
| 101 | std::string MemoryRegionName; | 101 | std::string MemoryRegionName; |
| 102 | std::string LMARegionName; | ||
| 102 | bool Noload = false; | 103 | bool Noload = false; |
| 103 | 104 | ||
| 104 | template <class ELFT> void finalize(); | 105 | template <class ELFT> void finalize(); |
deps/lld/ELF/ScriptParser.cpp+13-2| ... | @@ -709,6 +709,14 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { | ... | @@ -709,6 +709,14 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { |
| 709 | if (consume(">")) | 709 | if (consume(">")) |
| 710 | Cmd->MemoryRegionName = next(); | 710 | Cmd->MemoryRegionName = next(); |
| 711 | 711 | ||
| 712 | if (consume("AT")) { | ||
| 713 | expect(">"); | ||
| 714 | Cmd->LMARegionName = next(); | ||
| 715 | } | ||
| 716 | |||
| 717 | if (Cmd->LMAExpr && !Cmd->LMARegionName.empty()) | ||
| 718 | error("section can't have both LMA and a load region"); | ||
| 719 | |||
| 712 | Cmd->Phdrs = readOutputSectionPhdrs(); | 720 | Cmd->Phdrs = readOutputSectionPhdrs(); |
| 713 | 721 | ||
| 714 | if (consume("=")) | 722 | if (consume("=")) |
| ... | @@ -922,7 +930,10 @@ ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { | ... | @@ -922,7 +930,10 @@ ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { |
| 922 | 930 | ||
| 923 | StringRef ScriptParser::readParenLiteral() { | 931 | StringRef ScriptParser::readParenLiteral() { |
| 924 | expect("("); | 932 | expect("("); |
| 933 | bool Orig = InExpr; | ||
| 934 | InExpr = false; | ||
| 925 | StringRef Tok = next(); | 935 | StringRef Tok = next(); |
| 936 | InExpr = Orig; | ||
| 926 | expect(")"); | 937 | expect(")"); |
| 927 | return Tok; | 938 | return Tok; |
| 928 | } | 939 | } |
| ... | @@ -1282,8 +1293,8 @@ void ScriptParser::readMemory() { | ... | @@ -1282,8 +1293,8 @@ void ScriptParser::readMemory() { |
| 1282 | // Add the memory region to the region map. | 1293 | // Add the memory region to the region map. |
| 1283 | if (Script->MemoryRegions.count(Name)) | 1294 | if (Script->MemoryRegions.count(Name)) |
| 1284 | setError("region '" + Name + "' already defined"); | 1295 | setError("region '" + Name + "' already defined"); |
| 1285 | MemoryRegion *MR = make<MemoryRegion>(); | 1296 | MemoryRegion *MR = |
| 1286 | *MR = {Name, Origin, Length, Flags, NegFlags}; | 1297 | make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags); |
| 1287 | Script->MemoryRegions[Name] = MR; | 1298 | Script->MemoryRegions[Name] = MR; |
| 1288 | } | 1299 | } |
| 1289 | } | 1300 | } |
deps/lld/ELF/SymbolTable.cpp+2-1| ... | @@ -491,12 +491,13 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File, | ... | @@ -491,12 +491,13 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File, |
| 491 | if (WasInserted || ((S->isUndefined() || S->isLazy()) && | 491 | if (WasInserted || ((S->isUndefined() || S->isLazy()) && |
| 492 | S->getVisibility() == STV_DEFAULT)) { | 492 | S->getVisibility() == STV_DEFAULT)) { |
| 493 | uint8_t Binding = S->Binding; | 493 | uint8_t Binding = S->Binding; |
| 494 | bool WasUndefined = S->isUndefined(); | ||
| 494 | replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other, | 495 | replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other, |
| 495 | Sym.getType(), Sym.st_value, Sym.st_size, | 496 | Sym.getType(), Sym.st_value, Sym.st_size, |
| 496 | Alignment, VerdefIndex); | 497 | Alignment, VerdefIndex); |
| 497 | if (!WasInserted) { | 498 | if (!WasInserted) { |
| 498 | S->Binding = Binding; | 499 | S->Binding = Binding; |
| 499 | if (!S->isWeak() && !Config->GcSections) | 500 | if (!S->isWeak() && !Config->GcSections && WasUndefined) |
| 500 | File.IsNeeded = true; | 501 | File.IsNeeded = true; |
| 501 | } | 502 | } |
| 502 | } | 503 | } |
deps/lld/ELF/Writer.cpp+5-1| ... | @@ -822,6 +822,8 @@ void PhdrEntry::add(OutputSection *Sec) { | ... | @@ -822,6 +822,8 @@ void PhdrEntry::add(OutputSection *Sec) { |
| 822 | p_align = std::max(p_align, Sec->Alignment); | 822 | p_align = std::max(p_align, Sec->Alignment); |
| 823 | if (p_type == PT_LOAD) | 823 | if (p_type == PT_LOAD) |
| 824 | Sec->PtLoad = this; | 824 | Sec->PtLoad = this; |
| 825 | if (Sec->LMAExpr) | ||
| 826 | ASectionHasLMA = true; | ||
| 825 | } | 827 | } |
| 826 | 828 | ||
| 827 | // The beginning and the ending of .rel[a].plt section are marked | 829 | // The beginning and the ending of .rel[a].plt section are marked |
| ... | @@ -1626,7 +1628,9 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { | ... | @@ -1626,7 +1628,9 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { |
| 1626 | // different flags or is loaded at a discontiguous address using AT linker | 1628 | // different flags or is loaded at a discontiguous address using AT linker |
| 1627 | // script command. | 1629 | // script command. |
| 1628 | uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); | 1630 | uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); |
| 1629 | if (Sec->LMAExpr || Flags != NewFlags) { | 1631 | if ((Sec->LMAExpr && Load->ASectionHasLMA) || |
| 1632 | Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { | ||
| 1633 | |||
| 1630 | Load = AddHdr(PT_LOAD, NewFlags); | 1634 | Load = AddHdr(PT_LOAD, NewFlags); |
| 1631 | Flags = NewFlags; | 1635 | Flags = NewFlags; |
| 1632 | } | 1636 | } |
deps/lld/ELF/Writer.h+7| ... | @@ -44,6 +44,13 @@ struct PhdrEntry { | ... | @@ -44,6 +44,13 @@ struct PhdrEntry { |
| 44 | OutputSection *FirstSec = nullptr; | 44 | OutputSection *FirstSec = nullptr; |
| 45 | OutputSection *LastSec = nullptr; | 45 | OutputSection *LastSec = nullptr; |
| 46 | bool HasLMA = false; | 46 | bool HasLMA = false; |
| 47 | |||
| 48 | // True if one of the sections in this program header has a LMA specified via | ||
| 49 | // linker script: AT(addr). We never allow 2 or more sections with LMA in the | ||
| 50 | // same program header. | ||
| 51 | bool ASectionHasLMA = false; | ||
| 52 | |||
| 53 | uint64_t LMAOffset = 0; | ||
| 47 | }; | 54 | }; |
| 48 | 55 | ||
| 49 | void addReservedSymbols(); | 56 | void addReservedSymbols(); |
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp+1| ... | @@ -621,6 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal( | ... | @@ -621,6 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal( |
| 621 | // Fall into llvm_unreachable(). | 621 | // Fall into llvm_unreachable(). |
| 622 | break; | 622 | break; |
| 623 | } | 623 | } |
| 624 | llvm_unreachable("invalid x86_64 Reference Kind"); | ||
| 624 | } | 625 | } |
| 625 | 626 | ||
| 626 | void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, | 627 | void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, |
deps/lld/test/ELF/Inputs/as-needed-lazy.s created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | .global foo | ||
| 2 | foo: | ||
| 3 | nop | ||
deps/lld/test/ELF/Inputs/mips-gp-dips-corrupt-ver.s created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # Source file for mips-gp-dips-corrupt-ver.so | ||
| 2 | # | ||
| 3 | # % cat gpdisp.ver | ||
| 4 | # LLD_1.0.0 { global: foo; }; | ||
| 5 | # | ||
| 6 | # % as mips-gp-dips-corrupt-ver.s -o mips-gp-dips-corrupt-ver.o | ||
| 7 | # % ld -shared -o mips-gp-dips-corrupt-ver.so \ | ||
| 8 | # --version-script gpdisp.ver mips-gp-dips-corrupt-ver.o | ||
| 9 | |||
| 10 | .global foo | ||
| 11 | .text | ||
| 12 | foo: | ||
| 13 | lui $t0, %hi(_gp_disp) | ||
| 14 | addi $t0, $t0, %lo(_gp_disp) | ||
deps/lld/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so created| Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-gp-dips-corrupt-ver.so differ | |||
deps/lld/test/ELF/as-needed-lazy.s created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/as-needed-lazy.s -o %t2.o | ||
| 4 | # RUN: ld.lld %t2.o -o %t2.so -shared | ||
| 5 | # RUN: rm -f %t2.a | ||
| 6 | # RUN: llvm-ar rc %t2.a %t2.o | ||
| 7 | # RUN: ld.lld %t1.o %t2.a --as-needed %t2.so -o %t | ||
| 8 | # RUN: llvm-readobj -d %t | FileCheck %s | ||
| 9 | |||
| 10 | # CHECK-NOT: NEEDED | ||
| 11 | |||
| 12 | .global _start | ||
| 13 | _start: | ||
| 14 | nop | ||
deps/lld/test/ELF/i386-retpoline-nopic.s created+65| ... | @@ -0,0 +1,65 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t1.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/shared.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | // RUN: ld.lld %t1.o %t2.so -o %t.exe -z retpolineplt | ||
| 7 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | ||
| 8 | |||
| 9 | // CHECK: Disassembly of section .plt: | ||
| 10 | // CHECK-NEXT: .plt: | ||
| 11 | // CHECK-NEXT: 11010: ff 35 04 20 01 00 pushl 73732 | ||
| 12 | // CHECK-NEXT: 11016: 50 pushl %eax | ||
| 13 | // CHECK-NEXT: 11017: a1 08 20 01 00 movl 73736, %eax | ||
| 14 | // CHECK-NEXT: 1101c: e8 0f 00 00 00 calll 15 <.plt+0x20> | ||
| 15 | // CHECK-NEXT: 11021: f3 90 pause | ||
| 16 | // CHECK-NEXT: 11023: 0f ae e8 lfence | ||
| 17 | // CHECK-NEXT: 11026: eb f9 jmp -7 <.plt+0x11> | ||
| 18 | // CHECK-NEXT: 11028: cc int3 | ||
| 19 | // CHECK-NEXT: 11029: cc int3 | ||
| 20 | // CHECK-NEXT: 1102a: cc int3 | ||
| 21 | // CHECK-NEXT: 1102b: cc int3 | ||
| 22 | // CHECK-NEXT: 1102c: cc int3 | ||
| 23 | // CHECK-NEXT: 1102d: cc int3 | ||
| 24 | // CHECK-NEXT: 1102e: cc int3 | ||
| 25 | // CHECK-NEXT: 1102f: cc int3 | ||
| 26 | // CHECK-NEXT: 11030: 89 0c 24 movl %ecx, (%esp) | ||
| 27 | // CHECK-NEXT: 11033: 8b 4c 24 04 movl 4(%esp), %ecx | ||
| 28 | // CHECK-NEXT: 11037: 89 44 24 04 movl %eax, 4(%esp) | ||
| 29 | // CHECK-NEXT: 1103b: 89 c8 movl %ecx, %eax | ||
| 30 | // CHECK-NEXT: 1103d: 59 popl %ecx | ||
| 31 | // CHECK-NEXT: 1103e: c3 retl | ||
| 32 | // CHECK-NEXT: 1103f: cc int3 | ||
| 33 | // CHECK-NEXT: 11040: 50 pushl %eax | ||
| 34 | // CHECK-NEXT: 11041: a1 0c 20 01 00 movl 73740, %eax | ||
| 35 | // CHECK-NEXT: 11046: e8 e5 ff ff ff calll -27 <.plt+0x20> | ||
| 36 | // CHECK-NEXT: 1104b: e9 d1 ff ff ff jmp -47 <.plt+0x11> | ||
| 37 | // CHECK-NEXT: 11050: 68 00 00 00 00 pushl $0 | ||
| 38 | // CHECK-NEXT: 11055: e9 b6 ff ff ff jmp -74 <.plt> | ||
| 39 | // CHECK-NEXT: 1105a: cc int3 | ||
| 40 | // CHECK-NEXT: 1105b: cc int3 | ||
| 41 | // CHECK-NEXT: 1105c: cc int3 | ||
| 42 | // CHECK-NEXT: 1105d: cc int3 | ||
| 43 | // CHECK-NEXT: 1105e: cc int3 | ||
| 44 | // CHECK-NEXT: 1105f: cc int3 | ||
| 45 | // CHECK-NEXT: 11060: 50 pushl %eax | ||
| 46 | // CHECK-NEXT: 11061: a1 10 20 01 00 movl 73744, %eax | ||
| 47 | // CHECK-NEXT: 11066: e8 c5 ff ff ff calll -59 <.plt+0x20> | ||
| 48 | // CHECK-NEXT: 1106b: e9 b1 ff ff ff jmp -79 <.plt+0x11> | ||
| 49 | // CHECK-NEXT: 11070: 68 08 00 00 00 pushl $8 | ||
| 50 | // CHECK-NEXT: 11075: e9 96 ff ff ff jmp -106 <.plt> | ||
| 51 | // CHECK-NEXT: 1107a: cc int3 | ||
| 52 | // CHECK-NEXT: 1107b: cc int3 | ||
| 53 | // CHECK-NEXT: 1107c: cc int3 | ||
| 54 | // CHECK-NEXT: 1107d: cc int3 | ||
| 55 | // CHECK-NEXT: 1107e: cc int3 | ||
| 56 | // CHECK-NEXT: 1107f: cc int3 | ||
| 57 | |||
| 58 | // CHECK: Contents of section .got.plt: | ||
| 59 | // CHECK-NEXT: 00300100 00000000 00000000 50100100 | ||
| 60 | // CHECK-NEXT: 70100100 | ||
| 61 | |||
| 62 | .global _start | ||
| 63 | _start: | ||
| 64 | jmp bar@PLT | ||
| 65 | jmp zed@PLT | ||
deps/lld/test/ELF/i386-retpoline-pic.s created+62| ... | @@ -0,0 +1,62 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux -position-independent %s -o %t1.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux -position-independent %p/Inputs/shared.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | // RUN: ld.lld %t1.o %t2.so -o %t.exe -z retpolineplt -pie | ||
| 7 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | ||
| 8 | |||
| 9 | // CHECK: Disassembly of section .plt: | ||
| 10 | // CHECK-NEXT: .plt: | ||
| 11 | // CHECK-NEXT: 1010: ff b3 04 20 00 00 pushl 8196(%ebx) | ||
| 12 | // CHECK-NEXT: 1016: 50 pushl %eax | ||
| 13 | // CHECK-NEXT: 1017: 8b 83 08 20 00 00 movl 8200(%ebx), %eax | ||
| 14 | // CHECK-NEXT: 101d: e8 0e 00 00 00 calll 14 <.plt+0x20> | ||
| 15 | // CHECK-NEXT: 1022: f3 90 pause | ||
| 16 | // CHECK-NEXT: 1024: 0f ae e8 lfence | ||
| 17 | // CHECK-NEXT: 1027: eb f9 jmp -7 <.plt+0x12> | ||
| 18 | // CHECK-NEXT: 1029: cc int3 | ||
| 19 | // CHECK-NEXT: 102a: cc int3 | ||
| 20 | // CHECK-NEXT: 102b: cc int3 | ||
| 21 | // CHECK-NEXT: 102c: cc int3 | ||
| 22 | // CHECK-NEXT: 102d: cc int3 | ||
| 23 | // CHECK-NEXT: 102e: cc int3 | ||
| 24 | // CHECK-NEXT: 102f: cc int3 | ||
| 25 | // CHECK-NEXT: 1030: 89 0c 24 movl %ecx, (%esp) | ||
| 26 | // CHECK-NEXT: 1033: 8b 4c 24 04 movl 4(%esp), %ecx | ||
| 27 | // CHECK-NEXT: 1037: 89 44 24 04 movl %eax, 4(%esp) | ||
| 28 | // CHECK-NEXT: 103b: 89 c8 movl %ecx, %eax | ||
| 29 | // CHECK-NEXT: 103d: 59 popl %ecx | ||
| 30 | // CHECK-NEXT: 103e: c3 retl | ||
| 31 | // CHECK-NEXT: 103f: cc int3 | ||
| 32 | // CHECK-NEXT: 1040: 50 pushl %eax | ||
| 33 | // CHECK-NEXT: 1041: 8b 83 0c 20 00 00 movl 8204(%ebx), %eax | ||
| 34 | // CHECK-NEXT: 1047: e8 e4 ff ff ff calll -28 <.plt+0x20> | ||
| 35 | // CHECK-NEXT: 104c: e9 d1 ff ff ff jmp -47 <.plt+0x12> | ||
| 36 | // CHECK-NEXT: 1051: 68 00 00 00 00 pushl $0 | ||
| 37 | // CHECK-NEXT: 1056: e9 b5 ff ff ff jmp -75 <.plt> | ||
| 38 | // CHECK-NEXT: 105b: cc int3 | ||
| 39 | // CHECK-NEXT: 105c: cc int3 | ||
| 40 | // CHECK-NEXT: 105d: cc int3 | ||
| 41 | // CHECK-NEXT: 105e: cc int3 | ||
| 42 | // CHECK-NEXT: 105f: cc int3 | ||
| 43 | // CHECK-NEXT: 1060: 50 pushl %eax | ||
| 44 | // CHECK-NEXT: 1061: 8b 83 10 20 00 00 movl 8208(%ebx), %eax | ||
| 45 | // CHECK-NEXT: 1067: e8 c4 ff ff ff calll -60 <.plt+0x20> | ||
| 46 | // CHECK-NEXT: 106c: e9 b1 ff ff ff jmp -79 <.plt+0x12> | ||
| 47 | // CHECK-NEXT: 1071: 68 08 00 00 00 pushl $8 | ||
| 48 | // CHECK-NEXT: 1076: e9 95 ff ff ff jmp -107 <.plt> | ||
| 49 | // CHECK-NEXT: 107b: cc int3 | ||
| 50 | // CHECK-NEXT: 107c: cc int3 | ||
| 51 | // CHECK-NEXT: 107d: cc int3 | ||
| 52 | // CHECK-NEXT: 107e: cc int3 | ||
| 53 | // CHECK-NEXT: 107f: cc int3 | ||
| 54 | |||
| 55 | // CHECK: Contents of section .got.plt: | ||
| 56 | // CHECK-NEXT: 2000 00300000 00000000 00000000 51100000 | ||
| 57 | // CHECK-NEXT: 2010 71100000 | ||
| 58 | |||
| 59 | .global _start | ||
| 60 | _start: | ||
| 61 | jmp bar@PLT | ||
| 62 | jmp zed@PLT | ||
deps/lld/test/ELF/linkerscript/at-self-reference.s created+63| ... | @@ -0,0 +1,63 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: . = 0x1000; \ | ||
| 5 | # RUN: .aaa : AT(ADDR(.aaa)) { *(.aaa) } \ | ||
| 6 | # RUN: .bbb : AT(ADDR(.bbb)) { *(.bbb) } \ | ||
| 7 | # RUN: }" > %t.script | ||
| 8 | # RUN: ld.lld %t --script %t.script -o %t2 | ||
| 9 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s | ||
| 10 | |||
| 11 | # CHECK: ProgramHeaders [ | ||
| 12 | # CHECK-NEXT: ProgramHeader { | ||
| 13 | # CHECK-NEXT: Type: PT_LOAD (0x1) | ||
| 14 | # CHECK-NEXT: Offset: 0x1000 | ||
| 15 | # CHECK-NEXT: VirtualAddress: 0x1000 | ||
| 16 | # CHECK-NEXT: PhysicalAddress: 0x1000 | ||
| 17 | # CHECK-NEXT: FileSize: 3 | ||
| 18 | # CHECK-NEXT: MemSize: 3 | ||
| 19 | # CHECK-NEXT: Flags [ (0x5) | ||
| 20 | # CHECK-NEXT: PF_R (0x4) | ||
| 21 | # CHECK-NEXT: PF_X (0x1) | ||
| 22 | # CHECK-NEXT: ] | ||
| 23 | # CHECK-NEXT: Alignment: 4096 | ||
| 24 | # CHECK-NEXT: } | ||
| 25 | # CHECK-NEXT: ProgramHeader { | ||
| 26 | # CHECK-NEXT: Type: PT_LOAD (0x1) | ||
| 27 | # CHECK-NEXT: Offset: 0x1008 | ||
| 28 | # CHECK-NEXT: VirtualAddress: 0x1008 | ||
| 29 | # CHECK-NEXT: PhysicalAddress: 0x1008 | ||
| 30 | # CHECK-NEXT: FileSize: 9 | ||
| 31 | # CHECK-NEXT: MemSize: 9 | ||
| 32 | # CHECK-NEXT: Flags [ (0x5) | ||
| 33 | # CHECK-NEXT: PF_R (0x4) | ||
| 34 | # CHECK-NEXT: PF_X (0x1) | ||
| 35 | # CHECK-NEXT: ] | ||
| 36 | # CHECK-NEXT: Alignment: 4096 | ||
| 37 | # CHECK-NEXT: } | ||
| 38 | # CHECK-NEXT: ProgramHeader { | ||
| 39 | # CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) | ||
| 40 | # CHECK-NEXT: Offset: 0x0 | ||
| 41 | # CHECK-NEXT: VirtualAddress: 0x0 | ||
| 42 | # CHECK-NEXT: PhysicalAddress: 0x0 | ||
| 43 | # CHECK-NEXT: FileSize: 0 | ||
| 44 | # CHECK-NEXT: MemSize: 0 | ||
| 45 | # CHECK-NEXT: Flags [ (0x6) | ||
| 46 | # CHECK-NEXT: PF_R (0x4) | ||
| 47 | # CHECK-NEXT: PF_W (0x2) | ||
| 48 | # CHECK-NEXT: ] | ||
| 49 | # CHECK-NEXT: Alignment: 0 | ||
| 50 | # CHECK-NEXT: } | ||
| 51 | # CHECK-NEXT:] | ||
| 52 | |||
| 53 | .global _start | ||
| 54 | _start: | ||
| 55 | nop | ||
| 56 | |||
| 57 | |||
| 58 | .section .aaa, "a" | ||
| 59 | .asciz "aa" | ||
| 60 | |||
| 61 | .section .bbb, "a" | ||
| 62 | .align 8 | ||
| 63 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/at2.s created+81| ... | @@ -0,0 +1,81 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: echo "MEMORY { \ | ||
| 4 | # RUN: AX (ax) : ORIGIN = 0x2000, LENGTH = 0x100 \ | ||
| 5 | # RUN: AW (aw) : ORIGIN = 0x3000, LENGTH = 0x100 \ | ||
| 6 | # RUN: FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x100 \ | ||
| 7 | # RUN: RAM (aw) : ORIGIN = 0x7000, LENGTH = 0x100 } \ | ||
| 8 | # RUN: SECTIONS { \ | ||
| 9 | # RUN: .foo1 : { *(.foo1) } > AX AT>FLASH \ | ||
| 10 | # RUN: .foo2 : { *(.foo2) } > AX \ | ||
| 11 | # RUN: .bar1 : { *(.bar1) } > AW AT> RAM \ | ||
| 12 | # RUN: .bar2 : { *(.bar2) } > AW AT > RAM \ | ||
| 13 | # RUN: .bar3 : { *(.bar3) } > AW AT >RAM \ | ||
| 14 | # RUN: }" > %t.script | ||
| 15 | # RUN: ld.lld %t --script %t.script -o %t2 | ||
| 16 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s | ||
| 17 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=SECTIONS | ||
| 18 | |||
| 19 | # CHECK: ProgramHeaders [ | ||
| 20 | # CHECK-NEXT: ProgramHeader { | ||
| 21 | # CHECK-NEXT: Type: PT_LOAD | ||
| 22 | # CHECK-NEXT: Offset: 0x1000 | ||
| 23 | # CHECK-NEXT: VirtualAddress: 0x2000 | ||
| 24 | # CHECK-NEXT: PhysicalAddress: 0x6000 | ||
| 25 | # CHECK-NEXT: FileSize: 16 | ||
| 26 | # CHECK-NEXT: MemSize: 16 | ||
| 27 | # CHECK-NEXT: Flags [ | ||
| 28 | # CHECK-NEXT: PF_R | ||
| 29 | # CHECK-NEXT: PF_X | ||
| 30 | # CHECK-NEXT: ] | ||
| 31 | # CHECK-NEXT: Alignment: | ||
| 32 | # CHECK-NEXT: } | ||
| 33 | # CHECK-NEXT: ProgramHeader { | ||
| 34 | # CHECK-NEXT: Type: PT_LOAD | ||
| 35 | # CHECK-NEXT: Offset: 0x2000 | ||
| 36 | # CHECK-NEXT: VirtualAddress: 0x3000 | ||
| 37 | # CHECK-NEXT: PhysicalAddress: 0x7000 | ||
| 38 | # CHECK-NEXT: FileSize: 24 | ||
| 39 | # CHECK-NEXT: MemSize: 24 | ||
| 40 | # CHECK-NEXT: Flags [ | ||
| 41 | # CHECK-NEXT: PF_R | ||
| 42 | # CHECK-NEXT: PF_W | ||
| 43 | # CHECK-NEXT: ] | ||
| 44 | # CHECK-NEXT: Alignment: 4096 | ||
| 45 | # CHECK-NEXT: } | ||
| 46 | |||
| 47 | # SECTIONS: Sections: | ||
| 48 | # SECTIONS-NEXT: Idx Name Size Address | ||
| 49 | # SECTIONS-NEXT: 0 00000000 0000000000000000 | ||
| 50 | # SECTIONS-NEXT: 1 .foo1 00000008 0000000000002000 | ||
| 51 | # SECTIONS-NEXT: 2 .foo2 00000008 0000000000002008 | ||
| 52 | # SECTIONS-NEXT: 3 .text 00000000 0000000000002010 | ||
| 53 | # SECTIONS-NEXT: 4 .bar1 00000008 0000000000003000 | ||
| 54 | # SECTIONS-NEXT: 5 .bar2 00000008 0000000000003008 | ||
| 55 | # SECTIONS-NEXT: 6 .bar3 00000008 0000000000003010 | ||
| 56 | |||
| 57 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 58 | # RUN: echo "MEMORY { \ | ||
| 59 | # RUN: FLASH (ax) : ORIGIN = 0x2000, LENGTH = 0x100 \ | ||
| 60 | # RUN: RAM (aw) : ORIGIN = 0x5000, LENGTH = 0x100 } \ | ||
| 61 | # RUN: SECTIONS { \ | ||
| 62 | # RUN: .foo1 : AT(0x500) { *(.foo1) } > FLASH AT>FLASH \ | ||
| 63 | # RUN: }" > %t2.script | ||
| 64 | # RUN: not ld.lld %t --script %t2.script -o %t2 2>&1 | \ | ||
| 65 | # RUN: FileCheck %s --check-prefix=ERR | ||
| 66 | # ERR: error: section can't have both LMA and a load region | ||
| 67 | |||
| 68 | .section .foo1, "ax" | ||
| 69 | .quad 0 | ||
| 70 | |||
| 71 | .section .foo2, "ax" | ||
| 72 | .quad 0 | ||
| 73 | |||
| 74 | .section .bar1, "aw" | ||
| 75 | .quad 0 | ||
| 76 | |||
| 77 | .section .bar2, "aw" | ||
| 78 | .quad 0 | ||
| 79 | |||
| 80 | .section .bar3, "aw" | ||
| 81 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/at3.s created+38| ... | @@ -0,0 +1,38 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "MEMORY { \ | ||
| 4 | # RUN: FOO (ax) : ORIGIN = 0x1000, LENGTH = 0x100 \ | ||
| 5 | # RUN: BAR (ax) : ORIGIN = 0x2000, LENGTH = 0x100 \ | ||
| 6 | # RUN: ZED (ax) : ORIGIN = 0x3000, LENGTH = 0x100 \ | ||
| 7 | # RUN: FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x200 \ | ||
| 8 | # RUN: } \ | ||
| 9 | # RUN: SECTIONS { \ | ||
| 10 | # RUN: .foo1 : { *(.foo1) } > FOO AT>FLASH \ | ||
| 11 | # RUN: .foo2 : { *(.foo2) BYTE(0x42) } > BAR AT>FLASH \ | ||
| 12 | # RUN: .foo3 : { *(.foo3) } > ZED AT>FLASH \ | ||
| 13 | # RUN: }" > %t.script | ||
| 14 | # RUN: ld.lld %t.o --script %t.script -o %t | ||
| 15 | # RUN: llvm-readelf -sections -program-headers %t | FileCheck %s | ||
| 16 | |||
| 17 | # CHECK: .foo1 PROGBITS 0000000000001000 001000 | ||
| 18 | # CHECK: .foo2 PROGBITS 0000000000002000 002000 | ||
| 19 | # CHECK: .foo3 PROGBITS 0000000000003000 003000 | ||
| 20 | |||
| 21 | # CHECK: Program Headers: | ||
| 22 | # CHECK-NOT: LOAD | ||
| 23 | |||
| 24 | # CHECK: Type Offset VirtAddr PhysAddr | ||
| 25 | # CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000006000 | ||
| 26 | # CHECK-NEXT: LOAD 0x002000 0x0000000000002000 0x0000000000006008 | ||
| 27 | # CHECK-NEXT: LOAD 0x003000 0x0000000000003000 0x0000000000006011 | ||
| 28 | |||
| 29 | # CHECK-NOT: LOAD | ||
| 30 | |||
| 31 | .section .foo1, "a" | ||
| 32 | .quad 0 | ||
| 33 | |||
| 34 | .section .foo2, "ax" | ||
| 35 | .quad 0 | ||
| 36 | |||
| 37 | .section .foo3, "ax" | ||
| 38 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/merge-header-load.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: . = 0xffffffff80000200; \ | ||
| 5 | # RUN: .text : AT (0x4200) { *(.text) } \ | ||
| 6 | # RUN: }" > %t.script | ||
| 7 | # RUN: ld.lld %t.o --script %t.script -o %t | ||
| 8 | # RUN: llvm-readelf -program-headers %t | FileCheck %s | ||
| 9 | |||
| 10 | # Test that we put the header in the first PT_LOAD. We used to create a PT_LOAD | ||
| 11 | # just for it and it would have a different virtual to physical address delta. | ||
| 12 | |||
| 13 | # CHECK: Program Headers: | ||
| 14 | # CHECK: Type Offset VirtAddr PhysAddr | ||
| 15 | # CHECK-NEXT: PHDR 0x000040 0xffffffff80000040 0x0000000000004040 | ||
| 16 | # CHECK-NEXT: LOAD 0x000000 0xffffffff80000000 0x0000000000004000 | ||
| 17 | # CHECK-NOT: LOAD | ||
| 18 | |||
| 19 | .global _start | ||
| 20 | _start: | ||
| 21 | nop | ||
deps/lld/test/ELF/linkerscript/parse-section-in-addr.s created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { \ | ||
| 5 | # RUN: .foo-bar : AT(ADDR(.foo-bar)) { *(.text) } \ | ||
| 6 | # RUN: }" > %t.script | ||
| 7 | # RUN: ld.lld -o %t.so --script %t.script %t.o -shared | ||
| 8 | # RUN: llvm-readelf -S %t.so | FileCheck %s | ||
| 9 | |||
| 10 | # CHECK: .foo-bar | ||
deps/lld/test/ELF/mips-gp-disp-ver.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # MIPS BFD linker puts _gp_disp symbol into DSO files and assigns zero | ||
| 2 | # version definition index to it. This value means 'unversioned local symbol' | ||
| 3 | # while _gp_disp is a section global symbol. We have to handle this bug | ||
| 4 | # in the LLD because BFD linker is used for building MIPS toolchain | ||
| 5 | # libraries. This test checks such handling. | ||
| 6 | |||
| 7 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | ||
| 8 | # RUN: ld.lld %t.o %S/Inputs/mips-gp-dips-corrupt-ver.so | ||
| 9 | |||
| 10 | # REQUIRES: mips | ||
| 11 | |||
| 12 | .global __start | ||
| 13 | .text | ||
| 14 | __start: | ||
| 15 | lw $t0, %got(foo)($gp) | ||
deps/lld/test/ELF/pie.s+1-1| ... | @@ -48,7 +48,7 @@ | ... | @@ -48,7 +48,7 @@ |
| 48 | # CHECK: Type: PT_DYNAMIC | 48 | # CHECK: Type: PT_DYNAMIC |
| 49 | 49 | ||
| 50 | ## Check -nopie | 50 | ## Check -nopie |
| 51 | # RUN: ld.lld -nopie %t1.o -o %t2 | 51 | # RUN: ld.lld -no-pie %t1.o -o %t2 |
| 52 | # RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE | 52 | # RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE |
| 53 | # NOPIE-NOT: Type: SharedObject | 53 | # NOPIE-NOT: Type: SharedObject |
| 54 | 54 |
deps/lld/test/ELF/x86-64-retpoline-znow.s created+53| ... | @@ -0,0 +1,53 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | // RUN: ld.lld -shared %t1.o %t2.so -o %t.exe -z retpolineplt -z now | ||
| 7 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | ||
| 8 | |||
| 9 | // CHECK: Disassembly of section .plt: | ||
| 10 | // CHECK-NEXT: .plt: | ||
| 11 | // CHECK-NEXT: 1010:	e8 0b 00 00 00 	callq	11 <.plt+0x10> | ||
| 12 | // CHECK-NEXT: 1015:	f3 90 	pause | ||
| 13 | // CHECK-NEXT: 1017:	0f ae e8 	lfence | ||
| 14 | // CHECK-NEXT: 101a:	eb f9 	jmp	-7 <.plt+0x5> | ||
| 15 | // CHECK-NEXT: 101c:	cc 	int3 | ||
| 16 | // CHECK-NEXT: 101d:	cc 	int3 | ||
| 17 | // CHECK-NEXT: 101e:	cc 	int3 | ||
| 18 | // CHECK-NEXT: 101f:	cc 	int3 | ||
| 19 | // CHECK-NEXT: 1020:	4c 89 1c 24 	movq	%r11, (%rsp) | ||
| 20 | // CHECK-NEXT: 1024:	c3 	retq | ||
| 21 | // CHECK-NEXT: 1025:	cc 	int3 | ||
| 22 | // CHECK-NEXT: 1026:	cc 	int3 | ||
| 23 | // CHECK-NEXT: 1027:	cc 	int3 | ||
| 24 | // CHECK-NEXT: 1028:	cc 	int3 | ||
| 25 | // CHECK-NEXT: 1029:	cc 	int3 | ||
| 26 | // CHECK-NEXT: 102a:	cc 	int3 | ||
| 27 | // CHECK-NEXT: 102b:	cc 	int3 | ||
| 28 | // CHECK-NEXT: 102c:	cc 	int3 | ||
| 29 | // CHECK-NEXT: 102d:	cc 	int3 | ||
| 30 | // CHECK-NEXT: 102e:	cc 	int3 | ||
| 31 | // CHECK-NEXT: 102f:	cc 	int3 | ||
| 32 | // CHECK-NEXT: 1030:	4c 8b 1d c1 10 00 00 	movq	4289(%rip), %r11 | ||
| 33 | // CHECK-NEXT: 1037:	e9 d4 ff ff ff 	jmp	-44 <.plt> | ||
| 34 | // CHECK-NEXT: 103c:	cc 	int3 | ||
| 35 | // CHECK-NEXT: 103d:	cc 	int3 | ||
| 36 | // CHECK-NEXT: 103e:	cc 	int3 | ||
| 37 | // CHECK-NEXT: 103f:	cc 	int3 | ||
| 38 | // CHECK-NEXT: 1040:	4c 8b 1d b9 10 00 00 	movq	4281(%rip), %r11 | ||
| 39 | // CHECK-NEXT: 1047:	e9 c4 ff ff ff 	jmp	-60 <.plt> | ||
| 40 | // CHECK-NEXT: 104c:	cc 	int3 | ||
| 41 | // CHECK-NEXT: 104d:	cc 	int3 | ||
| 42 | // CHECK-NEXT: 104e:	cc 	int3 | ||
| 43 | // CHECK-NEXT: 104f:	cc 	int3 | ||
| 44 | |||
| 45 | // CHECK: Contents of section .got.plt: | ||
| 46 | // CHECK-NEXT: 20e0 00200000 00000000 00000000 00000000 | ||
| 47 | // CHECK-NEXT: 20f0 00000000 00000000 00000000 00000000 | ||
| 48 | // CHECK-NEXT: 2100 00000000 00000000 | ||
| 49 | |||
| 50 | .global _start | ||
| 51 | _start: | ||
| 52 | jmp bar@PLT | ||
| 53 | jmp zed@PLT | ||
deps/lld/test/ELF/x86-64-retpoline.s created+66| ... | @@ -0,0 +1,66 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | // RUN: ld.lld -shared %t1.o %t2.so -o %t.exe -z retpolineplt | ||
| 7 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | ||
| 8 | |||
| 9 | // CHECK: Disassembly of section .plt: | ||
| 10 | // CHECK-NEXT: .plt: | ||
| 11 | // CHECK-NEXT: 1010: ff 35 f2 0f 00 00 pushq 4082(%rip) | ||
| 12 | // CHECK-NEXT: 1016: 4c 8b 1d f3 0f 00 00 movq 4083(%rip), %r11 | ||
| 13 | // CHECK-NEXT: 101d: e8 0e 00 00 00 callq 14 <.plt+0x20> | ||
| 14 | // CHECK-NEXT: 1022: f3 90 pause | ||
| 15 | // CHECK-NEXT: 1024: 0f ae e8 lfence | ||
| 16 | // CHECK-NEXT: 1027: eb f9 jmp -7 <.plt+0x12> | ||
| 17 | // CHECK-NEXT: 1029: cc int3 | ||
| 18 | // CHECK-NEXT: 102a: cc int3 | ||
| 19 | // CHECK-NEXT: 102b: cc int3 | ||
| 20 | // CHECK-NEXT: 102c: cc int3 | ||
| 21 | // CHECK-NEXT: 102d: cc int3 | ||
| 22 | // CHECK-NEXT: 102e: cc int3 | ||
| 23 | // CHECK-NEXT: 102f: cc int3 | ||
| 24 | // CHECK-NEXT: 1030: 4c 89 1c 24 movq %r11, (%rsp) | ||
| 25 | // CHECK-NEXT: 1034: c3 retq | ||
| 26 | // CHECK-NEXT: 1035: cc int3 | ||
| 27 | // CHECK-NEXT: 1036: cc int3 | ||
| 28 | // CHECK-NEXT: 1037: cc int3 | ||
| 29 | // CHECK-NEXT: 1038: cc int3 | ||
| 30 | // CHECK-NEXT: 1039: cc int3 | ||
| 31 | // CHECK-NEXT: 103a: cc int3 | ||
| 32 | // CHECK-NEXT: 103b: cc int3 | ||
| 33 | // CHECK-NEXT: 103c: cc int3 | ||
| 34 | // CHECK-NEXT: 103d: cc int3 | ||
| 35 | // CHECK-NEXT: 103e: cc int3 | ||
| 36 | // CHECK-NEXT: 103f: cc int3 | ||
| 37 | // CHECK-NEXT: 1040: 4c 8b 1d d1 0f 00 00 movq 4049(%rip), %r11 | ||
| 38 | // CHECK-NEXT: 1047: e8 e4 ff ff ff callq -28 <.plt+0x20> | ||
| 39 | // CHECK-NEXT: 104c: e9 d1 ff ff ff jmp -47 <.plt+0x12> | ||
| 40 | // CHECK-NEXT: 1051: 68 00 00 00 00 pushq $0 | ||
| 41 | // CHECK-NEXT: 1056: e9 b5 ff ff ff jmp -75 <.plt> | ||
| 42 | // CHECK-NEXT: 105b: cc int3 | ||
| 43 | // CHECK-NEXT: 105c: cc int3 | ||
| 44 | // CHECK-NEXT: 105d: cc int3 | ||
| 45 | // CHECK-NEXT: 105e: cc int3 | ||
| 46 | // CHECK-NEXT: 105f: cc int3 | ||
| 47 | // CHECK-NEXT: 1060: 4c 8b 1d b9 0f 00 00 movq 4025(%rip), %r11 | ||
| 48 | // CHECK-NEXT: 1067: e8 c4 ff ff ff callq -60 <.plt+0x20> | ||
| 49 | // CHECK-NEXT: 106c: e9 b1 ff ff ff jmp -79 <.plt+0x12> | ||
| 50 | // CHECK-NEXT: 1071: 68 01 00 00 00 pushq $1 | ||
| 51 | // CHECK-NEXT: 1076: e9 95 ff ff ff jmp -107 <.plt> | ||
| 52 | // CHECK-NEXT: 107b: cc int3 | ||
| 53 | // CHECK-NEXT: 107c: cc int3 | ||
| 54 | // CHECK-NEXT: 107d: cc int3 | ||
| 55 | // CHECK-NEXT: 107e: cc int3 | ||
| 56 | // CHECK-NEXT: 107f: cc int3 | ||
| 57 | |||
| 58 | // CHECK: Contents of section .got.plt: | ||
| 59 | // CHECK-NEXT: 2000 00300000 00000000 00000000 00000000 | ||
| 60 | // CHECK-NEXT: 2010 00000000 00000000 51100000 00000000 | ||
| 61 | // CHECK-NEXT: 2020 71100000 00000000 | ||
| 62 | |||
| 63 | .global _start | ||
| 64 | _start: | ||
| 65 | jmp bar@PLT | ||
| 66 | jmp zed@PLT | ||