From 0933134a304b47d3767aad202df9f0e09743da6d Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Tue, 29 Jan 2013 22:10:07 +0000 Subject: [PATCH] [MC][COFF] Delay handling symbol aliases when writing Fixes PR14447 and PR9034. Patch by Nico Rieck! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173839 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/WinCOFFObjectWriter.cpp | 26 ++++++++++++++--------- lib/MC/WinCOFFStreamer.cpp | 39 ---------------------------------- test/MC/COFF/symbol-alias.s | 11 ++++++++++ 3 files changed, 27 insertions(+), 49 deletions(-) diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index e1d65387a1a..fc7aa942e6e 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -147,7 +147,9 @@ public: object_t *createCOFFEntity(StringRef Name, list_t &List); void DefineSection(MCSectionData const &SectionData); - void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler); + void DefineSymbol(MCSymbol const &Symbol, + MCSymbolData const &SymbolData, + MCAssembler &Assembler); void MakeSymbolReal(COFFSymbol &S, size_t Index); void MakeSectionReal(COFFSection &S, size_t Number); @@ -408,9 +410,10 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { /// This function takes a section data object from the assembler /// and creates the associated COFF symbol staging object. -void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, +void WinCOFFObjectWriter::DefineSymbol(MCSymbol const &Symbol, + MCSymbolData const &SymbolData, MCAssembler &Assembler) { - COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&SymbolData.getSymbol()); + COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol); coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0; coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16; @@ -418,9 +421,9 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, if (SymbolData.getFlags() & COFF::SF_WeakExternal) { coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; - if (SymbolData.getSymbol().isVariable()) { + if (Symbol.isVariable()) { coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; - const MCExpr *Value = SymbolData.getSymbol().getVariableValue(); + const MCExpr *Value = Symbol.getVariableValue(); // FIXME: This assert message isn't very good. assert(Value->getKind() == MCExpr::SymbolRef && @@ -428,10 +431,10 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, const MCSymbolRefExpr *SymbolRef = static_cast(Value); - coff_symbol->Other = GetOrCreateCOFFSymbol(&SymbolRef->getSymbol()); + coff_symbol->Other = GetOrCreateCOFFSymbol(&Symbol); } else { std::string WeakName = std::string(".weak.") - + SymbolData.getSymbol().getName().str() + + Symbol.getName().str() + ".default"; COFFSymbol *WeakDefault = createSymbol(WeakName); WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; @@ -464,7 +467,7 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, // Bind internal COFF symbol to MC symbol. coff_symbol->MCData = &SymbolData; - SymbolMap[&SymbolData.getSymbol()] = coff_symbol; + SymbolMap[&Symbol] = coff_symbol; } /// making a section real involves assigned it a number and putting @@ -619,8 +622,11 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(), e = Asm.symbol_end(); i != e; i++) { - if (ExportSymbol(*i, Asm)) - DefineSymbol(*i, Asm); + if (ExportSymbol(*i, Asm)) { + const MCSymbol &Alias = i->getSymbol(); + const MCSymbol &Symbol = Alias.AliasedSymbol(); + DefineSymbol(Alias, Asm.getSymbolData(Symbol), Asm); + } } } diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index cc2c272f38b..b529489b1a6 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -55,7 +55,6 @@ public: virtual void EmitDebugLabel(MCSymbol *Symbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); virtual void EmitThumbFunc(MCSymbol *Func); - virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol); @@ -201,44 +200,6 @@ void WinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) { llvm_unreachable("not implemented"); } -void WinCOFFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { - assert((Symbol->isInSection() - ? Symbol->getSection().getVariant() == MCSection::SV_COFF - : true) && "Got non COFF section in the COFF backend!"); - // 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) { - MCObjectStreamer::EmitAssignment(Symbol, 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, MCSymbolAttr Attribute) { assert(Symbol && "Symbol must be non-null!"); diff --git a/test/MC/COFF/symbol-alias.s b/test/MC/COFF/symbol-alias.s index 03f07b2e568..4b1772ce711 100644 --- a/test/MC/COFF/symbol-alias.s +++ b/test/MC/COFF/symbol-alias.s @@ -23,8 +23,11 @@ _bar: .long 0 # 0x0 +# Order is important here. Assign _bar_alias_alias before _bar_alias. .globl _foo_alias _foo_alias = _foo + .globl _bar_alias_alias +_bar_alias_alias = _bar_alias .globl _bar_alias _bar_alias = _bar @@ -52,6 +55,14 @@ _bar_alias = _bar // CHECK-NEXT: StorageClass = [[FOO_STORAGE_CLASS]] // CHECK-NEXT: NumberOfAuxSymbols = [[FOO_NUMBER_OF_AUX_SYMBOLS]] +// CHECK: Name = {{_?}}bar_alias_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]] + // CHECK: Name = {{_?}}bar_alias // CHECK-NEXT: Value = [[BAR_VALUE]] // CHECK-NEXT: SectionNumber = [[BAR_SECTION_NUMBER]]