LLVM API Documentation

ELFTargetAsmInfo.cpp

Go to the documentation of this file.
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 }