diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2014-09-21 09:18:07 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2014-09-21 09:18:07 +0000 |
| commit | 48227a37592f31bd8c9410f36fb0ee5246a2e2bf (patch) | |
| tree | a3f7ea909628af70d28eaeb14f98c4ef6fe9e0e6 /llvm/lib/MC | |
| parent | 8ff73c01704991fdbe0b23a67925defdcb988d64 (diff) | |
| download | bcm5719-llvm-48227a37592f31bd8c9410f36fb0ee5246a2e2bf.tar.gz bcm5719-llvm-48227a37592f31bd8c9410f36fb0ee5246a2e2bf.zip | |
MC: Support aligned COMMON symbols for COFF
link.exe:
Fuzz testing has shown that COMMON symbols with size > 32 will always
have an alignment of at least 32 and all symbols with size < 32 will
have an alignment of at least the largest power of 2 less than the size
of the symbol.
binutils:
The BFD linker essentially work like the link.exe behavior but with
alignment 4 instead of 32. The BFD linker also supports an extension to
COFF which adds an -aligncomm argument to the .drectve section which
permits specifying a precise alignment for a variable but MC currently
doesn't support editing .drectve in this way.
With all of this in mind, we decide to play a little trick: we can
ensure that the alignment will be respected by bumping the size of the
global to it's alignment.
llvm-svn: 218201
Diffstat (limited to 'llvm/lib/MC')
| -rw-r--r-- | llvm/lib/MC/MCObjectFileInfo.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/MC/WinCOFFStreamer.cpp | 17 |
2 files changed, 16 insertions, 5 deletions
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index da707d860a6..547630ea37d 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -595,9 +595,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { bool IsWoA = T.getArch() == Triple::arm || T.getArch() == Triple::thumb; - // The object file format cannot represent common symbols with explicit - // alignments. - CommDirectiveSupportsAlignment = false; + CommDirectiveSupportsAlignment = true; // COFF BSSSection = diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp index 1d03e2d742f..2829a8ff0b5 100644 --- a/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/llvm/lib/MC/WinCOFFStreamer.cpp @@ -183,8 +183,21 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Symbol->getSection().getVariant() == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!"); - if (ByteAlignment > 32) - report_fatal_error("alignment is limited to 32-bytes"); + const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); + 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. + Size = std::max(Size, static_cast<uint64_t>(ByteAlignment)); AssignSection(Symbol, nullptr); |

