LLVM API Documentation
00001 //===-- ELFTargetAsmInfo.cpp - ELF asm properties ---------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines target asm properties related what form asm statements 00011 // should take in general on ELF-based targets 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "llvm/Constants.h" 00016 #include "llvm/DerivedTypes.h" 00017 #include "llvm/Function.h" 00018 #include "llvm/GlobalVariable.h" 00019 #include "llvm/ADT/StringExtras.h" 00020 #include "llvm/CodeGen/MachineConstantPool.h" 00021 #include "llvm/Target/ELFTargetAsmInfo.h" 00022 #include "llvm/Target/TargetMachine.h" 00023 #include "llvm/Target/TargetData.h" 00024 00025 using namespace llvm; 00026 00027 ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) 00028 : TargetAsmInfo(TM) { 00029 00030 BSSSection_ = getUnnamedSection("\t.bss", 00031 SectionFlags::Writeable | SectionFlags::BSS); 00032 ReadOnlySection = getNamedSection("\t.rodata", SectionFlags::None); 00033 TLSDataSection = getNamedSection("\t.tdata", 00034 SectionFlags::Writeable | SectionFlags::TLS); 00035 TLSBSSSection = getNamedSection("\t.tbss", 00036 SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS); 00037 00038 } 00039 00040 const Section* 00041 ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { 00042 SectionKind::Kind Kind = SectionKindForGlobal(GV); 00043 00044 if (const Function *F = dyn_cast<Function>(GV)) { 00045 switch (F->getLinkage()) { 00046 default: assert(0 && "Unknown linkage type!"); 00047 case Function::PrivateLinkage: 00048 case Function::InternalLinkage: 00049 case Function::DLLExportLinkage: 00050 case Function::ExternalLinkage: 00051 return TextSection; 00052 case Function::WeakLinkage: 00053 case Function::LinkOnceLinkage: 00054 std::string Name = UniqueSectionForGlobal(GV, Kind); 00055 unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str()); 00056 return getNamedSection(Name.c_str(), Flags); 00057 } 00058 } else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { 00059 if (GVar->mayBeOverridden()) { 00060 std::string Name = UniqueSectionForGlobal(GVar, Kind); 00061 unsigned Flags = SectionFlagsForGlobal(GVar, Name.c_str()); 00062 return getNamedSection(Name.c_str(), Flags); 00063 } else { 00064 switch (Kind) { 00065 case SectionKind::Data: 00066 case SectionKind::SmallData: 00067 return DataSection; 00068 case SectionKind::BSS: 00069 case SectionKind::SmallBSS: 00070 // ELF targets usually have BSS sections 00071 return getBSSSection_(); 00072 case SectionKind::ROData: 00073 case SectionKind::SmallROData: 00074 return getReadOnlySection(); 00075 case SectionKind::RODataMergeStr: 00076 return MergeableStringSection(GVar); 00077 case SectionKind::RODataMergeConst: 00078 return MergeableConstSection(GVar); 00079 case SectionKind::ThreadData: 00080 // ELF targets usually support TLS stuff 00081 return TLSDataSection; 00082 case SectionKind::ThreadBSS: 00083 return TLSBSSSection; 00084 default: 00085 assert(0 && "Unsuported section kind for global"); 00086 } 00087 } 00088 } else 00089 assert(0 && "Unsupported global"); 00090 00091 return NULL; 00092 } 00093 00094 const Section* 00095 ELFTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { 00096 // FIXME: Support data.rel stuff someday 00097 return MergeableConstSection(Ty); 00098 } 00099 00100 const Section* 00101 ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { 00102 Constant *C = GV->getInitializer(); 00103 return MergeableConstSection(C->getType()); 00104 } 00105 00106 inline const Section* 00107 ELFTargetAsmInfo::MergeableConstSection(const Type *Ty) const { 00108 const TargetData *TD = TM.getTargetData(); 00109 00110 // FIXME: string here is temporary, until stuff will fully land in. 00111 // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's 00112 // currently directly used by asmprinter. 00113 unsigned Size = TD->getTypePaddedSize(Ty); 00114 if (Size == 4 || Size == 8 || Size == 16) { 00115 std::string Name = ".rodata.cst" + utostr(Size); 00116 00117 return getNamedSection(Name.c_str(), 00118 SectionFlags::setEntitySize(SectionFlags::Mergeable, 00119 Size)); 00120 } 00121 00122 return getReadOnlySection(); 00123 } 00124 00125 const Section* 00126 ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { 00127 const TargetData *TD = TM.getTargetData(); 00128 Constant *C = cast<GlobalVariable>(GV)->getInitializer(); 00129 const Type *Ty = cast<ArrayType>(C->getType())->getElementType(); 00130 00131 unsigned Size = TD->getTypePaddedSize(Ty); 00132 if (Size <= 16) { 00133 assert(getCStringSection() && "Should have string section prefix"); 00134 00135 // We also need alignment here 00136 unsigned Align = TD->getPrefTypeAlignment(Ty); 00137 if (Align < Size) 00138 Align = Size; 00139 00140 std::string Name = getCStringSection() + utostr(Size) + '.' + utostr(Align); 00141 unsigned Flags = SectionFlags::setEntitySize(SectionFlags::Mergeable | 00142 SectionFlags::Strings, 00143 Size); 00144 return getNamedSection(Name.c_str(), Flags); 00145 } 00146 00147 return getReadOnlySection(); 00148 } 00149 00150 std::string ELFTargetAsmInfo::printSectionFlags(unsigned flags) const { 00151 std::string Flags = ",\""; 00152 00153 if (!(flags & SectionFlags::Debug)) 00154 Flags += 'a'; 00155 if (flags & SectionFlags::Code) 00156 Flags += 'x'; 00157 if (flags & SectionFlags::Writeable) 00158 Flags += 'w'; 00159 if (flags & SectionFlags::Mergeable) 00160 Flags += 'M'; 00161 if (flags & SectionFlags::Strings) 00162 Flags += 'S'; 00163 if (flags & SectionFlags::TLS) 00164 Flags += 'T'; 00165 if (flags & SectionFlags::Small) 00166 Flags += 's'; 00167 00168 Flags += "\","; 00169 00170 // If comment string is '@', e.g. as on ARM - use '%' instead 00171 if (strcmp(CommentString, "@") == 0) 00172 Flags += '%'; 00173 else 00174 Flags += '@'; 00175 00176 // FIXME: There can be exceptions here 00177 if (flags & SectionFlags::BSS) 00178 Flags += "nobits"; 00179 else 00180 Flags += "progbits"; 00181 00182 if (unsigned entitySize = SectionFlags::getEntitySize(flags)) 00183 Flags += "," + utostr(entitySize); 00184 00185 return Flags; 00186 }