mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218201 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1ca1e33c3a
commit
31b080d57f
@ -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 =
|
||||
|
@ -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);
|
||||
|
||||
|
@ -9,5 +9,5 @@
|
||||
; CHECK: .lcomm _a,1
|
||||
; CHECK: .lcomm _b,8,8
|
||||
; .comm uses log2 alignment
|
||||
; CHECK: .comm _c,1
|
||||
; CHECK: .comm _d,8
|
||||
; CHECK: .comm _c,1,0
|
||||
; CHECK: .comm _d,8,3
|
||||
|
@ -1,7 +1,9 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s | llvm-readobj -t | FileCheck %s
|
||||
|
||||
.lcomm _a,4,4
|
||||
.comm _b, 4
|
||||
.comm _b, 4, 2
|
||||
// _c has size 1 but align 32, the value field is the max of size and align.
|
||||
.comm _c, 1, 5
|
||||
|
||||
|
||||
// CHECK: Symbol {
|
||||
@ -23,3 +25,13 @@
|
||||
// CHECK-NEXT: StorageClass: External
|
||||
// CHECK-NEXT: AuxSymbolCount: 0
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: Symbol {
|
||||
// CHECK: Name: _c
|
||||
// CHECK-NEXT: Value: 32
|
||||
// CHECK-NEXT: Section: IMAGE_SYM_UNDEFINED (0)
|
||||
// CHECK-NEXT: BaseType: Null
|
||||
// CHECK-NEXT: ComplexType: Null
|
||||
// CHECK-NEXT: StorageClass: External
|
||||
// CHECK-NEXT: AuxSymbolCount: 0
|
||||
// CHECK-NEXT: }
|
||||
|
Loading…
Reference in New Issue
Block a user