Skip to content
TargetLoweringObjectFile.cpp 43.6 KiB
Newer Older
TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const {
  // If this constant requires a relocation, we have to put it in the data
  // segment, not in the text segment.
  if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
  if (Kind.isMergeableConst4())
    return FourByteConstantSection;
  if (Kind.isMergeableConst8())
    return EightByteConstantSection;
  if (Kind.isMergeableConst16() && SixteenByteConstantSection)
    return SixteenByteConstantSection;
  return ReadOnlySection;  // .const
}

/// shouldEmitUsedDirectiveFor - 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;
  // 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.
Chris Lattner's avatar
Chris Lattner committed
    Mang->getNameWithPrefix(Name, GV, false);
    if (Name[0] == 'L' || Name[0] == 'l')
      return false;
  }
const MCExpr *TargetLoweringObjectFileMachO::
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
                             MachineModuleInfo *MMI, unsigned Encoding) const {
  // The mach-o version of this method defaults to returning a stub reference.

  if (Encoding & dwarf::DW_EH_PE_indirect) {
    SmallString<128> Name;
    Mang->getNameWithPrefix(Name, GV, true);
    Name += "$non_lazy_ptr";
    MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());

    return TargetLoweringObjectFile::
      getSymbolForDwarfReference(Sym, MMI,
                                 Encoding & ~dwarf::DW_EH_PE_indirect);
  }

  return TargetLoweringObjectFile::
    getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
//===----------------------------------------------------------------------===//
//                                  COFF
//===----------------------------------------------------------------------===//

typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;

TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() {
  delete (COFFUniqueMapTy*)UniquingMap;
}

const MCSection *TargetLoweringObjectFileCOFF::
getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const {
  // Create the map if it doesn't already exist.
  if (UniquingMap == 0)
    UniquingMap = new MachOUniqueMapTy();
  COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)UniquingMap;
  // Do the lookup, if we have a hit, return it.
  const MCSectionCOFF *&Entry = Map[Name];
  if (Entry) return Entry;
  return Entry = MCSectionCOFF::Create(Name, isDirective, Kind, getContext());
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
                                              const TargetMachine &TM) {
  if (UniquingMap != 0)
    ((COFFUniqueMapTy*)UniquingMap)->clear();
  TargetLoweringObjectFile::Initialize(Ctx, TM);
  TextSection = getCOFFSection("\t.text", true, SectionKind::getText());
  DataSection = getCOFFSection("\t.data", true, SectionKind::getDataRel());
    getCOFFSection(".ctors", false, SectionKind::getDataRel());
    getCOFFSection(".dtors", false, SectionKind::getDataRel());
  // FIXME: We're emitting LSDA info into a readonly section on COFF, even
  // though it contains relocatable pointers.  In PIC mode, this is probably a
  // big runtime hit for C++ apps.  Either the contents of the LSDA need to be
  // adjusted or this should be a data section.
  LSDASection =
    getCOFFSection(".gcc_except_table", false, SectionKind::getReadOnly());
  EHFrameSection =
    getCOFFSection(".eh_frame", false, SectionKind::getDataRel());
  // Debug info.
  // FIXME: Don't use 'directive' mode here.
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfAbbrevSection =
    getCOFFSection("\t.section\t.debug_abbrev,\"dr\"",
                   true, SectionKind::getMetadata());
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfInfoSection =
    getCOFFSection("\t.section\t.debug_info,\"dr\"",
                   true, SectionKind::getMetadata());
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfLineSection =
    getCOFFSection("\t.section\t.debug_line,\"dr\"",
                   true, SectionKind::getMetadata());
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfFrameSection =
    getCOFFSection("\t.section\t.debug_frame,\"dr\"",
                   true, SectionKind::getMetadata());
    getCOFFSection("\t.section\t.debug_pubnames,\"dr\"",
                   true, SectionKind::getMetadata());
    getCOFFSection("\t.section\t.debug_pubtypes,\"dr\"",
                   true, SectionKind::getMetadata());
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfStrSection =
    getCOFFSection("\t.section\t.debug_str,\"dr\"",
                   true, SectionKind::getMetadata());
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfLocSection =
    getCOFFSection("\t.section\t.debug_loc,\"dr\"",
                   true, SectionKind::getMetadata());
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfARangesSection =
    getCOFFSection("\t.section\t.debug_aranges,\"dr\"",
                   true, SectionKind::getMetadata());
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfRangesSection =
    getCOFFSection("\t.section\t.debug_ranges,\"dr\"",
                   true, SectionKind::getMetadata());
Anton Korobeynikov's avatar
Anton Korobeynikov committed
  DwarfMacroInfoSection =
    getCOFFSection("\t.section\t.debug_macinfo,\"dr\"",
                   true, SectionKind::getMetadata());
const MCSection *TargetLoweringObjectFileCOFF::
Anton Korobeynikov's avatar
Anton Korobeynikov committed
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
                         Mangler *Mang, const TargetMachine &TM) const {
  return getCOFFSection(GV->getSection(), false, Kind);
static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
  if (Kind.isText())
    return ".text$linkonce";
  if (Kind.isWriteable())
    return ".data$linkonce";
  return ".rdata$linkonce";
}


const MCSection *TargetLoweringObjectFileCOFF::
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
                       Mangler *Mang, const TargetMachine &TM) const {
  assert(!Kind.isThreadLocal() && "Doesn't support TLS");
  // If this global is linkonce/weak and the target handles this by emitting it
  // into a 'uniqued' section name, create and return the section now.
Chris Lattner's avatar
Chris Lattner committed
  if (GV->isWeakForLinker()) {
    const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
    SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
    Mang->getNameWithPrefix(Name, GV, false);
    return getCOFFSection(Name.str(), false, Kind);