new llvm::GlobalVariable(module,
stringConstant->getType(),
true,
- llvm::GlobalValue::LinkerPrivateLinkage,
+ llvm::GlobalValue::PrivateLinkage,
stringConstant,
"");
}
new llvm::GlobalVariable(module,
stringConstant->getType(),
true,
- llvm::GlobalValue::LinkerPrivateLinkage,
+ llvm::GlobalValue::PrivateLinkage,
stringConstant,
"");
}
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *getCurrentSection() const;
+ void getNameWithPrefix(SmallVectorImpl<char> &Name,
+ const GlobalValue *GV) const;
+
MCSymbol *getSymbol(const GlobalValue *GV) const;
//===------------------------------------------------------------------===//
/// Return an MCExpr to use for a reference to the specified type info global
/// variable from exception handling information.
- const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
- unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI,
- MCStreamer &Streamer) const
+ const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI, MCStreamer &Streamer) const
LLVM_OVERRIDE;
// The symbol that gets passed to .cfi_personality.
MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
+ const TargetMachine &TM,
MachineModuleInfo *MMI) const LLVM_OVERRIDE;
void InitializeELF(bool UseInitArray_);
Mangler &Mang, const TargetMachine &TM) const
LLVM_OVERRIDE;
+ bool isSectionAtomizableBySymbols(const MCSection &Section) const
+ LLVM_OVERRIDE;
+
const MCSection *SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind, Mangler &Mang,
const TargetMachine &TM) const
/// This hook allows targets to selectively decide not to emit the
/// UsedDirective for some symbols in llvm.used.
/// FIXME: REMOVE this (rdar://7071300)
- bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler &Mang) const
- LLVM_OVERRIDE;
+ bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler &Mang,
+ TargetMachine &TM) const LLVM_OVERRIDE;
/// The mach-o version of this method defaults to returning a stub reference.
- const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
- unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI,
- MCStreamer &Streamer) const
+ const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI, MCStreamer &Streamer) const
LLVM_OVERRIDE;
// The symbol that gets passed to .cfi_personality.
MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
+ const TargetMachine &TM,
MachineModuleInfo *MMI) const LLVM_OVERRIDE;
};
/// Print the appropriate prefix and the specified global variable's name.
/// If the global variable doesn't have a name, this fills in a unique name
/// for the global.
- void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV) const;
- void getNameWithPrefix(SmallVectorImpl<char> &OutName,
- const GlobalValue *GV) const;
+ void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
+ bool CannotUsePrivateLabel) const;
+ void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
+ bool CannotUsePrivateLabel) const;
/// Print the appropriate prefix and the specified name as the global variable
/// name. GVName must not be empty.
class MachineFunction;
class MachineInstr;
class MachineJumpTableInfo;
+ class Mangler;
class MCContext;
class MCExpr;
+ class MCSymbol;
template<typename T> class SmallVectorImpl;
class DataLayout;
class TargetRegisterClass;
return LibcallCallingConvs[Call];
}
+ void getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV,
+ Mangler &Mang, bool MayAlwaysUsePrivate = false) const;
+ MCSymbol *getSymbol(const GlobalValue *GV, Mangler &Mang) const;
+
private:
const TargetMachine &TM;
const DataLayout *DL;
/// This hook allows targets to selectively decide not to emit the
/// UsedDirective for some symbols in llvm.used.
/// FIXME: REMOVE this (rdar://7071300)
- virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
- Mangler &Mang) const {
+ virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler &Mang,
+ TargetMachine &TM) const {
return GV != 0;
}
/// Return an MCExpr to use for a reference to the specified global variable
/// from exception handling information.
- virtual const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
- unsigned Encoding,
- Mangler &Mang,
- MachineModuleInfo *MMI,
- MCStreamer &Streamer) const;
-
- /// Return the MCSymbol for the specified global value. This symbol is the
- /// main label that is the address of the global
- MCSymbol *getSymbol(const GlobalValue *GV, Mangler &M) const;
+ virtual const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI, MCStreamer &Streamer) const;
/// Return the MCSymbol for a private symbol with global value name as its
/// base, with the specified suffix.
MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,
- StringRef Suffix, Mangler &M) const;
+ StringRef Suffix, Mangler &Mang,
+ const TargetMachine &TM) const;
// The symbol that gets passed to .cfi_personality.
- virtual MCSymbol *
- getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
- MachineModuleInfo *MMI) const;
+ virtual MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV,
+ Mangler &Mang,
+ const TargetMachine &TM,
+ MachineModuleInfo *MMI) const;
const MCExpr *
getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const;
virtual const MCExpr *
- getExecutableRelativeSymbol(const ConstantExpr *CE, Mangler &Mang) const {
+ getExecutableRelativeSymbol(const ConstantExpr *CE, Mangler &Mang,
+ const TargetMachine &TM) const {
return 0;
}
+ /// \brief True if the section is atomized using the symbols in it.
+ /// This is false if the section is not atomized at all (most ELF sections) or
+ /// if it is atomized based on its contents (MachO' __TEXT,__cstring for
+ /// example).
+ virtual bool isSectionAtomizableBySymbols(const MCSection &Section) const;
+
protected:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
llvm_unreachable("Unknown linkage type!");
}
+void AsmPrinter::getNameWithPrefix(SmallVectorImpl<char> &Name,
+ const GlobalValue *GV) const {
+ TM.getTargetLowering()->getNameWithPrefix(Name, GV, *Mang);
+}
+
MCSymbol *AsmPrinter::getSymbol(const GlobalValue *GV) const {
- return getObjFileLowering().getSymbol(GV, *Mang);
+ return TM.getTargetLowering()->getSymbol(GV, *Mang);
}
/// EmitGlobalVariable - Emit the specified global variable to the .s file.
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
const GlobalValue *GV =
dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());
- if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, *Mang))
+ if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, *Mang, TM))
OutStreamer.EmitSymbolAttribute(getSymbol(GV), MCSA_NoDeadStrip);
}
}
}
if (const MCExpr *RelocExpr =
- AP.getObjFileLowering().getExecutableRelativeSymbol(CE, *AP.Mang))
+ AP.getObjFileLowering().getExecutableRelativeSymbol(CE, *AP.Mang,
+ AP.TM))
return RelocExpr;
switch (CE->getOpcode()) {
MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV,
StringRef Suffix) const {
- return getObjFileLowering().getSymbolWithGlobalValueBase(GV, Suffix, *Mang);
+ return getObjFileLowering().getSymbolWithGlobalValueBase(GV, Suffix, *Mang,
+ TM);
}
/// GetExternalSymbolSymbol - Return the MCSymbol for the specified
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
const MCExpr *Exp =
- TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, MMI, OutStreamer);
+ TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, TM, MMI, OutStreamer);
OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
} else
OutStreamer.EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
if (!shouldEmitPersonality)
return;
- const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, MMI);
+ const MCSymbol *Sym =
+ TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
Asm->OutStreamer.EmitCFIPersonality(Sym, PerEncoding);
Asm->OutStreamer.EmitDebugLabel
if (shouldEmitPersonality) {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()];
- const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, MMI);
+ const MCSymbol *Sym =
+ TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
Asm->OutStreamer.PushSection();
Asm->OutStreamer.EmitWin64EHHandlerData();
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
return true;
}
+
+void TargetLoweringBase::getNameWithPrefix(SmallVectorImpl<char> &Name,
+ const GlobalValue *GV,
+ Mangler &Mang,
+ bool MayAlwaysUsePrivate) const {
+ if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
+ // Simple case: If GV is not private, it is not important to find out if
+ // private labels are legal in this case or not.
+ Mang.getNameWithPrefix(Name, GV, false);
+ return;
+ }
+ SectionKind GVKind =
+ TargetLoweringObjectFile::getKindForGlobal(GV, getTargetMachine());
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering();
+ const MCSection *TheSection =
+ TLOF.SectionForGlobal(GV, GVKind, Mang, getTargetMachine());
+ bool CannotUsePrivateLabel = TLOF.isSectionAtomizableBySymbols(*TheSection);
+ Mang.getNameWithPrefix(Name, GV, CannotUsePrivateLabel);
+}
+
+MCSymbol *TargetLoweringBase::getSymbol(const GlobalValue *GV,
+ Mangler &Mang) const {
+ SmallString<60> NameStr;
+ getNameWithPrefix(NameStr, GV, Mang);
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering();
+ return TLOF.getContext().GetOrCreateSymbol(NameStr.str());
+}
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetLowering.h"
using namespace llvm;
using namespace dwarf;
// ELF
//===----------------------------------------------------------------------===//
-MCSymbol *
-TargetLoweringObjectFileELF::getCFIPersonalitySymbol(const GlobalValue *GV,
- Mangler &Mang,
- MachineModuleInfo *MMI) const {
+MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
+ const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI) const {
unsigned Encoding = getPersonalityEncoding();
switch (Encoding & 0x70) {
default:
report_fatal_error("We do not support this DWARF encoding yet!");
case dwarf::DW_EH_PE_absptr:
- return getSymbol(GV, Mang);
+ return TM.getTargetLowering()->getSymbol(GV, Mang);
case dwarf::DW_EH_PE_pcrel: {
return getContext().GetOrCreateSymbol(StringRef("DW.ref.") +
- getSymbol(GV, Mang)->getName());
+ TM.getTargetLowering()->getSymbol(GV, Mang)->getName());
}
}
}
const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(
const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+ const TargetMachine &TM, MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const {
if (Encoding & dwarf::DW_EH_PE_indirect) {
MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
- MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang);
+ MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang, TM);
// Add information about the stub reference to ELFMMI so that the stub
// gets emitted by the asmprinter.
MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
if (StubSym.getPointer() == 0) {
- MCSymbol *Sym = getSymbol(GV, Mang);
+ MCSymbol *Sym = TM.getTargetLowering()->getSymbol(GV, Mang);
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
}
Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
}
- return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, Mang,
- MMI, Streamer);
+ return TargetLoweringObjectFile::
+ getTTypeGlobalReference(GV, Encoding, Mang, TM, MMI, Streamer);
}
static SectionKind
return Flags;
}
-
-const MCSection *TargetLoweringObjectFileELF::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler &Mang, const TargetMachine &TM) const {
+const MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
+ const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const {
StringRef SectionName = GV->getSection();
// Infer section flags from the section name if we can.
Prefix = getSectionPrefixForGlobal(Kind);
SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
- MCSymbol *Sym = getSymbol(GV, Mang);
- Name.append(Sym->getName().begin(), Sym->getName().end());
+ TM.getTargetLowering()->getNameWithPrefix(Name, GV, Mang, true);
+
StringRef Group = "";
unsigned Flags = getELFSectionFlags(Kind);
if (GV->isWeakForLinker()) {
- Group = Sym->getName();
+ Group = Name.substr(strlen(Prefix));
Flags |= ELF::SHF_GROUP;
}
Streamer.AddBlankLine();
}
-const MCSection *TargetLoweringObjectFileMachO::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler &Mang, const TargetMachine &TM) const {
+const MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
+ const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const {
// Parse the section specifier and create it if valid.
StringRef Segment, Section;
unsigned TAA = 0, StubSize = 0;
return S;
}
+bool TargetLoweringObjectFileMachO::isSectionAtomizableBySymbols(
+ const MCSection &Section) const {
+ const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
+
+ // Sections holding 1 byte strings are atomized based on the data
+ // they contain.
+ // Sections holding 2 byte strings require symbols in order to be
+ // atomized.
+ // There is no dedicated section for 4 byte strings.
+ if (SMO.getKind().isMergeable1ByteCString())
+ return false;
+
+ if (SMO.getSegmentName() == "__DATA" &&
+ SMO.getSectionName() == "__cfstring")
+ return false;
+
+ switch (SMO.getType()) {
+ default:
+ return true;
+
+ // These sections are atomized at the element boundaries without using
+ // symbols.
+ case MCSectionMachO::S_4BYTE_LITERALS:
+ case MCSectionMachO::S_8BYTE_LITERALS:
+ case MCSectionMachO::S_16BYTE_LITERALS:
+ case MCSectionMachO::S_LITERAL_POINTERS:
+ case MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS:
+ case MCSectionMachO::S_LAZY_SYMBOL_POINTERS:
+ case MCSectionMachO::S_MOD_INIT_FUNC_POINTERS:
+ case MCSectionMachO::S_MOD_TERM_FUNC_POINTERS:
+ case MCSectionMachO::S_INTERPOSING:
+ return false;
+ }
+}
+
const MCSection *TargetLoweringObjectFileMachO::
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler &Mang, const TargetMachine &TM) const {
return ReadOnlySection; // .const
}
-/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively decide
-/// not to emit the UsedDirective for some symbols in llvm.used.
+/// This hook allows targets to selectively decide not to emit the UsedDirective
+/// for some symbols in llvm.used.
// FIXME: REMOVE this (rdar://7071300)
-bool TargetLoweringObjectFileMachO::
-shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler &Mang) const {
- /// On Darwin, internally linked data beginning with "L" or "l" does not have
- /// the directive emitted (this occurs in ObjC metadata).
- if (!GV) return false;
-
+bool TargetLoweringObjectFileMachO::shouldEmitUsedDirectiveFor(
+ const GlobalValue *GV, Mangler &Mang, TargetMachine &TM) const {
// Check whether the mangled name has the "Private" or "LinkerPrivate" prefix.
if (GV->hasLocalLinkage() && !isa<Function>(GV)) {
// FIXME: ObjC metadata is currently emitted as internal symbols that have
// \1L and \0l prefixes on them. Fix them to be Private/LinkerPrivate and
// this horrible hack can go away.
- MCSymbol *Sym = getSymbol(GV, Mang);
+ MCSymbol *Sym = TM.getTargetLowering()->getSymbol(GV, Mang);
if (Sym->getName()[0] == 'L' || Sym->getName()[0] == 'l')
return false;
}
const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference(
const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+ const TargetMachine &TM, MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const {
// The mach-o version of this method defaults to returning a stub reference.
if (Encoding & DW_EH_PE_indirect) {
MachineModuleInfoMachO &MachOMMI =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
- MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang);
+ MCSymbol *SSym =
+ getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang, TM);
// Add information about the stub reference to MachOMMI so that the stub
// gets emitted by the asmprinter.
GV->hasHiddenVisibility() ? MachOMMI.getHiddenGVStubEntry(SSym) :
MachOMMI.getGVStubEntry(SSym);
if (StubSym.getPointer() == 0) {
- MCSymbol *Sym = getSymbol(GV, Mang);
+ MCSymbol *Sym = TM.getTargetLowering()->getSymbol(GV, Mang);
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
}
Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
}
- return TargetLoweringObjectFile::
- getTTypeGlobalReference(GV, Encoding, Mang, MMI, Streamer);
+ return TargetLoweringObjectFile::getTTypeGlobalReference(GV, Encoding, Mang,
+ TM, MMI, Streamer);
}
-MCSymbol *TargetLoweringObjectFileMachO::
-getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
- MachineModuleInfo *MMI) const {
+MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol(
+ const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI) const {
// The mach-o version of this method defaults to returning a stub reference.
MachineModuleInfoMachO &MachOMMI =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
- MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang);
+ MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr", Mang, TM);
// Add information about the stub reference to MachOMMI so that the stub
// gets emitted by the asmprinter.
MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
if (StubSym.getPointer() == 0) {
- MCSymbol *Sym = getSymbol(GV, Mang);
+ MCSymbol *Sym = TM.getTargetLowering()->getSymbol(GV, Mang);
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
}
return Flags;
}
-const MCSection *TargetLoweringObjectFileCOFF::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler &Mang, const TargetMachine &TM) const {
+const MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
+ const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const {
int Selection = 0;
unsigned Characteristics = getCOFFSectionFlags(Kind);
StringRef Name = GV->getSection();
if (GV->isWeakForLinker()) {
Selection = COFF::IMAGE_COMDAT_SELECT_ANY;
Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
- MCSymbol *Sym = getSymbol(GV, Mang);
+ MCSymbol *Sym = TM.getTargetLowering()->getSymbol(GV, Mang);
COMDATSymName = Sym->getName();
}
return getContext().getCOFFSection(Name,
unsigned Characteristics = getCOFFSectionFlags(Kind);
Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
- MCSymbol *Sym = getSymbol(GV, Mang);
+ MCSymbol *Sym = TM.getTargetLowering()->getSymbol(GV, Mang);
return getContext().getCOFFSection(Name, Characteristics,
Kind, Sym->getName(),
COFF::IMAGE_COMDAT_SELECT_ANY);
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MutexGuard.h"
+#include "llvm/Target/TargetLowering.h"
using namespace llvm;
// load address of the symbol, not the local address.
Mangler Mang(TM->getDataLayout());
SmallString<128> Name;
- Mang.getNameWithPrefix(Name, F);
+ TM->getTargetLowering()->getNameWithPrefix(Name, F, Mang);
return (void*)Dyld.getSymbolLoadAddress(Name);
}
OS << '@' << ArgWords;
}
-void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV) const {
+void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
+ bool CannotUsePrivateLabel) const {
ManglerPrefixTy PrefixTy = Mangler::Default;
- if (GV->hasPrivateLinkage())
- PrefixTy = Mangler::Private;
- else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage())
+ if (GV->hasPrivateLinkage()) {
+ if (CannotUsePrivateLabel)
+ PrefixTy = Mangler::LinkerPrivate;
+ else
+ PrefixTy = Mangler::Private;
+ } else if (GV->hasLinkerPrivateLinkage() ||
+ GV->hasLinkerPrivateWeakLinkage()) {
PrefixTy = Mangler::LinkerPrivate;
+ }
if (!GV->hasName()) {
// Get the ID for the global, assigning a new one if we haven't got one
}
void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
- const GlobalValue *GV) const {
+ const GlobalValue *GV,
+ bool CannotUsePrivateLabel) const {
raw_svector_ostream OS(OutName);
- getNameWithPrefix(OS, GV);
+ getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
}
std::vector<const char*> &MustPreserveList,
SmallPtrSet<GlobalValue*, 8> &AsmUsed,
Mangler &Mangler) {
- SmallString<64> Buffer;
- Mangler.getNameWithPrefix(Buffer, &GV);
-
+ // There are no restrictions to apply to declarations.
if (GV.isDeclaration())
return;
+
+ // There is nothing more restrictive than private linkage.
+ if (GV.hasPrivateLinkage())
+ return;
+
+ SmallString<64> Buffer;
+ TargetMach->getTargetLowering()->getNameWithPrefix(Buffer, &GV, Mangler);
+
if (MustPreserveSymbols.count(Buffer))
MustPreserveList.push_back(GV.getName().data());
if (AsmUndefinedRefs.count(Buffer))
m->materializeAllPermanently();
LTOModule *Ret = new LTOModule(m.take(), target);
+
+ // We need a MCContext set up in order to get mangled names of private
+ // symbols. It is a bit odd that we need to report uses and definitions
+ // of private symbols, but it does look like ld64 expects to be informed
+ // of at least the ones with an 'l' prefix.
+ MCContext &Context = Ret->_context;
+ const TargetLoweringObjectFile &TLOF =
+ target->getTargetLowering()->getObjFileLowering();
+ const_cast<TargetLoweringObjectFile &>(TLOF).Initialize(Context, *target);
+
if (Ret->parseSymbols(errMsg)) {
delete Ret;
return NULL;
// string is owned by _defines
SmallString<64> Buffer;
- _mangler.getNameWithPrefix(Buffer, def);
+ _target->getTargetLowering()->getNameWithPrefix(Buffer, def, _mangler);
// set alignment part log2() can have rounding errors
uint32_t align = def->getAlignment();
return;
SmallString<64> name;
- _mangler.getNameWithPrefix(name, decl);
+ _target->getTargetLowering()->getNameWithPrefix(name, decl, _mangler);
StringMap<NameAndAttributes>::value_type &entry =
_undefines.GetOrCreateValue(name);
#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ELF.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetLowering.h"
using namespace llvm;
using namespace dwarf;
const MCExpr *ARMElfTargetObjectFile::getTTypeGlobalReference(
const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+ const TargetMachine &TM, MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const {
assert(Encoding == DW_EH_PE_absptr && "Can handle absptr encoding only");
- return MCSymbolRefExpr::Create(getSymbol(GV, Mang),
- MCSymbolRefExpr::VK_ARM_TARGET2,
- getContext());
+ return MCSymbolRefExpr::Create(TM.getTargetLowering()->getSymbol(GV, Mang),
+ MCSymbolRefExpr::VK_ARM_TARGET2, getContext());
}
const MCExpr *ARMElfTargetObjectFile::
void Initialize(MCContext &Ctx, const TargetMachine &TM) LLVM_OVERRIDE;
- const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
- unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI,
- MCStreamer &Streamer) const
+ const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI, MCStreamer &Streamer) const
LLVM_OVERRIDE;
/// \brief Describe a TLS variable address within debug info.
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
using namespace llvm;
static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) {
static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){
- const DataLayout *DL = AP.TM.getDataLayout();
+ const TargetMachine &TM = AP.TM;
+ Mangler *Mang = AP.Mang;
+ const DataLayout *DL = TM.getDataLayout();
MCContext &Ctx = AP.OutContext;
SmallString<128> Name;
if (!MO.isGlobal()) {
assert(MO.isSymbol() && "Isn't a symbol reference");
- AP.Mang->getNameWithPrefix(Name, MO.getSymbolName());
+ Mang->getNameWithPrefix(Name, MO.getSymbolName());
} else {
const GlobalValue *GV = MO.getGlobal();
- AP.Mang->getNameWithPrefix(Name, GV);
+ TM.getTargetLowering()->getNameWithPrefix(Name, GV, *Mang);
}
unsigned OrigLen = Name.size() - PrefixLen;
#include "MCTargetDesc/SparcMCExpr.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/Support/Dwarf.h"
+#include "llvm/Target/TargetLowering.h"
using namespace llvm;
const MCExpr *SparcELFTargetObjectFile::getTTypeGlobalReference(
const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+ const TargetMachine &TM, MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const {
if (Encoding & dwarf::DW_EH_PE_pcrel) {
MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
- MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang);
+ MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang, TM);
// Add information about the stub reference to ELFMMI so that the stub
// gets emitted by the asmprinter.
MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
if (StubSym.getPointer() == 0) {
- MCSymbol *Sym = getSymbol(GV, Mang);
+ MCSymbol *Sym = TM.getTargetLowering()->getSymbol(GV, Mang);
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
}
}
return TargetLoweringObjectFileELF::getTTypeGlobalReference(
- GV, Encoding, Mang, MMI, Streamer);
+ GV, Encoding, Mang, TM, MMI, Streamer);
}
TargetLoweringObjectFileELF()
{}
- const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
- unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI,
- MCStreamer &Streamer) const
+ const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI, MCStreamer &Streamer) const
LLVM_OVERRIDE;
};
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
return false;
}
-/// Return the MCSymbol for the specified global value. This
-/// symbol is the main label that is the address of the global.
-MCSymbol *TargetLoweringObjectFile::getSymbol(const GlobalValue *GV,
- Mangler &M) const {
- SmallString<60> NameStr;
- M.getNameWithPrefix(NameStr, GV);
- return Ctx->GetOrCreateSymbol(NameStr.str());
-}
-
MCSymbol *TargetLoweringObjectFile::getSymbolWithGlobalValueBase(
- const GlobalValue *GV, StringRef Suffix, Mangler &M) const {
+ const GlobalValue *GV, StringRef Suffix, Mangler &Mang,
+ const TargetMachine &TM) const {
assert(!Suffix.empty());
SmallString<60> NameStr;
NameStr += DL->getPrivateGlobalPrefix();
- M.getNameWithPrefix(NameStr, GV);
+ TM.getTargetLowering()->getNameWithPrefix(NameStr, GV, Mang);
NameStr.append(Suffix.begin(), Suffix.end());
return Ctx->GetOrCreateSymbol(NameStr.str());
}
-MCSymbol *TargetLoweringObjectFile::
-getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
- MachineModuleInfo *MMI) const {
- return getSymbol(GV, Mang);
+MCSymbol *TargetLoweringObjectFile::getCFIPersonalitySymbol(
+ const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI) const {
+ return TM.getTargetLowering()->getSymbol(GV, Mang);
}
void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer,
return SelectSectionForGlobal(GV, Kind, Mang, TM);
}
+bool TargetLoweringObjectFile::isSectionAtomizableBySymbols(
+ const MCSection &Section) const {
+ return false;
+}
// Lame default implementation. Calculate the section name for global.
const MCSection *
/// handling information.
const MCExpr *TargetLoweringObjectFile::getTTypeGlobalReference(
const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+ const TargetMachine &TM, MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const {
const MCSymbolRefExpr *Ref =
- MCSymbolRefExpr::Create(getSymbol(GV, Mang), getContext());
+ MCSymbolRefExpr::Create(TM.getTargetLowering()->getSymbol(GV, Mang),
+ getContext());
return getTTypeReference(Ref, Encoding, Streamer);
}
if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
- getMang()->getNameWithPrefix(Name, GV);
+ AsmPrinter.getNameWithPrefix(Name, GV);
} else if (MO.isSymbol()) {
getMang()->getNameWithPrefix(Name, MO.getSymbolName());
} else if (MO.isMBB()) {
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/Dwarf.h"
+#include "llvm/Target/TargetLowering.h"
using namespace llvm;
using namespace dwarf;
const MCExpr *X86_64MachoTargetObjectFile::getTTypeGlobalReference(
const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+ const TargetMachine &TM, MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const {
// On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which
// is an indirect pc-relative reference.
if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) {
- const MCSymbol *Sym = getSymbol(GV, Mang);
+ const MCSymbol *Sym = TM.getTargetLowering()->getSymbol(GV, Mang);
const MCExpr *Res =
MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext());
const MCExpr *Four = MCConstantExpr::Create(4, getContext());
}
return TargetLoweringObjectFileMachO::getTTypeGlobalReference(
- GV, Encoding, Mang, MMI, Streamer);
+ GV, Encoding, Mang, TM, MMI, Streamer);
}
-MCSymbol *X86_64MachoTargetObjectFile::
-getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
- MachineModuleInfo *MMI) const {
- return getSymbol(GV, Mang);
+MCSymbol *X86_64MachoTargetObjectFile::getCFIPersonalitySymbol(
+ const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI) const {
+ return TM.getTargetLowering()->getSymbol(GV, Mang);
}
void
return MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_DTPOFF, getContext());
}
-const MCExpr *
-X86WindowsTargetObjectFile::getExecutableRelativeSymbol(const ConstantExpr *CE,
- Mangler &Mang) const {
+const MCExpr *X86WindowsTargetObjectFile::getExecutableRelativeSymbol(
+ const ConstantExpr *CE, Mangler &Mang, const TargetMachine &TM) const {
// We are looking for the difference of two symbols, need a subtraction
// operation.
const SubOperator *Sub = dyn_cast<SubOperator>(CE);
if (GVLHS->isThreadLocal())
return 0;
- return MCSymbolRefExpr::Create(
- getSymbol(GVLHS, Mang), MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
+ return MCSymbolRefExpr::Create(TM.getTargetLowering()->getSymbol(GVLHS, Mang),
+ MCSymbolRefExpr::VK_COFF_IMGREL32,
+ getContext());
}
/// x86-64.
class X86_64MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
public:
- const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
- unsigned Encoding, Mangler &Mang,
- MachineModuleInfo *MMI,
- MCStreamer &Streamer) const
+ const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI, MCStreamer &Streamer) const
LLVM_OVERRIDE;
// getCFIPersonalitySymbol - The symbol that gets passed to
// .cfi_personality.
MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
+ const TargetMachine &TM,
MachineModuleInfo *MMI) const
LLVM_OVERRIDE;
};
/// \brief This implementation is used for Windows targets on x86 and x86-64.
class X86WindowsTargetObjectFile : public TargetLoweringObjectFileCOFF {
const MCExpr *getExecutableRelativeSymbol(const ConstantExpr *CE,
- Mangler &Mang) const
+ Mangler &Mang,
+ const TargetMachine &TM) const
LLVM_OVERRIDE;
};
return Flags;
}
-const MCSection *XCoreTargetObjectFile::
-getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler &Mang, const TargetMachine &TM) const {
+const MCSection *
+XCoreTargetObjectFile::getExplicitSectionGlobal(const GlobalValue *GV,
+ SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const {
StringRef SectionName = GV->getSection();
// Infer section flags from the section name if we can.
bool IsCPRel = SectionName.startswith(".cp.");
static GlobalVariable *createPrivateGlobalForString(
Module &M, StringRef Str, bool AllowMerging) {
Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
- // For module-local strings that can be merged with another one we set the
- // private linkage and the unnamed_addr attribute.
- // Non-mergeable strings are made linker_private to remove them from the
- // symbol table. "private" linkage doesn't work for Darwin, where the
- // "L"-prefixed globals end up in __TEXT,__const section
- // (see http://llvm.org/bugs/show_bug.cgi?id=17976 for more info).
- GlobalValue::LinkageTypes linkage =
- AllowMerging ? GlobalValue::PrivateLinkage
- : GlobalValue::LinkerPrivateLinkage;
+ // We use private linkage for module-local strings. If they can be merged
+ // with another one, we set the unnamed_addr attribute.
GlobalVariable *GV =
new GlobalVariable(M, StrConst->getType(), true,
- linkage, StrConst, kAsanGenPrefix);
- if (AllowMerging) GV->setUnnamedAddr(true);
+ GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix);
+ if (AllowMerging)
+ GV->setUnnamedAddr(true);
GV->setAlignment(1); // Strings may not be merged w/o setting align 1.
return GV;
}
; RUN: FileCheck --check-prefix=OSX %s
; LINUX: .Lfoo:
-; OSX: L_foo:
+; OSX: l_foo:
define private void @foo() nounwind {
ret void
}
define i32 @bar() nounwind {
; LINUX: bl{{.*}}.Lfoo
-; OSX: bl{{.*}}L_foo
+; OSX: bl{{.*}}l_foo
call void @foo()
; LINUX: lis{{.*}}.Lbaz
-; OSX: lis{{.*}}L_baz
+; OSX: lis{{.*}}l_baz
%1 = load i32* @baz, align 4
ret i32 %1
}
; LINUX: .Lbaz:
-; OSX: L_baz:
+; OSX: l_baz:
@baz = private global i32 4
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
; rdar://7396984
-@str = private constant [28 x i8] c"xxxxxxxxxxxxxxxxxxxxxxxxxxx\00", align 1
+@str = private unnamed_addr constant [28 x i8] c"xxxxxxxxxxxxxxxxxxxxxxxxxxx\00", align 1
define void @t(i32 %count) ssp nounwind {
entry:
; DARWIN: .zerofill __DATA,__common,_G12,1,3
; DARWIN: .globl _G13
; DARWIN: .zerofill __DATA,__common,_G13,1,3
+
+@G14 = private unnamed_addr constant [4 x i8] c"foo\00", align 1
+
+; LINUX-SECTIONS: .type .LG14,@object # @G14
+; LINUX-SECTIONS: .section .rodata..LG14,"aMS",@progbits,1
+; LINUX-SECTIONS: .LG14:
+; LINUX-SECTIONS: .asciz "foo"
+; LINUX-SECTIONS: .size .LG14, 4
--- /dev/null
+; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
+; Test all the cases where a L label is safe. Removing any entry from
+; TargetLoweringObjectFileMachO::isSectionAtomizableBySymbols should cause
+; this to fail.
+; We also test some noteworthy cases that require an l label.
+
+@private1 = private unnamed_addr constant [4 x i8] c"zed\00"
+; CHECK: .section __TEXT,__cstring,cstring_literals
+; CHECK-NEXT: L_private1:
+
+@private2 = private unnamed_addr constant [5 x i16] [i16 116, i16 101,
+ i16 115, i16 116, i16 0]
+; CHECK: .section __TEXT,__ustring
+; CHECK-NEXT: .align 1
+; CHECK-NEXT: l_private2:
+
+; There is no dedicated 4 byte strings on MachO.
+
+%struct.NSConstantString = type { i32*, i32, i8*, i32 }
+@private3 = private constant %struct.NSConstantString { i32* null, i32 1992, i8* null, i32 0 }, section "__DATA,__cfstring"
+; CHECK: .section __DATA,__cfstring
+; CHECK-NEXT: .align 4
+; CHECK-NEXT: L_private3:
+
+; There is no dedicated 1 or 2 byte constant section on MachO.
+
+@private4 = private unnamed_addr constant i32 42
+; CHECK: .section __TEXT,__literal4,4byte_literals
+; CHECK-NEXT: .align 2
+; CHECK-NEXT: L_private4:
+
+@private5 = private unnamed_addr constant i64 42
+; CHECK: .section __TEXT,__literal8,8byte_literals
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: L_private5:
+
+@private6 = private unnamed_addr constant i128 42
+; CHECK: .section __TEXT,__literal16,16byte_literals
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: L_private6:
+
+%struct._objc_class = type { i8* }
+@private7 = private global %struct._objc_class* null, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip"
+; CHECK: .section __OBJC,__cls_refs,literal_pointers,no_dead_strip
+; CHECK: .align 3
+; CHECK: L_private7:
+
+@private8 = private global i32* null, section "__DATA,__nl_symbol_ptr,non_lazy_symbol_pointers"
+; CHECK: .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: L_private8:
+
+@private9 = private global i32* null, section "__DATA,__la_symbol_ptr,lazy_symbol_pointers"
+; CHECK: .section __DATA,__la_symbol_ptr,lazy_symbol_pointers
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: L_private9:
+
+@private10 = private global i32* null, section "__DATA,__mod_init_func,mod_init_funcs"
+; CHECK: .section __DATA,__mod_init_func,mod_init_funcs
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: L_private10:
+
+@private11 = private global i32* null, section "__DATA,__mod_term_func,mod_term_funcs"
+; CHECK: .section __DATA,__mod_term_func,mod_term_funcs
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: L_private11:
+
+@private12 = private global i32* null, section "__DATA,__foobar,interposing"
+; CHECK: .section __DATA,__foobar,interposing
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: L_private12:
ret void;
}
-; CHECK: L_foo: ## @foo
+; CHECK: l_foo: ## @foo
; CHECK-NEXT: Ltmp0:
; CHECK: _bar: ## @bar
; CHECK-NEXT: {{.quad|.long}} Ltmp[[NUM2]]
-; OLD: L_foo: ## @foo
+; OLD: l_foo: ## @foo
; OLD-NEXT: Ltmp0:
; OLD: _bar: ## @bar
; Quote should be outside of private prefix.
; rdar://6855766x
-; CHECK: L__ZZ20
+; CHECK: "l__ZZ20-[Example1 whatever]E4C.91"
%struct.A = type { i32*, i32 }
@"_ZZ20-[Example1 whatever]E4C.91" = private constant %struct.A { i32* null, i32 1 } ; <%struct.A*> [#uses=1]
; module ctor/dtor
; CHECK: llvm.global_ctors
+; CHECK: @__asan_gen_ = private constant [8 x i8] c"<stdin>\00", align 1
; CHECK: llvm.global_dtors
; Test that we don't instrument global arrays with static initializer
--- /dev/null
+; RUN: llvm-as < %s >%t1
+; RUN: llvm-lto -o %t2 %t1
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1