static unsigned
getCOFFSectionFlags(SectionKind K) {
  unsigned Flags = 0;

  if (K.isMetadata())
    Flags |=
      COFF::IMAGE_SCN_MEM_DISCARDABLE;
  else if (K.isText())
    Flags |=
      COFF::IMAGE_SCN_MEM_EXECUTE |
      COFF::IMAGE_SCN_MEM_READ |
      COFF::IMAGE_SCN_CNT_CODE;
  else if (K.isBSS ())
    Flags |=
      COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
      COFF::IMAGE_SCN_MEM_READ |
      COFF::IMAGE_SCN_MEM_WRITE;
  else if (K.isReadOnly())
    Flags |=
      COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
      COFF::IMAGE_SCN_MEM_READ;
  else if (K.isWriteable())
    Flags |=
      COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
      COFF::IMAGE_SCN_MEM_READ |
      COFF::IMAGE_SCN_MEM_WRITE;

  return Flags;
}
/// IsGlobalInSmallSection - Return true if this global address should be
/// placed into small data/bss section.
bool MipsTargetObjectFile::
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
                       SectionKind Kind) const {

  // Only use small section for non linux targets.
  const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
  if (Subtarget.isLinux())
    return false;

  // Only global variables, not functions.
  const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
  if (!GVA)
    return false;

  // We can only do this for datarel or BSS objects for now.
  if (!Kind.isBSS() && !Kind.isDataRel())
    return false;

  // If this is a internal constant string, there is a special
  // section for it, but not in small data/bss.
  if (Kind.isMergeable1ByteCString())
    return false;

  const Type *Ty = GV->getType()->getElementType();
  return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
}
Example #3
0
// .section name [, "flags"] [, identifier [ identifier ], identifier]
//
// Supported flags:
//   a: Ignored.
//   b: BSS section (uninitialized data)
//   d: data section (initialized data)
//   n: Discardable section
//   r: Readable section
//   s: Shared section
//   w: Writable section
//   x: Executable section
//   y: Not-readable section (clears 'r')
//
// Subsections are not supported.
bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
  StringRef SectionName;

  if (ParseSectionName(SectionName))
    return TokError("expected identifier in directive");

  unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                   COFF::IMAGE_SCN_MEM_READ |
                   COFF::IMAGE_SCN_MEM_WRITE;

  if (getLexer().is(AsmToken::Comma)) {
    Lex();

    if (getLexer().isNot(AsmToken::String))
      return TokError("expected string in directive");

    StringRef FlagsStr = getTok().getStringContents();
    Lex();

    if (ParseSectionFlags(FlagsStr, &Flags))
      return true;
  }

  COFF::COMDATType Type = (COFF::COMDATType)0;
  StringRef COMDATSymName;
  if (getLexer().is(AsmToken::Comma)) {
    Type = COFF::IMAGE_COMDAT_SELECT_ANY;
    Lex();

    Flags |= COFF::IMAGE_SCN_LNK_COMDAT;

    if (!getLexer().is(AsmToken::Identifier))
      return TokError("expected comdat type such as 'discard' or 'largest' "
                      "after protection bits");

    if (parseCOMDATType(Type))
      return true;

    if (getLexer().isNot(AsmToken::Comma))
      return TokError("expected comma in directive");
    Lex();

    if (getParser().parseIdentifier(COMDATSymName))
      return TokError("expected identifier in directive");
  }

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  SectionKind Kind = computeSectionKind(Flags);
  if (Kind.isText()) {
    const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
    if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
      Flags |= COFF::IMAGE_SCN_MEM_16BIT;
  }
  ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
  return false;
}
static unsigned
getELFSectionFlags(SectionKind K) {
  unsigned Flags = 0;

  if (!K.isMetadata())
    Flags |= ELF::SHF_ALLOC;

  if (K.isText())
    Flags |= ELF::SHF_EXECINSTR;

  if (K.isWriteable())
    Flags |= ELF::SHF_WRITE;

  if (K.isThreadLocal())
    Flags |= ELF::SHF_TLS;

  // K.isMergeableConst() is left out to honour PR4650
  if (K.isMergeableCString() || K.isMergeableConst4() ||
      K.isMergeableConst8() || K.isMergeableConst16())
    Flags |= ELF::SHF_MERGE;

  if (K.isMergeableCString())
    Flags |= ELF::SHF_STRINGS;

  return Flags;
}
static unsigned getELFSectionFlags(SectionKind K) {
  unsigned Flags = 0;

  if (!K.isMetadata())
    Flags |= ELF::SHF_ALLOC;

  if (K.isText())
    Flags |= ELF::SHF_EXECINSTR;

  if (K.isExecuteOnly())
    Flags |= ELF::SHF_ARM_PURECODE;

  if (K.isWriteable())
    Flags |= ELF::SHF_WRITE;

  if (K.isThreadLocal())
    Flags |= ELF::SHF_TLS;

  if (K.isMergeableCString() || K.isMergeableConst())
    Flags |= ELF::SHF_MERGE;

  if (K.isMergeableCString())
    Flags |= ELF::SHF_STRINGS;

  return Flags;
}
static unsigned getXCoreSectionFlags(SectionKind K, bool IsCPRel) {
  unsigned Flags = 0;

  if (!K.isMetadata())
    Flags |= ELF::SHF_ALLOC;

  if (K.isText())
    Flags |= ELF::SHF_EXECINSTR;
  else if (IsCPRel)
    Flags |= ELF::XCORE_SHF_CP_SECTION;
  else
    Flags |= ELF::XCORE_SHF_DP_SECTION;

  if (K.isWriteable())
    Flags |= ELF::SHF_WRITE;

  if (K.isMergeableCString() || K.isMergeableConst4() ||
      K.isMergeableConst8() || K.isMergeableConst16())
    Flags |= ELF::SHF_MERGE;

  if (K.isMergeableCString())
    Flags |= ELF::SHF_STRINGS;

  return Flags;
}
/// IsGlobalInSmallSection - Return true if this global value should be
/// placed into small data/bss section.
bool HexagonTargetObjectFile::
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
                       SectionKind Kind) const {
  // Only global variables, not functions.
  const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
  if (!GVA)
    return false;

  if (Kind.isBSS() || Kind.isDataNoRel() || Kind.isCommon()) {
    Type *Ty = GV->getType()->getElementType();
    return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
  }

  return false;
}
static unsigned getELFSectionType(StringRef Name, SectionKind K) {

  if (Name == ".init_array")
    return ELF::SHT_INIT_ARRAY;

  if (Name == ".fini_array")
    return ELF::SHT_FINI_ARRAY;

  if (Name == ".preinit_array")
    return ELF::SHT_PREINIT_ARRAY;

  if (K.isBSS() || K.isThreadBSS())
    return ELF::SHT_NOBITS;

  return ELF::SHT_PROGBITS;
}
Example #9
0
static bool isExecuteOnlyFunction(const GlobalObject *GO, SectionKind SK,
                                  const TargetMachine &TM) {
  if (const Function *F = dyn_cast<Function>(GO))
    if (TM.getSubtarget<ARMSubtarget>(*F).genExecuteOnly() && SK.isText())
      return true;
  return false;
}
/// getSectionPrefixForGlobal - Return the section prefix name used by options
/// FunctionsSections and DataSections.
static StringRef getSectionPrefixForGlobal(SectionKind Kind) {
  if (Kind.isText())                 return ".text.";
  if (Kind.isReadOnly())             return ".rodata.";
  if (Kind.isBSS())                  return ".bss.";

  if (Kind.isThreadData())           return ".tdata.";
  if (Kind.isThreadBSS())            return ".tbss.";

  if (Kind.isDataNoRel())            return ".data.";
  if (Kind.isDataRelLocal())         return ".data.rel.local.";
  if (Kind.isDataRel())              return ".data.rel.";
  if (Kind.isReadOnlyWithRelLocal()) return ".data.rel.ro.local.";

  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
  return ".data.rel.ro.";
}
static unsigned
getELFSectionFlags(SectionKind K, bool InCOMDAT) {
  unsigned Flags = 0;

  if (!K.isMetadata())
    Flags |= ELF::SHF_ALLOC;

  if (K.isText())
    Flags |= ELF::SHF_EXECINSTR;

  if (K.isWriteable())
    Flags |= ELF::SHF_WRITE;

  if (K.isThreadLocal())
    Flags |= ELF::SHF_TLS;

  // FIXME: There is nothing in ELF preventing an SHF_MERGE from being
  // in a comdat. We just avoid it for now because we don't print
  // those .sections correctly.
  if (!InCOMDAT && (K.isMergeableCString() || K.isMergeableConst()))
    Flags |= ELF::SHF_MERGE;

  if (K.isMergeableCString())
    Flags |= ELF::SHF_STRINGS;

  return Flags;
}
static SectionKind getWasmKindForNamedSection(StringRef Name, SectionKind K) {
  // If we're told we have function data, then use that.
  if (K.isText())
    return SectionKind::getText();

  // Otherwise, ignore whatever section type the generic impl detected and use
  // a plain data section.
  return SectionKind::getData();
}
static unsigned getELFSectionType(StringRef Name, SectionKind K) {
  // Use SHT_NOTE for section whose name starts with ".note" to allow
  // emitting ELF notes from C variable declaration.
  // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609
  if (Name.startswith(".note"))
    return ELF::SHT_NOTE;

  if (Name == ".init_array")
    return ELF::SHT_INIT_ARRAY;

  if (Name == ".fini_array")
    return ELF::SHT_FINI_ARRAY;

  if (Name == ".preinit_array")
    return ELF::SHT_PREINIT_ARRAY;

  if (K.isBSS() || K.isThreadBSS())
    return ELF::SHT_NOBITS;

  return ELF::SHT_PROGBITS;
}
Example #14
0
SVMProgramSection SVMMemoryLayout::getSectionKind(const MCSectionData *SD) const
{
    /*
     * Categorize a MCSection as one of the several predefined
     * SVMProgramSection types. This determines which program section
     * we'll lump it in with, or whether it'll be included as debug-only.
     *
     * This value can be specifically overridden with setSectionKind().
     * If we have no override, we calculate the proper section kind
     * using the section's name, size, type, and other data.
     */

    SectionKindOverrides_t::const_iterator it = SectionKindOverrides.find(SD);
    if (it != SectionKindOverrides.end())
        return it->second;

    const MCSection *S = &SD->getSection();
    SectionKind k = S->getKind();
    const MCSectionELF *SE = dyn_cast<MCSectionELF>(S);
    assert(SE);
    StringRef Name = SE->getSectionName();

    if (Name == ".metadata")
        return SPS_META;

    if (Name.startswith(".debug_"))
        return SPS_DEBUG;

    if (k.isBSS())
        return SPS_BSS;

    if (SE->getType() == ELF::SHT_PROGBITS) {
        if (k.isReadOnly() || k.isText())
            return SPS_RO;
        if (k.isGlobalWriteableData())
            return SPS_RW_PLAIN;
    }

    return SPS_DEBUG;
}
Example #15
0
unsigned MCSectionELF::DetermineEntrySize(SectionKind Kind) {
  if (Kind.isMergeable1ByteCString()) return 1;
  if (Kind.isMergeable2ByteCString()) return 2;
  if (Kind.isMergeable4ByteCString()) return 4;
  if (Kind.isMergeableConst4())       return 4;
  if (Kind.isMergeableConst8())       return 8;
  if (Kind.isMergeableConst16())      return 16;
  return 0;
}
static unsigned
getCOFFSectionFlags(SectionKind K, const TargetMachine &TM) {
  unsigned Flags = 0;
  bool isThumb = TM.getTargetTriple().getArch() == Triple::thumb;

  if (K.isMetadata())
    Flags |=
      COFF::IMAGE_SCN_MEM_DISCARDABLE;
  else if (K.isText())
    Flags |=
      COFF::IMAGE_SCN_MEM_EXECUTE |
      COFF::IMAGE_SCN_MEM_READ |
      COFF::IMAGE_SCN_CNT_CODE |
      (isThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0);
  else if (K.isBSS())
    Flags |=
      COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
      COFF::IMAGE_SCN_MEM_READ |
      COFF::IMAGE_SCN_MEM_WRITE;
  else if (K.isThreadLocal())
    Flags |=
      COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
      COFF::IMAGE_SCN_MEM_READ |
      COFF::IMAGE_SCN_MEM_WRITE;
  else if (K.isReadOnly() || K.isReadOnlyWithRel())
    Flags |=
      COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
      COFF::IMAGE_SCN_MEM_READ;
  else if (K.isWriteable())
    Flags |=
      COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
      COFF::IMAGE_SCN_MEM_READ |
      COFF::IMAGE_SCN_MEM_WRITE;

  return Flags;
}
Example #17
0
// 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);
  bool IsUndefSym = IsELFUndefSym(GV);

  ELFSym *GblSym = IsUndefSym ? ELFSym::getUndefGV(GV, SymBind)
    : ELFSym::getGV(GV, SymBind, SymType, getGlobalELFVisibility(GV));

  if (!IsUndefSym) {
    assert(isa<GlobalVariable>(GV) && "GV not a global variable!");
    const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);

    // Handle special llvm globals
    if (EmitSpecialLLVMGlobal(GVar))
      return;

    // Get the ELF section where this global belongs from TLOF
    const MCSectionELF *S = 
      (const MCSectionELF *)TLOF.SectionForGlobal(GV, Mang, TM);
    ELFSection &ES = 
      getSection(S->getSectionName(), S->getType(), S->getFlags());
    SectionKind Kind = S->getKind();

    // The symbol align should update the section alignment if needed
    const TargetData *TD = TM.getTargetData();
    unsigned Align = TD->getPreferredAlignment(GVar);
    unsigned Size = TD->getTypeAllocSize(GVar->getInitializer()->getType());
    GblSym->Size = Size;

    if (HasCommonSymbols(*S)) { // Symbol must go to a common section
      GblSym->SectionIdx = ELF::SHN_COMMON;

      // A new linkonce section is created for each global in the
      // common section, the default alignment is 1 and the symbol
      // value contains its alignment.
      ES.Align = 1;
      GblSym->Value = Align;

    } else if (Kind.isBSS() || Kind.isThreadBSS()) { // Symbol goes to BSS.
      GblSym->SectionIdx = ES.SectionIdx;

      // Update the size with alignment and the next object can
      // start in the right offset in the section
      if (Align) ES.Size = (ES.Size + Align-1) & ~(Align-1);
      ES.Align = std::max(ES.Align, Align);

      // GblSym->Value should contain the virtual offset inside the section.
      // Virtual because the BSS space is not allocated on ELF objects
      GblSym->Value = ES.Size;
      ES.Size += Size;

    } else { // The symbol must go to some kind of data section
      GblSym->SectionIdx = ES.SectionIdx;

      // GblSym->Value should contain the symbol offset inside the section,
      // and all symbols should start on their required alignment boundary
      ES.Align = std::max(ES.Align, Align);
      ES.emitAlignment(Align);
      GblSym->Value = ES.size();

      // Emit the global to the data section 'ES'
      EmitGlobalConstant(GVar->getInitializer(), ES);
    }
  }

  AddToSymbolList(GblSym);
}
static unsigned getXCoreSectionType(SectionKind K) {
  if (K.isBSS())
    return ELF::SHT_NOBITS;
  return ELF::SHT_PROGBITS;
}
// Return true if this global address should be placed into small data/bss
// section.
bool LanaiTargetObjectFile::isGlobalInSmallSection(const GlobalValue *GV,
                                                   const TargetMachine &TM,
                                                   SectionKind Kind) const {
  return (isGlobalInSmallSectionImpl(GV, TM) &&
          (Kind.isData() || Kind.isBSS() || Kind.isCommon()));
}
/// Return the section prefix name used by options FunctionsSections and
/// DataSections.
static StringRef getSectionPrefixForGlobal(SectionKind Kind) {
  if (Kind.isTexTramp())
    return ".tramp.";
  if (Kind.isText())
    return ".text";
  if (Kind.isReadOnly())
    return ".rodata";
  if (Kind.isBSS())
    return ".bss";
  if (Kind.isThreadData())
    return ".tdata";
  if (Kind.isThreadBSS())
    return ".tbss";
  if (Kind.isData())
    return ".data";
  if (Kind.isTexTrap())
    return ".textrap.";
  if (Kind.isTexTrapText())
    return ".textrap.";
  if (Kind.isTexTramp())
    return ".text.xvtable.";
  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
  return ".data.rel.ro";
}
/// IsGlobalInSmallSection - Return true if this global address should be
/// placed into small data/bss section.
bool TriCoreTargetObjectFile::
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
                       SectionKind Kind) const {
  return (IsGlobalInSmallSectionImpl(GV, TM) &&
          (Kind.isDataRel() || Kind.isBSS() || Kind.isCommon()));
}