diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index fd1956ec26c..6afa6db40fa 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -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 + // MCObjectStreamer. + getAssembler().getOrCreateSymbolData(*Symbol); + AddValueSymbols(Value); + 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(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 index 00000000000..3c00117f161 --- /dev/null +++ b/test/MC/COFF/symbol-alias.ll @@ -0,0 +1,48 @@ +; The purpose of this test is to verify that symbol aliases +; (@foo = alias @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]]