From 2a1678a7890a80b73b49c9ec185a65f11e0a6084 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Tue, 21 Apr 2015 00:14:25 +0000 Subject: [PATCH] [MC] When using bundle aligment, align sections to bundle size Summary: Bundle aligment requires that the functions always start at an aligned address. Usually this is ensured by the compiler, but assembly code does not always begin with a .align directive. This change ensures that sections get the correct alignment if they contain any instructions and bundling is enabled. (It also makes LLVM match the behavior of GNU as). Differential Revision: http://reviews.llvm.org/D9131 llvm-svn: 235365 --- llvm/lib/MC/MCELFStreamer.cpp | 15 +++++++++++++ .../X86/AlignedBundling/section-alignment.s | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 llvm/test/MC/X86/AlignedBundling/section-alignment.s diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index aa0539077255c..24b5681e55a30 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -131,6 +131,16 @@ void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { llvm_unreachable("invalid assembler flag!"); } +// If bundle aligment is used and there are any instructions in the section, it +// needs to be aligned to at least the bundle size. +static void setSectionAlignmentForBundling( + const MCAssembler &Assembler, MCSectionData *Section) { + if (Assembler.isBundlingEnabled() && Section && + Section->hasInstructions() && + Section->getAlignment() < Assembler.getBundleAlignSize()) + Section->setAlignment(Assembler.getBundleAlignSize()); +} + void MCELFStreamer::ChangeSection(const MCSection *Section, const MCExpr *Subsection) { MCSectionData *CurSection = getCurrentSectionData(); @@ -138,6 +148,8 @@ void MCELFStreamer::ChangeSection(const MCSection *Section, report_fatal_error("Unterminated .bundle_lock when changing a section"); MCAssembler &Asm = getAssembler(); + // Ensure the previous section gets aligned if necessary. + setSectionAlignmentForBundling(Asm, CurSection); auto *SectionELF = static_cast(Section); const MCSymbol *Grp = SectionELF->getGroup(); if (Grp) @@ -639,6 +651,9 @@ void MCELFStreamer::Flush() { } void MCELFStreamer::FinishImpl() { + // Ensure the last section gets aligned if necessary. + setSectionAlignmentForBundling(getAssembler(), getCurrentSectionData()); + EmitFrames(nullptr); Flush(); diff --git a/llvm/test/MC/X86/AlignedBundling/section-alignment.s b/llvm/test/MC/X86/AlignedBundling/section-alignment.s new file mode 100644 index 0000000000000..c40432cd4e7ae --- /dev/null +++ b/llvm/test/MC/X86/AlignedBundling/section-alignment.s @@ -0,0 +1,21 @@ +# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - \ +# RUN: | llvm-readobj -sections | FileCheck %s + +# Test that bundle-aligned sections with instructions are aligned + + .bundle_align_mode 5 +# CHECK: Sections +# Check that the empty .text section has the default alignment +# CHECK-LABEL: Name: .text +# CHECK-NOT: Name +# CHECK: AddressAlignment: 4 + + .section text1, "x" + imull $17, %ebx, %ebp +# CHECK-LABEL: Name: text1 +# CHECK: AddressAlignment: 32 + + .section text2, "x" + imull $17, %ebx, %ebp +# CHECK-LABEL: Name: text2 +# CHECK: AddressAlignment: 32