Home | History | Annotate | Download | only in Target
      1 //===-- llvm/Target/TargetLoweringObjectFile.cpp - Object File Info -------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements classes used to handle lowerings specific to common
     11 // object file formats.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "llvm/Target/TargetLoweringObjectFile.h"
     16 #include "llvm/Constants.h"
     17 #include "llvm/DerivedTypes.h"
     18 #include "llvm/Function.h"
     19 #include "llvm/GlobalVariable.h"
     20 #include "llvm/MC/MCContext.h"
     21 #include "llvm/MC/MCExpr.h"
     22 #include "llvm/MC/MCStreamer.h"
     23 #include "llvm/MC/MCSymbol.h"
     24 #include "llvm/Target/Mangler.h"
     25 #include "llvm/Target/TargetData.h"
     26 #include "llvm/Target/TargetMachine.h"
     27 #include "llvm/Target/TargetOptions.h"
     28 #include "llvm/Support/Dwarf.h"
     29 #include "llvm/Support/ErrorHandling.h"
     30 #include "llvm/Support/raw_ostream.h"
     31 #include "llvm/ADT/SmallString.h"
     32 using namespace llvm;
     33 
     34 //===----------------------------------------------------------------------===//
     35 //                              Generic Code
     36 //===----------------------------------------------------------------------===//
     37 
     38 /// Initialize - this method must be called before any actual lowering is
     39 /// done.  This specifies the current context for codegen, and gives the
     40 /// lowering implementations a chance to set up their default sections.
     41 void TargetLoweringObjectFile::Initialize(MCContext &ctx,
     42                                           const TargetMachine &TM) {
     43   Ctx = &ctx;
     44   InitMCObjectFileInfo(TM.getTargetTriple(),
     45                        TM.getRelocationModel(), TM.getCodeModel(), *Ctx);
     46 }
     47 
     48 TargetLoweringObjectFile::~TargetLoweringObjectFile() {
     49 }
     50 
     51 static bool isSuitableForBSS(const GlobalVariable *GV) {
     52   const Constant *C = GV->getInitializer();
     53 
     54   // Must have zero initializer.
     55   if (!C->isNullValue())
     56     return false;
     57 
     58   // Leave constant zeros in readonly constant sections, so they can be shared.
     59   if (GV->isConstant())
     60     return false;
     61 
     62   // If the global has an explicit section specified, don't put it in BSS.
     63   if (!GV->getSection().empty())
     64     return false;
     65 
     66   // If -nozero-initialized-in-bss is specified, don't ever use BSS.
     67   if (NoZerosInBSS)
     68     return false;
     69 
     70   // Otherwise, put it in BSS!
     71   return true;
     72 }
     73 
     74 /// IsNullTerminatedString - Return true if the specified constant (which is
     75 /// known to have a type that is an array of 1/2/4 byte elements) ends with a
     76 /// nul value and contains no other nuls in it.
     77 static bool IsNullTerminatedString(const Constant *C) {
     78   ArrayType *ATy = cast<ArrayType>(C->getType());
     79 
     80   // First check: is we have constant array of i8 terminated with zero
     81   if (const ConstantArray *CVA = dyn_cast<ConstantArray>(C)) {
     82     if (ATy->getNumElements() == 0) return false;
     83 
     84     ConstantInt *Null =
     85       dyn_cast<ConstantInt>(CVA->getOperand(ATy->getNumElements()-1));
     86     if (Null == 0 || !Null->isZero())
     87       return false; // Not null terminated.
     88 
     89     // Verify that the null doesn't occur anywhere else in the string.
     90     for (unsigned i = 0, e = ATy->getNumElements()-1; i != e; ++i)
     91       // Reject constantexpr elements etc.
     92       if (!isa<ConstantInt>(CVA->getOperand(i)) ||
     93           CVA->getOperand(i) == Null)
     94         return false;
     95     return true;
     96   }
     97 
     98   // Another possibility: [1 x i8] zeroinitializer
     99   if (isa<ConstantAggregateZero>(C))
    100     return ATy->getNumElements() == 1;
    101 
    102   return false;
    103 }
    104 
    105 MCSymbol *TargetLoweringObjectFile::
    106 getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
    107                         MachineModuleInfo *MMI) const {
    108   return Mang->getSymbol(GV);
    109 }
    110 
    111 void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer,
    112                                                     const TargetMachine &TM,
    113                                                     const MCSymbol *Sym) const {
    114 }
    115 
    116 
    117 /// getKindForGlobal - This is a top-level target-independent classifier for
    118 /// a global variable.  Given an global variable and information from TM, it
    119 /// classifies the global in a variety of ways that make various target
    120 /// implementations simpler.  The target implementation is free to ignore this
    121 /// extra info of course.
    122 SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
    123                                                        const TargetMachine &TM){
    124   assert(!GV->isDeclaration() && !GV->hasAvailableExternallyLinkage() &&
    125          "Can only be used for global definitions");
    126 
    127   Reloc::Model ReloModel = TM.getRelocationModel();
    128 
    129   // Early exit - functions should be always in text sections.
    130   const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
    131   if (GVar == 0)
    132     return SectionKind::getText();
    133 
    134   // Handle thread-local data first.
    135   if (GVar->isThreadLocal()) {
    136     if (isSuitableForBSS(GVar))
    137       return SectionKind::getThreadBSS();
    138     return SectionKind::getThreadData();
    139   }
    140 
    141   // Variables with common linkage always get classified as common.
    142   if (GVar->hasCommonLinkage())
    143     return SectionKind::getCommon();
    144 
    145   // Variable can be easily put to BSS section.
    146   if (isSuitableForBSS(GVar)) {
    147     if (GVar->hasLocalLinkage())
    148       return SectionKind::getBSSLocal();
    149     else if (GVar->hasExternalLinkage())
    150       return SectionKind::getBSSExtern();
    151     return SectionKind::getBSS();
    152   }
    153 
    154   const Constant *C = GVar->getInitializer();
    155 
    156   // If the global is marked constant, we can put it into a mergable section,
    157   // a mergable string section, or general .data if it contains relocations.
    158   if (GVar->isConstant()) {
    159     // If the initializer for the global contains something that requires a
    160     // relocation, then we may have to drop this into a wriable data section
    161     // even though it is marked const.
    162     switch (C->getRelocationInfo()) {
    163     default: assert(0 && "unknown relocation info kind");
    164     case Constant::NoRelocation:
    165       // If the global is required to have a unique address, it can't be put
    166       // into a mergable section: just drop it into the general read-only
    167       // section instead.
    168       if (!GVar->hasUnnamedAddr())
    169         return SectionKind::getReadOnly();
    170 
    171       // If initializer is a null-terminated string, put it in a "cstring"
    172       // section of the right width.
    173       if (ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
    174         if (IntegerType *ITy =
    175               dyn_cast<IntegerType>(ATy->getElementType())) {
    176           if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 ||
    177                ITy->getBitWidth() == 32) &&
    178               IsNullTerminatedString(C)) {
    179             if (ITy->getBitWidth() == 8)
    180               return SectionKind::getMergeable1ByteCString();
    181             if (ITy->getBitWidth() == 16)
    182               return SectionKind::getMergeable2ByteCString();
    183 
    184             assert(ITy->getBitWidth() == 32 && "Unknown width");
    185             return SectionKind::getMergeable4ByteCString();
    186           }
    187         }
    188       }
    189 
    190       // Otherwise, just drop it into a mergable constant section.  If we have
    191       // a section for this size, use it, otherwise use the arbitrary sized
    192       // mergable section.
    193       switch (TM.getTargetData()->getTypeAllocSize(C->getType())) {
    194       case 4:  return SectionKind::getMergeableConst4();
    195       case 8:  return SectionKind::getMergeableConst8();
    196       case 16: return SectionKind::getMergeableConst16();
    197       default: return SectionKind::getMergeableConst();
    198       }
    199 
    200     case Constant::LocalRelocation:
    201       // In static relocation model, the linker will resolve all addresses, so
    202       // the relocation entries will actually be constants by the time the app
    203       // starts up.  However, we can't put this into a mergable section, because
    204       // the linker doesn't take relocations into consideration when it tries to
    205       // merge entries in the section.
    206       if (ReloModel == Reloc::Static)
    207         return SectionKind::getReadOnly();
    208 
    209       // Otherwise, the dynamic linker needs to fix it up, put it in the
    210       // writable data.rel.local section.
    211       return SectionKind::getReadOnlyWithRelLocal();
    212 
    213     case Constant::GlobalRelocations:
    214       // In static relocation model, the linker will resolve all addresses, so
    215       // the relocation entries will actually be constants by the time the app
    216       // starts up.  However, we can't put this into a mergable section, because
    217       // the linker doesn't take relocations into consideration when it tries to
    218       // merge entries in the section.
    219       if (ReloModel == Reloc::Static)
    220         return SectionKind::getReadOnly();
    221 
    222       // Otherwise, the dynamic linker needs to fix it up, put it in the
    223       // writable data.rel section.
    224       return SectionKind::getReadOnlyWithRel();
    225     }
    226   }
    227 
    228   // Okay, this isn't a constant.  If the initializer for the global is going
    229   // to require a runtime relocation by the dynamic linker, put it into a more
    230   // specific section to improve startup time of the app.  This coalesces these
    231   // globals together onto fewer pages, improving the locality of the dynamic
    232   // linker.
    233   if (ReloModel == Reloc::Static)
    234     return SectionKind::getDataNoRel();
    235 
    236   switch (C->getRelocationInfo()) {
    237   default: assert(0 && "unknown relocation info kind");
    238   case Constant::NoRelocation:
    239     return SectionKind::getDataNoRel();
    240   case Constant::LocalRelocation:
    241     return SectionKind::getDataRelLocal();
    242   case Constant::GlobalRelocations:
    243     return SectionKind::getDataRel();
    244   }
    245 }
    246 
    247 /// SectionForGlobal - This method computes the appropriate section to emit
    248 /// the specified global variable or function definition.  This should not
    249 /// be passed external (or available externally) globals.
    250 const MCSection *TargetLoweringObjectFile::
    251 SectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang,
    252                  const TargetMachine &TM) const {
    253   // Select section name.
    254   if (GV->hasSection())
    255     return getExplicitSectionGlobal(GV, Kind, Mang, TM);
    256 
    257 
    258   // Use default section depending on the 'type' of global
    259   return SelectSectionForGlobal(GV, Kind, Mang, TM);
    260 }
    261 
    262 
    263 // Lame default implementation. Calculate the section name for global.
    264 const MCSection *
    265 TargetLoweringObjectFile::SelectSectionForGlobal(const GlobalValue *GV,
    266                                                  SectionKind Kind,
    267                                                  Mangler *Mang,
    268                                                  const TargetMachine &TM) const{
    269   assert(!Kind.isThreadLocal() && "Doesn't support TLS");
    270 
    271   if (Kind.isText())
    272     return getTextSection();
    273 
    274   if (Kind.isBSS() && BSSSection != 0)
    275     return BSSSection;
    276 
    277   if (Kind.isReadOnly() && ReadOnlySection != 0)
    278     return ReadOnlySection;
    279 
    280   return getDataSection();
    281 }
    282 
    283 /// getSectionForConstant - Given a mergable constant with the
    284 /// specified size and relocation information, return a section that it
    285 /// should be placed in.
    286 const MCSection *
    287 TargetLoweringObjectFile::getSectionForConstant(SectionKind Kind) const {
    288   if (Kind.isReadOnly() && ReadOnlySection != 0)
    289     return ReadOnlySection;
    290 
    291   return DataSection;
    292 }
    293 
    294 /// getExprForDwarfGlobalReference - Return an MCExpr to use for a
    295 /// reference to the specified global variable from exception
    296 /// handling information.
    297 const MCExpr *TargetLoweringObjectFile::
    298 getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
    299                                MachineModuleInfo *MMI, unsigned Encoding,
    300                                MCStreamer &Streamer) const {
    301   const MCSymbol *Sym = Mang->getSymbol(GV);
    302   return getExprForDwarfReference(Sym, Encoding, Streamer);
    303 }
    304 
    305 const MCExpr *TargetLoweringObjectFile::
    306 getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
    307                          MCStreamer &Streamer) const {
    308   const MCExpr *Res = MCSymbolRefExpr::Create(Sym, getContext());
    309 
    310   switch (Encoding & 0x70) {
    311   default:
    312     report_fatal_error("We do not support this DWARF encoding yet!");
    313   case dwarf::DW_EH_PE_absptr:
    314     // Do nothing special
    315     return Res;
    316   case dwarf::DW_EH_PE_pcrel: {
    317     // Emit a label to the streamer for the current position.  This gives us
    318     // .-foo addressing.
    319     MCSymbol *PCSym = getContext().CreateTempSymbol();
    320     Streamer.EmitLabel(PCSym);
    321     const MCExpr *PC = MCSymbolRefExpr::Create(PCSym, getContext());
    322     return MCBinaryExpr::CreateSub(Res, PC, getContext());
    323   }
    324   }
    325 }
    326