[MC] Common symbols weren't being checked for redeclaration which allowed an assembly...
[oota-llvm.git] / lib / MC / MCELFStreamer.cpp
index 01c8e2825e9d32a8ff2f6d7b3f348acdb96b5ae4..e0f4a2ae16a36652c3893f6e5c5dfca11f9f7557 100644 (file)
@@ -20,8 +20,6 @@
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCELF.h"
-#include "llvm/MC/MCELFSymbolFlags.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCObjectFileInfo.h"
@@ -107,7 +105,8 @@ void MCELFStreamer::InitSections(bool NoExecStack) {
     SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
 }
 
-void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
+void MCELFStreamer::EmitLabel(MCSymbol *S) {
+  auto *Symbol = cast<MCSymbolELF>(S);
   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
 
   MCObjectStreamer::EmitLabel(Symbol);
@@ -115,7 +114,7 @@ void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
   const MCSectionELF &Section =
     static_cast<const MCSectionELF&>(Symbol->getSection());
   if (Section.getFlags() & ELF::SHF_TLS)
-    MCELF::SetType(*Symbol, ELF::STT_TLS);
+    Symbol->setType(ELF::STT_TLS);
 }
 
 void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
@@ -160,14 +159,14 @@ void MCELFStreamer::ChangeSection(MCSection *Section,
 
   this->MCObjectStreamer::ChangeSection(Section, Subsection);
   MCContext &Ctx = getContext();
-  MCSymbol *Begin = Section->getBeginSymbol();
+  auto *Begin = cast_or_null<MCSymbolELF>(Section->getBeginSymbol());
   if (!Begin) {
     Begin = Ctx.getOrCreateSectionSymbol(*SectionELF);
     Section->setBeginSymbol(Begin);
   }
   if (Begin->isUndefined()) {
     Asm.registerSymbol(*Begin);
-    MCELF::SetType(*Begin, ELF::STT_SECTION);
+    Begin->setType(ELF::STT_SECTION);
   }
 }
 
@@ -197,8 +196,8 @@ static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) {
   return T2;
 }
 
-bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
-                                        MCSymbolAttr Attribute) {
+bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
+  auto *Symbol = cast<MCSymbolELF>(S);
   // Indirect symbols are handled differently, to match how 'as' handles
   // them. This makes writing matching .o files easier.
   if (Attribute == MCSA_IndirectSymbol) {
@@ -238,91 +237,81 @@ bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
     break;
 
   case MCSA_ELF_TypeGnuUniqueObject:
-    MCELF::SetType(
-        *Symbol, CombineSymbolTypes(MCELF::GetType(*Symbol), ELF::STT_OBJECT));
-    MCELF::SetBinding(*Symbol, ELF::STB_GNU_UNIQUE);
+    Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
+    Symbol->setBinding(ELF::STB_GNU_UNIQUE);
     Symbol->setExternal(true);
-    BindingExplicitlySet.insert(Symbol);
     break;
 
   case MCSA_Global:
-    MCELF::SetBinding(*Symbol, ELF::STB_GLOBAL);
+    Symbol->setBinding(ELF::STB_GLOBAL);
     Symbol->setExternal(true);
-    BindingExplicitlySet.insert(Symbol);
     break;
 
   case MCSA_WeakReference:
   case MCSA_Weak:
-    MCELF::SetBinding(*Symbol, ELF::STB_WEAK);
+    Symbol->setBinding(ELF::STB_WEAK);
     Symbol->setExternal(true);
-    BindingExplicitlySet.insert(Symbol);
     break;
 
   case MCSA_Local:
-    MCELF::SetBinding(*Symbol, ELF::STB_LOCAL);
+    Symbol->setBinding(ELF::STB_LOCAL);
     Symbol->setExternal(false);
-    BindingExplicitlySet.insert(Symbol);
     break;
 
   case MCSA_ELF_TypeFunction:
-    MCELF::SetType(*Symbol,
-                   CombineSymbolTypes(MCELF::GetType(*Symbol), ELF::STT_FUNC));
+    Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_FUNC));
     break;
 
   case MCSA_ELF_TypeIndFunction:
-    MCELF::SetType(*Symbol, CombineSymbolTypes(MCELF::GetType(*Symbol),
-                                               ELF::STT_GNU_IFUNC));
+    Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_GNU_IFUNC));
     break;
 
   case MCSA_ELF_TypeObject:
-    MCELF::SetType(
-        *Symbol, CombineSymbolTypes(MCELF::GetType(*Symbol), ELF::STT_OBJECT));
+    Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
     break;
 
   case MCSA_ELF_TypeTLS:
-    MCELF::SetType(*Symbol,
-                   CombineSymbolTypes(MCELF::GetType(*Symbol), ELF::STT_TLS));
+    Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_TLS));
     break;
 
   case MCSA_ELF_TypeCommon:
     // TODO: Emit these as a common symbol.
-    MCELF::SetType(
-        *Symbol, CombineSymbolTypes(MCELF::GetType(*Symbol), ELF::STT_OBJECT));
+    Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_OBJECT));
     break;
 
   case MCSA_ELF_TypeNoType:
-    MCELF::SetType(
-        *Symbol, CombineSymbolTypes(MCELF::GetType(*Symbol), ELF::STT_NOTYPE));
+    Symbol->setType(CombineSymbolTypes(Symbol->getType(), ELF::STT_NOTYPE));
     break;
 
   case MCSA_Protected:
-    MCELF::SetVisibility(*Symbol, ELF::STV_PROTECTED);
+    Symbol->setVisibility(ELF::STV_PROTECTED);
     break;
 
   case MCSA_Hidden:
-    MCELF::SetVisibility(*Symbol, ELF::STV_HIDDEN);
+    Symbol->setVisibility(ELF::STV_HIDDEN);
     break;
 
   case MCSA_Internal:
-    MCELF::SetVisibility(*Symbol, ELF::STV_INTERNAL);
+    Symbol->setVisibility(ELF::STV_INTERNAL);
     break;
   }
 
   return true;
 }
 
-void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+void MCELFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size,
                                      unsigned ByteAlignment) {
+  auto *Symbol = cast<MCSymbolELF>(S);
   getAssembler().registerSymbol(*Symbol);
 
-  if (!BindingExplicitlySet.count(Symbol)) {
-    MCELF::SetBinding(*Symbol, ELF::STB_GLOBAL);
+  if (!Symbol->isBindingSet()) {
+    Symbol->setBinding(ELF::STB_GLOBAL);
     Symbol->setExternal(true);
   }
 
-  MCELF::SetType(*Symbol, ELF::STT_OBJECT);
+  Symbol->setType(ELF::STT_OBJECT);
 
-  if (MCELF::GetBinding(*Symbol) == ELF_STB_Local) {
+  if (Symbol->getBinding() == ELF::STB_LOCAL) {
     MCSection *Section = getAssembler().getContext().getELFSection(
         ".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
 
@@ -331,7 +320,9 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
     struct LocalCommon L = {Symbol, Size, ByteAlignment};
     LocalCommons.push_back(L);
   } else {
-    Symbol->setCommon(Size, ByteAlignment);
+    if(Symbol->declareCommon(Size, ByteAlignment))
+      report_fatal_error("Symbol: " + Symbol->getName() +
+                         " redeclared as different type");
   }
 
   cast<MCSymbolELF>(Symbol)
@@ -342,13 +333,13 @@ void MCELFStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) {
   Symbol->setSize(Value);
 }
 
-void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
                                           unsigned ByteAlignment) {
+  auto *Symbol = cast<MCSymbolELF>(S);
   // FIXME: Should this be caught and done earlier?
   getAssembler().registerSymbol(*Symbol);
-  MCELF::SetBinding(*Symbol, ELF::STB_LOCAL);
+  Symbol->setBinding(ELF::STB_LOCAL);
   Symbol->setExternal(false);
-  BindingExplicitlySet.insert(Symbol);
   EmitCommonSymbol(Symbol, Size, ByteAlignment);
 }
 
@@ -463,7 +454,7 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
       break;
     }
     getAssembler().registerSymbol(symRef.getSymbol());
-    MCELF::SetType(symRef.getSymbol(), ELF::STT_TLS);
+    cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
     break;
   }
 
@@ -612,7 +603,7 @@ void MCELFStreamer::EmitBundleUnlock() {
     report_fatal_error("Empty bundle-locked group is forbidden");
 
   // When the -mc-relax-all flag is used, we emit instructions to fragments
-  // stored on a stack. When the bundle unlock is emited, we pop a fragment 
+  // stored on a stack. When the bundle unlock is emited, we pop a fragment
   // from the stack a merge it to the one below.
   if (getAssembler().getRelaxAll()) {
     assert(!BundleGroups.empty() && "There are no bundle groups");