Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: lib/MC/MCELFStreamer.cpp

Issue 1133723005: Cherry-pick r234714: [MC] Write padding into fragments when -mc-relax-all flag is used (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Rebase Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/MC/MCAssembler.cpp ('k') | lib/MC/MCObjectStreamer.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « lib/MC/MCAssembler.cpp ('k') | lib/MC/MCObjectStreamer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698