From: Saleem Abdulrasool Date: Tue, 7 Oct 2014 19:37:57 +0000 (+0000) Subject: MC: add support for -aligncomm GNU extension X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=29890f73dc27ea268f2a80b51c0411cd1405c534;p=llvm MC: add support for -aligncomm GNU extension The GNU linker supports an -aligncomm directive that allows for power-of-2 alignment of common data. Add support to emit this directive. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219229 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index 2829a8ff0b5..9bae53706a0 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/COFF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" @@ -184,16 +185,10 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, "Got non-COFF section in the COFF backend!"); const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); - if (T.isKnownWindowsMSVCEnvironment()) { + if (T.isKnownWindowsMSVCEnvironment()) if (ByteAlignment > 32) report_fatal_error("alignment is limited to 32-bytes"); - } else { - // The bfd linker from binutils only supports alignments less than 4 bytes - // without inserting -aligncomm arguments into the .drectve section. - // TODO: Support inserting -aligncomm into the .drectve section. - if (ByteAlignment > 4) - report_fatal_error("alignment is limited to 4-bytes"); - } + // Round size up to alignment so that we will honor the alignment request. // TODO: We don't need to do this if we are targeting the bfd linker once we // add support for adding -aligncomm into the .drectve section. @@ -204,6 +199,21 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); SD.setExternal(true); SD.setCommon(Size, ByteAlignment); + + if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) { + SmallString<128> Directive; + raw_svector_ostream OS(Directive); + const MCObjectFileInfo *MFI = getContext().getObjectFileInfo(); + + OS << " -aligncomm:\"" << Symbol->getName() << "\"," + << Log2_32_Ceil(ByteAlignment); + OS.flush(); + + PushSection(); + SwitchSection(MFI->getDrectveSection()); + EmitBytes(Directive); + PopSection(); + } } void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/test/MC/COFF/comm-align.s b/test/MC/COFF/comm-align.s new file mode 100644 index 00000000000..e658c5685d3 --- /dev/null +++ b/test/MC/COFF/comm-align.s @@ -0,0 +1,50 @@ +# RUN: llvm-mc -triple i686-windows-gnu -filetype obj -o - %s \ +# RUN: | llvm-readobj -coff-directives -symbols | FileCheck %s + +# NOTE: this test checks multiple things: +# - that -aligncomm is not emitted for 1-byte alignment +# - that -aligncomm is emitted for the various alignments (greater than 1) +# - that the alignment is represented as a log_2 of the alignment +# - that the section switching occurs correctly +# - that functions after the switch also are emitted into the correct section + + .text + + .def _a + .scl 3 + .type 32 + .endef +_a: + ret + + .data + + .comm _s_1,4,0 # @s_1 + .comm _s_2,4,1 # @s_2 + .comm _s_4,4,2 # @s_3 + .comm _s_8,4,3 # @s_4 + + .text + + .def _b + .scl 3 + .type 32 + .endef +_b: + ret + +# CHECK-NOT: -aligncomm:"_s_1",0 + +# CHECK: Symbols [ +# CHECK: Symbol { +# CHECK: Name: _a +# CHECK: Section: .text (1) +# CHECK: } +# CHECK: Symbol { +# CHECK: Name: _b +# CHECK: Section: .text (1) +# CHECK: } +# CHECK: ] + +# CHECK: Directive(s): -aligncomm:"_s_2",1 -aligncomm:"_s_4",2 -aligncomm:"_s_8",3 +