MC-COFF: Fix symbol aliases. Fixes PR8251.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Thu, 7 Oct 2010 06:29:33 +0000 (06:29 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Thu, 7 Oct 2010 06:29:33 +0000 (06:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115909 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/WinCOFFStreamer.cpp
test/MC/COFF/symbol-alias.ll [new file with mode: 0644]

index fd1956ec26c74ac043fa8934b47ef038d830ce09..6afa6db40fa7ef7cee44936a4efcb87c79a74611 100644 (file)
@@ -157,11 +157,42 @@ void WinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
 }
 
 void WinCOFFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
-  // TODO: This is exactly the same as MachOStreamer. Consider merging into
-  // MCObjectStreamer.
-  getAssembler().getOrCreateSymbolData(*Symbol);
-  AddValueSymbols(Value);
-  Symbol->setVariableValue(Value);
+  // FIXME: This is all very ugly and depressing. What needs to happen here
+  // depends on quite a few things that are all part of relaxation, which we
+  // don't really even do.
+
+  if (Value->getKind() != MCExpr::SymbolRef) {
+    // TODO: This is exactly the same as MachOStreamer. Consider merging into\r
+    // MCObjectStreamer.\r
+    getAssembler().getOrCreateSymbolData(*Symbol);\r
+    AddValueSymbols(Value);\r
+    Symbol->setVariableValue(Value);
+  } else {
+    // FIXME: This is a horrible way to do this :(. This should really be
+    // handled after we are done with the MC* objects and immediately before
+    // writing out the object file when we know exactly what the symbol should
+    // look like in the coff symbol table. I'm not doing that now because the
+    // COFF object writer doesn't have a clearly defined separation between MC
+    // data structures, the object writers data structures, and the raw, POD,
+    // data structures that get written to disk.
+
+    // Copy over the aliased data.
+    MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+    const MCSymbolData &RealSD = getAssembler().getOrCreateSymbolData(
+      dyn_cast<const MCSymbolRefExpr>(Value)->getSymbol());
+
+    // FIXME: This is particularly nasty because it breaks as soon as any data
+    // members of MCSymbolData change.
+    SD.CommonAlign     = RealSD.CommonAlign;
+    SD.CommonSize      = RealSD.CommonSize;
+    SD.Flags           = RealSD.Flags;
+    SD.Fragment        = RealSD.Fragment;
+    SD.Index           = RealSD.Index;
+    SD.IsExternal      = RealSD.IsExternal;
+    SD.IsPrivateExtern = RealSD.IsPrivateExtern;
+    SD.Offset          = RealSD.Offset;
+    SD.SymbolSize      = RealSD.SymbolSize;
+  }
 }
 
 void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
diff --git a/test/MC/COFF/symbol-alias.ll b/test/MC/COFF/symbol-alias.ll
new file mode 100644 (file)
index 0000000..3c00117
--- /dev/null
@@ -0,0 +1,48 @@
+; The purpose of this test is to verify that symbol aliases
+; (@foo = alias <type> @bar) generate the correct entries in the symbol table.
+; They should be identical except for the name.
+
+; RUN: llc -filetype=obj -mtriple i686-pc-win32 %s -o - | coff-dump.py | FileCheck %s
+; RUN: llc -filetype=obj -mtriple x86_64-pc-win32 %s -o - | coff-dump.py | FileCheck %s
+
+define void @foo() {
+entry:
+  ret void
+}
+
+@bar = global i32 zeroinitializer
+
+@foo_alias = alias void ()* @foo
+@bar_alias = alias i32* @bar
+
+; CHECK:      Name               = {{_?}}foo
+; CHECK-NEXT: Value              = [[FOO_VALUE:.*$]]
+; CHECK-NEXT: SectionNumber      = [[FOO_SECTION_NUMBER:.*$]]
+; CHECK-NEXT: SimpleType         = [[FOO_SIMPLE_TYPE:.*$]]
+; CHECK-NEXT: ComplexType        = [[FOO_COMPLEX_TYPE:.*$]]
+; CHECK-NEXT: StorageClass       = [[FOO_STORAGE_CLASS:.*$]]
+; CHECK-NEXT: NumberOfAuxSymbols = [[FOO_NUMBER_OF_AUX_SYMBOLS:.*$]]
+
+; CHECK:      Name               = {{_?}}bar
+; CHECK-NEXT: Value              = [[BAR_VALUE:.*$]]
+; CHECK-NEXT: SectionNumber      = [[BAR_SECTION_NUMBER:.*$]]
+; CHECK-NEXT: SimpleType         = [[BAR_SIMPLE_TYPE:.*$]]
+; CHECK-NEXT: ComplexType        = [[BAR_COMPLEX_TYPE:.*$]]
+; CHECK-NEXT: StorageClass       = [[BAR_STORAGE_CLASS:.*$]]
+; CHECK-NEXT: NumberOfAuxSymbols = [[BAR_NUMBER_OF_AUX_SYMBOLS:.*$]]
+
+; CHECK:      Name               = {{_?}}foo_alias
+; CHECK-NEXT: Value              = [[FOO_VALUE]]
+; CHECK-NEXT: SectionNumber      = [[FOO_SECTION_NUMBER]]
+; CHECK-NEXT: SimpleType         = [[FOO_SIMPLE_TYPE]]
+; CHECK-NEXT: ComplexType        = [[FOO_COMPLEX_TYPE]]
+; CHECK-NEXT: StorageClass       = [[FOO_STORAGE_CLASS]]
+; CHECK-NEXT: NumberOfAuxSymbols = [[FOO_NUMBER_OF_AUX_SYMBOLS]]
+
+; CHECK:      Name               = {{_?}}bar_alias
+; CHECK-NEXT: Value              = [[BAR_VALUE]]
+; CHECK-NEXT: SectionNumber      = [[BAR_SECTION_NUMBER]]
+; CHECK-NEXT: SimpleType         = [[BAR_SIMPLE_TYPE]]
+; CHECK-NEXT: ComplexType        = [[BAR_COMPLEX_TYPE]]
+; CHECK-NEXT: StorageClass       = [[BAR_STORAGE_CLASS]]
+; CHECK-NEXT: NumberOfAuxSymbols = [[BAR_NUMBER_OF_AUX_SYMBOLS]]