OLD | NEW |
1 //===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===// | 1 //===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file assembles .s files and emits ELF .o object files. | 10 // This file assembles .s files and emits ELF .o object files. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "llvm/MC/MCELFStreamer.h" | 14 #include "llvm/MC/MCELFStreamer.h" |
15 #include "llvm/ADT/STLExtras.h" | 15 #include "llvm/ADT/STLExtras.h" |
16 #include "llvm/ADT/SmallPtrSet.h" | 16 #include "llvm/ADT/SmallPtrSet.h" |
17 #include "llvm/MC/MCAsmBackend.h" | 17 #include "llvm/MC/MCAsmBackend.h" |
| 18 #include "llvm/MC/MCAsmLayout.h" |
18 #include "llvm/MC/MCAsmInfo.h" | 19 #include "llvm/MC/MCAsmInfo.h" |
19 #include "llvm/MC/MCAssembler.h" | 20 #include "llvm/MC/MCAssembler.h" |
20 #include "llvm/MC/MCCodeEmitter.h" | 21 #include "llvm/MC/MCCodeEmitter.h" |
21 #include "llvm/MC/MCContext.h" | 22 #include "llvm/MC/MCContext.h" |
22 #include "llvm/MC/MCELF.h" | 23 #include "llvm/MC/MCELF.h" |
23 #include "llvm/MC/MCELFSymbolFlags.h" | 24 #include "llvm/MC/MCELFSymbolFlags.h" |
24 #include "llvm/MC/MCExpr.h" | 25 #include "llvm/MC/MCExpr.h" |
25 #include "llvm/MC/MCInst.h" | 26 #include "llvm/MC/MCInst.h" |
26 #include "llvm/MC/MCObjectFileInfo.h" | 27 #include "llvm/MC/MCObjectFileInfo.h" |
27 #include "llvm/MC/MCObjectStreamer.h" | 28 #include "llvm/MC/MCObjectStreamer.h" |
28 #include "llvm/MC/MCSection.h" | 29 #include "llvm/MC/MCSection.h" |
29 #include "llvm/MC/MCSectionELF.h" | 30 #include "llvm/MC/MCSectionELF.h" |
30 #include "llvm/MC/MCSymbol.h" | 31 #include "llvm/MC/MCSymbol.h" |
31 #include "llvm/MC/MCValue.h" | 32 #include "llvm/MC/MCValue.h" |
32 #include "llvm/Support/Debug.h" | 33 #include "llvm/Support/Debug.h" |
33 #include "llvm/Support/ELF.h" | 34 #include "llvm/Support/ELF.h" |
34 #include "llvm/Support/ErrorHandling.h" | 35 #include "llvm/Support/ErrorHandling.h" |
35 #include "llvm/Support/raw_ostream.h" | 36 #include "llvm/Support/raw_ostream.h" |
36 | 37 |
37 using namespace llvm; | 38 using namespace llvm; |
38 | 39 |
39 MCELFStreamer::~MCELFStreamer() { | 40 MCELFStreamer::~MCELFStreamer() { |
40 } | 41 } |
41 | 42 |
| 43 void MCELFStreamer::mergeFragment(MCDataFragment *DF, |
| 44 MCEncodedFragmentWithFixups *EF) { |
| 45 MCAssembler &Assembler = getAssembler(); |
| 46 |
| 47 if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) { |
| 48 uint64_t FSize = EF->getContents().size(); |
| 49 |
| 50 if (FSize > Assembler.getBundleAlignSize()) |
| 51 report_fatal_error("Fragment can't be larger than a bundle size"); |
| 52 |
| 53 uint64_t RequiredBundlePadding = computeBundlePadding( |
| 54 Assembler, EF, DF->getContents().size(), FSize); |
| 55 |
| 56 if (RequiredBundlePadding > UINT8_MAX) |
| 57 report_fatal_error("Padding cannot exceed 255 bytes"); |
| 58 |
| 59 if (RequiredBundlePadding > 0) { |
| 60 SmallString<256> Code; |
| 61 raw_svector_ostream VecOS(Code); |
| 62 MCObjectWriter *OW = Assembler.getBackend().createObjectWriter(VecOS); |
| 63 |
| 64 EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding)); |
| 65 |
| 66 Assembler.writeFragmentPadding(*EF, FSize, OW); |
| 67 VecOS.flush(); |
| 68 delete OW; |
| 69 |
| 70 DF->getContents().append(Code.begin(), Code.end()); |
| 71 } |
| 72 } |
| 73 |
| 74 flushPendingLabels(DF, DF->getContents().size()); |
| 75 |
| 76 for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) { |
| 77 EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() + |
| 78 DF->getContents().size()); |
| 79 DF->getFixups().push_back(EF->getFixups()[i]); |
| 80 } |
| 81 DF->setHasInstructions(true); |
| 82 DF->getContents().append(EF->getContents().begin(), EF->getContents().end()); |
| 83 } |
| 84 |
42 void MCELFStreamer::InitSections(bool NoExecStack) { | 85 void MCELFStreamer::InitSections(bool NoExecStack) { |
43 // This emulates the same behavior of GNU as. This makes it easier | 86 // This emulates the same behavior of GNU as. This makes it easier |
44 // to compare the output as the major sections are in the same order. | 87 // to compare the output as the major sections are in the same order. |
45 MCContext &Ctx = getContext(); | 88 MCContext &Ctx = getContext(); |
46 SwitchSection(Ctx.getObjectFileInfo()->getTextSection()); | 89 SwitchSection(Ctx.getObjectFileInfo()->getTextSection()); |
47 EmitCodeAlignment(4); | 90 EmitCodeAlignment(4); |
48 | 91 |
49 SwitchSection(Ctx.getObjectFileInfo()->getDataSection()); | 92 SwitchSection(Ctx.getObjectFileInfo()->getDataSection()); |
50 EmitCodeAlignment(4); | 93 EmitCodeAlignment(4); |
51 | 94 |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 // instruction, emit a MCCompactEncodedInstFragment. Otherwise, emit a | 495 // instruction, emit a MCCompactEncodedInstFragment. Otherwise, emit a |
453 // MCDataFragment. | 496 // MCDataFragment. |
454 // - If we're in a bundle-locked group, append the instruction to the current | 497 // - If we're in a bundle-locked group, append the instruction to the current |
455 // data fragment because we want all the instructions in a group to get into | 498 // data fragment because we want all the instructions in a group to get into |
456 // the same fragment. Be careful not to do that for the first instruction in | 499 // the same fragment. Be careful not to do that for the first instruction in |
457 // the group, though. | 500 // the group, though. |
458 MCDataFragment *DF; | 501 MCDataFragment *DF; |
459 | 502 |
460 if (Assembler.isBundlingEnabled()) { | 503 if (Assembler.isBundlingEnabled()) { |
461 MCSectionData *SD = getCurrentSectionData(); | 504 MCSectionData *SD = getCurrentSectionData(); |
462 if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst()) | 505 if (Assembler.getRelaxAll() && SD->isBundleLocked()) |
| 506 // If the -mc-relax-all flag is used and we are bundle-locked, we re-use |
| 507 // the current bundle group. |
| 508 DF = BundleGroups.back(); |
| 509 else if (Assembler.getRelaxAll() && !SD->isBundleLocked()) |
| 510 // When not in a bundle-locked group and the -mc-relax-all flag is used, |
| 511 // we create a new temporary fragment which will be later merged into |
| 512 // the current fragment. |
| 513 DF = new MCDataFragment(); |
| 514 else if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst()) |
463 // If we are bundle-locked, we re-use the current fragment. | 515 // If we are bundle-locked, we re-use the current fragment. |
464 // The bundle-locking directive ensures this is a new data fragment. | 516 // The bundle-locking directive ensures this is a new data fragment. |
465 DF = cast<MCDataFragment>(getCurrentFragment()); | 517 DF = cast<MCDataFragment>(getCurrentFragment()); |
466 else if (!SD->isBundleLocked() && Fixups.size() == 0) { | 518 else if (!SD->isBundleLocked() && Fixups.size() == 0) { |
467 // Optimize memory usage by emitting the instruction to a | 519 // Optimize memory usage by emitting the instruction to a |
468 // MCCompactEncodedInstFragment when not in a bundle-locked group and | 520 // MCCompactEncodedInstFragment when not in a bundle-locked group and |
469 // there are no fixups registered. | 521 // there are no fixups registered. |
470 MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment(); | 522 MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment(); |
471 insert(CEIF); | 523 insert(CEIF); |
472 CEIF->getContents().append(Code.begin(), Code.end()); | 524 CEIF->getContents().append(Code.begin(), Code.end()); |
(...skipping 17 matching lines...) Expand all Loading... |
490 DF = getOrCreateDataFragment(); | 542 DF = getOrCreateDataFragment(); |
491 } | 543 } |
492 | 544 |
493 // Add the fixups and data. | 545 // Add the fixups and data. |
494 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { | 546 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { |
495 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); | 547 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); |
496 DF->getFixups().push_back(Fixups[i]); | 548 DF->getFixups().push_back(Fixups[i]); |
497 } | 549 } |
498 DF->setHasInstructions(true); | 550 DF->setHasInstructions(true); |
499 DF->getContents().append(Code.begin(), Code.end()); | 551 DF->getContents().append(Code.begin(), Code.end()); |
| 552 |
| 553 if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) { |
| 554 MCSectionData *SD = getCurrentSectionData(); |
| 555 if (!SD->isBundleLocked()) { |
| 556 mergeFragment(getOrCreateDataFragment(), DF); |
| 557 delete DF; |
| 558 } |
| 559 } |
500 } | 560 } |
501 | 561 |
502 void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) { | 562 void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) { |
503 assert(AlignPow2 <= 30 && "Invalid bundle alignment"); | 563 assert(AlignPow2 <= 30 && "Invalid bundle alignment"); |
504 MCAssembler &Assembler = getAssembler(); | 564 MCAssembler &Assembler = getAssembler(); |
505 if (AlignPow2 > 0 && (Assembler.getBundleAlignSize() == 0 || | 565 if (AlignPow2 > 0 && (Assembler.getBundleAlignSize() == 0 || |
506 Assembler.getBundleAlignSize() == 1U << AlignPow2)) | 566 Assembler.getBundleAlignSize() == 1U << AlignPow2)) |
507 Assembler.setBundleAlignSize(1U << AlignPow2); | 567 Assembler.setBundleAlignSize(1U << AlignPow2); |
508 else | 568 else |
509 report_fatal_error(".bundle_align_mode cannot be changed once set"); | 569 report_fatal_error(".bundle_align_mode cannot be changed once set"); |
510 } | 570 } |
511 | 571 |
512 void MCELFStreamer::EmitBundleLock(bool AlignToEnd) { | 572 void MCELFStreamer::EmitBundleLock(bool AlignToEnd) { |
513 MCSectionData *SD = getCurrentSectionData(); | 573 MCSectionData *SD = getCurrentSectionData(); |
514 | 574 |
515 // Sanity checks | 575 // Sanity checks |
516 // | 576 // |
517 if (!getAssembler().isBundlingEnabled()) | 577 if (!getAssembler().isBundlingEnabled()) |
518 report_fatal_error(".bundle_lock forbidden when bundling is disabled"); | 578 report_fatal_error(".bundle_lock forbidden when bundling is disabled"); |
519 | 579 |
520 if (!SD->isBundleLocked()) | 580 if (!SD->isBundleLocked()) |
521 SD->setBundleGroupBeforeFirstInst(true); | 581 SD->setBundleGroupBeforeFirstInst(true); |
522 | 582 |
| 583 if (getAssembler().getRelaxAll() && !SD->isBundleLocked()) { |
| 584 // TODO: drop the lock state and set directly in the fragment |
| 585 MCDataFragment *DF = new MCDataFragment(); |
| 586 BundleGroups.push_back(DF); |
| 587 } |
| 588 |
523 SD->setBundleLockState(AlignToEnd ? MCSectionData::BundleLockedAlignToEnd : | 589 SD->setBundleLockState(AlignToEnd ? MCSectionData::BundleLockedAlignToEnd : |
524 MCSectionData::BundleLocked); | 590 MCSectionData::BundleLocked); |
525 } | 591 } |
526 | 592 |
527 void MCELFStreamer::EmitBundleUnlock() { | 593 void MCELFStreamer::EmitBundleUnlock() { |
528 MCSectionData *SD = getCurrentSectionData(); | 594 MCSectionData *SD = getCurrentSectionData(); |
529 | 595 |
530 // Sanity checks | 596 // Sanity checks |
531 if (!getAssembler().isBundlingEnabled()) | 597 if (!getAssembler().isBundlingEnabled()) |
532 report_fatal_error(".bundle_unlock forbidden when bundling is disabled"); | 598 report_fatal_error(".bundle_unlock forbidden when bundling is disabled"); |
533 else if (!SD->isBundleLocked()) | 599 else if (!SD->isBundleLocked()) |
534 report_fatal_error(".bundle_unlock without matching lock"); | 600 report_fatal_error(".bundle_unlock without matching lock"); |
535 else if (SD->isBundleGroupBeforeFirstInst()) | 601 else if (SD->isBundleGroupBeforeFirstInst()) |
536 report_fatal_error("Empty bundle-locked group is forbidden"); | 602 report_fatal_error("Empty bundle-locked group is forbidden"); |
537 | 603 |
538 SD->setBundleLockState(MCSectionData::NotBundleLocked); | 604 // When the -mc-relax-all flag is used, we emit instructions to fragments |
| 605 // stored on a stack. When the bundle unlock is emited, we pop a fragment |
| 606 // from the stack a merge it to the one below. |
| 607 if (getAssembler().getRelaxAll()) { |
| 608 assert(!BundleGroups.empty() && "There are no bundle groups"); |
| 609 MCDataFragment *DF = BundleGroups.back(); |
| 610 |
| 611 // FIXME: Use BundleGroups to track the lock state instead. |
| 612 SD->setBundleLockState(MCSectionData::NotBundleLocked); |
| 613 |
| 614 // FIXME: Use more separate fragments for nested groups. |
| 615 if (!SD->isBundleLocked()) { |
| 616 mergeFragment(getOrCreateDataFragment(), DF); |
| 617 BundleGroups.pop_back(); |
| 618 delete DF; |
| 619 } |
| 620 |
| 621 if (SD->getBundleLockState() != MCSectionData::BundleLockedAlignToEnd) |
| 622 getOrCreateDataFragment()->setAlignToBundleEnd(false); |
| 623 } else |
| 624 SD->setBundleLockState(MCSectionData::NotBundleLocked); |
539 } | 625 } |
540 | 626 |
541 void MCELFStreamer::Flush() { | 627 void MCELFStreamer::Flush() { |
542 for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), | 628 for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), |
543 e = LocalCommons.end(); | 629 e = LocalCommons.end(); |
544 i != e; ++i) { | 630 i != e; ++i) { |
545 MCSymbolData *SD = i->SD; | 631 MCSymbolData *SD = i->SD; |
546 uint64_t Size = i->Size; | 632 uint64_t Size = i->Size; |
547 unsigned ByteAlignment = i->ByteAlignment; | 633 unsigned ByteAlignment = i->ByteAlignment; |
548 const MCSymbol &Symbol = SD->getSymbol(); | 634 const MCSymbol &Symbol = SD->getSymbol(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 | 694 |
609 void MCELFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, | 695 void MCELFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, |
610 uint64_t Size, unsigned ByteAlignment) { | 696 uint64_t Size, unsigned ByteAlignment) { |
611 llvm_unreachable("ELF doesn't support this directive"); | 697 llvm_unreachable("ELF doesn't support this directive"); |
612 } | 698 } |
613 | 699 |
614 void MCELFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, | 700 void MCELFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, |
615 uint64_t Size, unsigned ByteAlignment) { | 701 uint64_t Size, unsigned ByteAlignment) { |
616 llvm_unreachable("ELF doesn't support this directive"); | 702 llvm_unreachable("ELF doesn't support this directive"); |
617 } | 703 } |
OLD | NEW |