- unsigned Align = TM.getTargetData()->getPreferredAlignment(GV);
- unsigned Size =
- TM.getTargetData()->getTypeAllocSize(GV->getType()->getElementType());
-
- // If this global has a zero initializer, it is part of the .bss or common
- // section.
- if (GV->getInitializer()->isNullValue()) {
- // If this global is part of the common block, add it now. Variables are
- // part of the common block if they are zero initialized and allowed to be
- // merged with other symbols.
- if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
- GV->hasCommonLinkage()) {
- ELFSym CommonSym(GV);
- // Value for common symbols is the alignment required.
- CommonSym.Value = Align;
- CommonSym.Size = Size;
- CommonSym.SetBind(ELFSym::STB_GLOBAL);
- CommonSym.SetType(ELFSym::STT_OBJECT);
- // TODO SOMEDAY: add ELF visibility.
- CommonSym.SectionIdx = ELFSection::SHN_COMMON;
- SymbolTable.push_back(CommonSym);
+ const MCSection *CPSect = TLOF.getSectionForConstant(Kind);
+ return getSection(((MCSectionELF*)CPSect)->getName(),
+ ELFSection::SHT_PROGBITS,
+ getElfSectionFlags(Kind),
+ CPE.getAlignment());
+}
+
+// getRelocSection - Return the relocation section of section 'S'. 'RelA'
+// is true if the relocation section contains entries with addends.
+ELFSection &ELFWriter::getRelocSection(ELFSection &S) {
+ unsigned SectionHeaderTy = TEW->hasRelocationAddend() ?
+ ELFSection::SHT_RELA : ELFSection::SHT_REL;
+ std::string RelSName(".rel");
+ if (TEW->hasRelocationAddend())
+ RelSName.append("a");
+ RelSName.append(S.getName());
+
+ return getSection(RelSName, SectionHeaderTy, 0, TEW->getPrefELFAlignment());
+}
+
+// getGlobalELFVisibility - Returns the ELF specific visibility type
+unsigned ELFWriter::getGlobalELFVisibility(const GlobalValue *GV) {
+ switch (GV->getVisibility()) {
+ default:
+ llvm_unreachable("unknown visibility type");
+ case GlobalValue::DefaultVisibility:
+ return ELFSym::STV_DEFAULT;
+ case GlobalValue::HiddenVisibility:
+ return ELFSym::STV_HIDDEN;
+ case GlobalValue::ProtectedVisibility:
+ return ELFSym::STV_PROTECTED;
+ }
+ return 0;
+}
+
+// getGlobalELFBinding - Returns the ELF specific binding type
+unsigned ELFWriter::getGlobalELFBinding(const GlobalValue *GV) {
+ if (GV->hasInternalLinkage())
+ return ELFSym::STB_LOCAL;
+
+ if (GV->isWeakForLinker() && !GV->hasCommonLinkage())
+ return ELFSym::STB_WEAK;
+
+ return ELFSym::STB_GLOBAL;
+}
+
+// getGlobalELFType - Returns the ELF specific type for a global
+unsigned ELFWriter::getGlobalELFType(const GlobalValue *GV) {
+ if (GV->isDeclaration())
+ return ELFSym::STT_NOTYPE;
+
+ if (isa<Function>(GV))
+ return ELFSym::STT_FUNC;
+
+ return ELFSym::STT_OBJECT;
+}
+
+// getElfSectionFlags - Get the ELF Section Header flags based
+// on the flags defined in SectionKind.h.
+unsigned ELFWriter::getElfSectionFlags(SectionKind Kind, bool IsAlloc) {
+ unsigned ElfSectionFlags = 0;
+
+ if (IsAlloc)
+ ElfSectionFlags |= ELFSection::SHF_ALLOC;
+ if (Kind.isText())
+ ElfSectionFlags |= ELFSection::SHF_EXECINSTR;
+ if (Kind.isWriteable())
+ ElfSectionFlags |= ELFSection::SHF_WRITE;
+ if (Kind.isMergeableConst() || Kind.isMergeableCString())
+ ElfSectionFlags |= ELFSection::SHF_MERGE;
+ if (Kind.isThreadLocal())
+ ElfSectionFlags |= ELFSection::SHF_TLS;
+ if (Kind.isMergeableCString())
+ ElfSectionFlags |= ELFSection::SHF_STRINGS;
+
+ return ElfSectionFlags;
+}
+
+// isUndefOrNull - The constant is either a null initialized value or an
+// undefined one.
+static bool isUndefOrNull(const Constant *CV) {
+ return (CV->isNullValue() || isa<UndefValue>(CV));
+}
+
+// isELFUndefSym - the symbol has no section and must be placed in
+// the symbol table with a reference to the null section.
+static bool isELFUndefSym(const GlobalValue *GV) {
+ // Functions which make up until this point references are an undef symbol
+ return GV->isDeclaration() || (isa<Function>(GV));
+}
+
+// isELFBssSym - for an undef or null value, the symbol must go to a bss
+// section if it's not weak for linker, otherwise it's a common sym.
+static bool isELFBssSym(const GlobalVariable *GV, SectionKind Kind) {
+ const Constant *CV = GV->getInitializer();
+
+ return (!Kind.isMergeableCString() &&
+ isUndefOrNull(CV) &&
+ !GV->isWeakForLinker());
+}
+
+// isELFCommonSym - for an undef or null value, the symbol must go to a
+// common section if it's weak for linker, otherwise bss.
+static bool isELFCommonSym(const GlobalVariable *GV) {
+ return (isUndefOrNull(GV->getInitializer()) && GV->isWeakForLinker());
+}
+
+// EmitGlobal - Choose the right section for global and emit it
+void ELFWriter::EmitGlobal(const GlobalValue *GV) {
+
+ // Check if the referenced symbol is already emitted
+ if (GblSymLookup.find(GV) != GblSymLookup.end())
+ return;
+
+ // Handle ELF Bind, Visibility and Type for the current symbol
+ unsigned SymBind = getGlobalELFBinding(GV);
+ unsigned SymType = getGlobalELFType(GV);
+
+ // All undef symbols have the same binding, type and visibily and
+ // are classified regardless of their type.
+ ELFSym *GblSym = isELFUndefSym(GV) ? ELFSym::getUndefGV(GV, SymBind)
+ : ELFSym::getGV(GV, SymBind, SymType, getGlobalELFVisibility(GV));
+
+ if (!isELFUndefSym(GV)) {
+ assert(isa<GlobalVariable>(GV) && "GV not a global variable!");
+ const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
+
+ // Handle special llvm globals
+ if (EmitSpecialLLVMGlobal(GVar))