Example #1
0
void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
  // COFF
  BSSSection =
    Ctx->getCOFFSection(".bss",
                        COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
                        COFF::IMAGE_SCN_MEM_READ |
                        COFF::IMAGE_SCN_MEM_WRITE,
                        SectionKind::getBSS());
  TextSection =
    Ctx->getCOFFSection(".text",
                        COFF::IMAGE_SCN_CNT_CODE |
                        COFF::IMAGE_SCN_MEM_EXECUTE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getText());
  DataSection =
    Ctx->getCOFFSection(".data",
                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                        COFF::IMAGE_SCN_MEM_READ |
                        COFF::IMAGE_SCN_MEM_WRITE,
                        SectionKind::getDataRel());
  ReadOnlySection =
    Ctx->getCOFFSection(".rdata",
                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getReadOnly());
  if (T.getOS() == Triple::Win32) {
    StaticCtorSection =
      Ctx->getCOFFSection(".CRT$XCU",
                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                          COFF::IMAGE_SCN_MEM_READ,
                          SectionKind::getReadOnly());
  } else {
    StaticCtorSection =
      Ctx->getCOFFSection(".ctors",
                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                          COFF::IMAGE_SCN_MEM_READ |
                          COFF::IMAGE_SCN_MEM_WRITE,
                          SectionKind::getDataRel());
  }


  if (T.getOS() == Triple::Win32) {
    StaticDtorSection =
      Ctx->getCOFFSection(".CRT$XTX",
                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                          COFF::IMAGE_SCN_MEM_READ,
                          SectionKind::getReadOnly());
  } else {
    StaticDtorSection =
      Ctx->getCOFFSection(".dtors",
                          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                          COFF::IMAGE_SCN_MEM_READ |
                          COFF::IMAGE_SCN_MEM_WRITE,
                          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 =
    Ctx->getCOFFSection(".gcc_except_table",
                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getReadOnly());

  // Debug info.
  COFFDebugSymbolsSection =
    Ctx->getCOFFSection(".debug$S",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());

  DwarfAbbrevSection =
    Ctx->getCOFFSection(".debug_abbrev",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfInfoSection =
    Ctx->getCOFFSection(".debug_info",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfLineSection =
    Ctx->getCOFFSection(".debug_line",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfFrameSection =
    Ctx->getCOFFSection(".debug_frame",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfPubNamesSection =
    Ctx->getCOFFSection(".debug_pubnames",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfPubTypesSection =
    Ctx->getCOFFSection(".debug_pubtypes",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfGnuPubNamesSection =
    Ctx->getCOFFSection(".debug_gnu_pubnames",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfGnuPubTypesSection =
    Ctx->getCOFFSection(".debug_gnu_pubtypes",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfStrSection =
    Ctx->getCOFFSection(".debug_str",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfLocSection =
    Ctx->getCOFFSection(".debug_loc",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfARangesSection =
    Ctx->getCOFFSection(".debug_aranges",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfRangesSection =
    Ctx->getCOFFSection(".debug_ranges",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());
  DwarfMacroInfoSection =
    Ctx->getCOFFSection(".debug_macinfo",
                        COFF::IMAGE_SCN_MEM_DISCARDABLE |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getMetadata());

  DrectveSection =
    Ctx->getCOFFSection(".drectve",
                        COFF::IMAGE_SCN_LNK_INFO,
                        SectionKind::getMetadata());

  PDataSection =
    Ctx->getCOFFSection(".pdata",
                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getDataRel());

  XDataSection =
    Ctx->getCOFFSection(".xdata",
                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                        COFF::IMAGE_SCN_MEM_READ,
                        SectionKind::getDataRel());
  TLSDataSection =
    Ctx->getCOFFSection(".tls$",
                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                        COFF::IMAGE_SCN_MEM_READ |
                        COFF::IMAGE_SCN_MEM_WRITE,
                        SectionKind::getDataRel());
}
Example #2
0
void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
  if (T.getArch() == Triple::x86) {
    PersonalityEncoding = (RelocM == Reloc::PIC_)
     ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
     : dwarf::DW_EH_PE_absptr;
    LSDAEncoding = (RelocM == Reloc::PIC_)
      ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
      : dwarf::DW_EH_PE_absptr;
    FDEEncoding = FDECFIEncoding = (RelocM == Reloc::PIC_)
      ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
      : dwarf::DW_EH_PE_absptr;
    TTypeEncoding = (RelocM == Reloc::PIC_)
     ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
     : dwarf::DW_EH_PE_absptr;
  } else if (T.getArch() == Triple::x86_64) {
    FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;

    if (RelocM == Reloc::PIC_) {
      PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium)
         ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
      LSDAEncoding = dwarf::DW_EH_PE_pcrel |
        (CMModel == CodeModel::Small
         ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
      FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
      TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium)
         ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
    } else {
      PersonalityEncoding =
        (CMModel == CodeModel::Small || CMModel == CodeModel::Medium)
        ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
      LSDAEncoding = (CMModel == CodeModel::Small)
        ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
      FDEEncoding = dwarf::DW_EH_PE_udata4;
      TTypeEncoding = (CMModel == CodeModel::Small)
        ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
    }
  }

  // Solaris requires different flags for .eh_frame to seemingly every other
  // platform.
  EHSectionType = ELF::SHT_PROGBITS;
  EHSectionFlags = ELF::SHF_ALLOC;
  if (T.getOS() == Triple::Solaris) {
    if (T.getArch() == Triple::x86_64)
      EHSectionType = ELF::SHT_X86_64_UNWIND;
    else
      EHSectionFlags |= ELF::SHF_WRITE;
  }


  // ELF
  BSSSection =
    Ctx->getELFSection(".bss", ELF::SHT_NOBITS,
                       ELF::SHF_WRITE | ELF::SHF_ALLOC,
                       SectionKind::getBSS());

  TextSection =
    Ctx->getELFSection(".text", ELF::SHT_PROGBITS,
                       ELF::SHF_EXECINSTR |
                       ELF::SHF_ALLOC,
                       SectionKind::getText());

  DataSection =
    Ctx->getELFSection(".data", ELF::SHT_PROGBITS,
                       ELF::SHF_WRITE |ELF::SHF_ALLOC,
                       SectionKind::getDataRel());

  ReadOnlySection =
    Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC,
                       SectionKind::getReadOnly());

  TLSDataSection =
    Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC | ELF::SHF_TLS |
                       ELF::SHF_WRITE,
                       SectionKind::getThreadData());

  TLSBSSSection =
    Ctx->getELFSection(".tbss", ELF::SHT_NOBITS,
                       ELF::SHF_ALLOC | ELF::SHF_TLS |
                       ELF::SHF_WRITE,
                       SectionKind::getThreadBSS());

  DataRelSection =
    Ctx->getELFSection(".data.rel", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getDataRel());

  DataRelLocalSection =
    Ctx->getELFSection(".data.rel.local", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getDataRelLocal());

  DataRelROSection =
    Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getReadOnlyWithRel());

  DataRelROLocalSection =
    Ctx->getELFSection(".data.rel.ro.local", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getReadOnlyWithRelLocal());

  MergeableConst4Section =
    Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_MERGE,
                       SectionKind::getMergeableConst4());

  MergeableConst8Section =
    Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_MERGE,
                       SectionKind::getMergeableConst8());

  MergeableConst16Section =
    Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_MERGE,
                       SectionKind::getMergeableConst16());

  StaticCtorSection =
    Ctx->getELFSection(".ctors", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getDataRel());

  StaticDtorSection =
    Ctx->getELFSection(".dtors", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getDataRel());

  // Exception Handling Sections.

  // FIXME: We're emitting LSDA info into a readonly section on ELF, 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 =
    Ctx->getELFSection(".gcc_except_table", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC,
                       SectionKind::getReadOnly());

  // Debug Info Sections.
  DwarfAbbrevSection =
    Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfInfoSection =
    Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfLineSection =
    Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfFrameSection =
    Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfPubTypesSection =
    Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfStrSection =
    Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS,
                       ELF::SHF_MERGE | ELF::SHF_STRINGS,
                       SectionKind::getMergeable1ByteCString());
  DwarfLocSection =
    Ctx->getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfARangesSection =
    Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfRangesSection =
    Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfMacroInfoSection =
    Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());

  // DWARF5 Experimental Debug Info

  // Accelerator Tables
  DwarfAccelNamesSection =
    Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfAccelObjCSection =
    Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfAccelNamespaceSection =
    Ctx->getELFSection(".apple_namespaces", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfAccelTypesSection =
    Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());

  // Fission Sections
  DwarfInfoDWOSection =
    Ctx->getELFSection(".debug_info.dwo", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
}
Example #3
0
void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
  if (T.getArch() == Triple::mips ||
      T.getArch() == Triple::mipsel)
    FDECFIEncoding = dwarf::DW_EH_PE_sdata4;
  else if (T.getArch() == Triple::mips64 ||
           T.getArch() == Triple::mips64el)
    FDECFIEncoding = dwarf::DW_EH_PE_sdata8;
  else
    FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;

  if (T.getArch() == Triple::x86) {
    PersonalityEncoding = (RelocM == Reloc::PIC_)
     ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
     : dwarf::DW_EH_PE_absptr;
    LSDAEncoding = (RelocM == Reloc::PIC_)
      ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
      : dwarf::DW_EH_PE_absptr;
    FDEEncoding = (RelocM == Reloc::PIC_)
      ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
      : dwarf::DW_EH_PE_absptr;
    TTypeEncoding = (RelocM == Reloc::PIC_)
     ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
     : dwarf::DW_EH_PE_absptr;
  } else if (T.getArch() == Triple::x86_64) {
    if (RelocM == Reloc::PIC_) {
      PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium)
         ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
      LSDAEncoding = dwarf::DW_EH_PE_pcrel |
        (CMModel == CodeModel::Small
         ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
      FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
      TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium)
         ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
    } else {
      PersonalityEncoding =
        (CMModel == CodeModel::Small || CMModel == CodeModel::Medium)
        ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
      LSDAEncoding = (CMModel == CodeModel::Small)
        ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
      FDEEncoding = dwarf::DW_EH_PE_udata4;
      TTypeEncoding = (CMModel == CodeModel::Small)
        ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
    }
  }  else if (T.getArch() ==  Triple::aarch64) {
    // The small model guarantees static code/data size < 4GB, but not where it
    // will be in memory. Most of these could end up >2GB away so even a signed
    // pc-relative 32-bit address is insufficient, theoretically.
    if (RelocM == Reloc::PIC_) {
      PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        dwarf::DW_EH_PE_sdata8;
      LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
      FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
      TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        dwarf::DW_EH_PE_sdata8;
    } else {
      PersonalityEncoding = dwarf::DW_EH_PE_absptr;
      LSDAEncoding = dwarf::DW_EH_PE_absptr;
      FDEEncoding = dwarf::DW_EH_PE_udata4;
      TTypeEncoding = dwarf::DW_EH_PE_absptr;
    }
  } else if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le) {
    PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
      dwarf::DW_EH_PE_udata8;
    LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
    FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
    TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
      dwarf::DW_EH_PE_udata8;
  } else if (T.getArch() == Triple::sparc) {
    if (RelocM == Reloc::PIC_) {
      LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
      PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        dwarf::DW_EH_PE_sdata4;
      FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
      TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        dwarf::DW_EH_PE_sdata4;
    } else {
      LSDAEncoding = dwarf::DW_EH_PE_absptr;
      PersonalityEncoding = dwarf::DW_EH_PE_absptr;
      FDEEncoding = dwarf::DW_EH_PE_udata4;
      TTypeEncoding = dwarf::DW_EH_PE_absptr;
    }
  } else if (T.getArch() == Triple::sparcv9) {
    LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
    if (RelocM == Reloc::PIC_) {
      PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        dwarf::DW_EH_PE_sdata4;
      FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
      TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        dwarf::DW_EH_PE_sdata4;
    } else {
      PersonalityEncoding = dwarf::DW_EH_PE_absptr;
      FDEEncoding = dwarf::DW_EH_PE_udata4;
      TTypeEncoding = dwarf::DW_EH_PE_absptr;
    }
  } else if (T.getArch() == Triple::systemz) {
    // All currently-defined code models guarantee that 4-byte PC-relative
    // values will be in range.
    if (RelocM == Reloc::PIC_) {
      PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        dwarf::DW_EH_PE_sdata4;
      LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
      FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
      TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
        dwarf::DW_EH_PE_sdata4;
    } else {
      PersonalityEncoding = dwarf::DW_EH_PE_absptr;
      LSDAEncoding = dwarf::DW_EH_PE_absptr;
      FDEEncoding = dwarf::DW_EH_PE_absptr;
      TTypeEncoding = dwarf::DW_EH_PE_absptr;
    }
  }

  // Solaris requires different flags for .eh_frame to seemingly every other
  // platform.
  EHSectionType = ELF::SHT_PROGBITS;
  EHSectionFlags = ELF::SHF_ALLOC;
  if (T.getOS() == Triple::Solaris) {
    if (T.getArch() == Triple::x86_64)
      EHSectionType = ELF::SHT_X86_64_UNWIND;
    else
      EHSectionFlags |= ELF::SHF_WRITE;
  }


  // ELF
  BSSSection =
    Ctx->getELFSection(".bss", ELF::SHT_NOBITS,
                       ELF::SHF_WRITE | ELF::SHF_ALLOC,
                       SectionKind::getBSS());

  TextSection =
    Ctx->getELFSection(".text", ELF::SHT_PROGBITS,
                       ELF::SHF_EXECINSTR |
                       ELF::SHF_ALLOC,
                       SectionKind::getText());

  DataSection =
    Ctx->getELFSection(".data", ELF::SHT_PROGBITS,
                       ELF::SHF_WRITE |ELF::SHF_ALLOC,
                       SectionKind::getDataRel());

  ReadOnlySection =
    Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC,
                       SectionKind::getReadOnly());

  TLSDataSection =
    Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC | ELF::SHF_TLS |
                       ELF::SHF_WRITE,
                       SectionKind::getThreadData());

  TLSBSSSection =
    Ctx->getELFSection(".tbss", ELF::SHT_NOBITS,
                       ELF::SHF_ALLOC | ELF::SHF_TLS |
                       ELF::SHF_WRITE,
                       SectionKind::getThreadBSS());

  DataRelSection =
    Ctx->getELFSection(".data.rel", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getDataRel());

  DataRelLocalSection =
    Ctx->getELFSection(".data.rel.local", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getDataRelLocal());

  DataRelROSection =
    Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getReadOnlyWithRel());

  DataRelROLocalSection =
    Ctx->getELFSection(".data.rel.ro.local", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getReadOnlyWithRelLocal());

  MergeableConst4Section =
    Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_MERGE,
                       SectionKind::getMergeableConst4());

  MergeableConst8Section =
    Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_MERGE,
                       SectionKind::getMergeableConst8());

  MergeableConst16Section =
    Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_MERGE,
                       SectionKind::getMergeableConst16());

  StaticCtorSection =
    Ctx->getELFSection(".ctors", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getDataRel());

  StaticDtorSection =
    Ctx->getELFSection(".dtors", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC |ELF::SHF_WRITE,
                       SectionKind::getDataRel());

  // Exception Handling Sections.

  // FIXME: We're emitting LSDA info into a readonly section on ELF, 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 =
    Ctx->getELFSection(".gcc_except_table", ELF::SHT_PROGBITS,
                       ELF::SHF_ALLOC,
                       SectionKind::getReadOnly());

  // Debug Info Sections.
  DwarfAbbrevSection =
    Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfInfoSection =
    Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfLineSection =
    Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfFrameSection =
    Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfPubNamesSection =
    Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfPubTypesSection =
    Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfGnuPubNamesSection =
    Ctx->getELFSection(".debug_gnu_pubnames", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfGnuPubTypesSection =
    Ctx->getELFSection(".debug_gnu_pubtypes", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfStrSection =
    Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS,
                       ELF::SHF_MERGE | ELF::SHF_STRINGS,
                       SectionKind::getMergeable1ByteCString());
  DwarfLocSection =
    Ctx->getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfARangesSection =
    Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfRangesSection =
    Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfMacroInfoSection =
    Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());

  // DWARF5 Experimental Debug Info

  // Accelerator Tables
  DwarfAccelNamesSection =
    Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfAccelObjCSection =
    Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfAccelNamespaceSection =
    Ctx->getELFSection(".apple_namespaces", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfAccelTypesSection =
    Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());

  // Fission Sections
  DwarfInfoDWOSection =
    Ctx->getELFSection(".debug_info.dwo", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfAbbrevDWOSection =
    Ctx->getELFSection(".debug_abbrev.dwo", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfStrDWOSection =
    Ctx->getELFSection(".debug_str.dwo", ELF::SHT_PROGBITS,
                       ELF::SHF_MERGE | ELF::SHF_STRINGS,
                       SectionKind::getMergeable1ByteCString());
  DwarfLineDWOSection =
    Ctx->getELFSection(".debug_line.dwo", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfLocDWOSection =
    Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfStrOffDWOSection =
    Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
  DwarfAddrSection =
    Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0,
                       SectionKind::getMetadata());
}
/// initialize - Initialize the set of available library functions based on the
/// specified target triple.  This should be carefully written so that a missing
/// target triple gets a sane set of defaults.
static void initialize(TargetLibraryInfo &TLI, const Triple &T,
                       const char **StandardNames) {
    initializeTargetLibraryInfoPass(*PassRegistry::getPassRegistry());

#ifndef NDEBUG
    // Verify that the StandardNames array is in alphabetical order.
    for (unsigned F = 1; F < LibFunc::NumLibFuncs; ++F) {
        if (strcmp(StandardNames[F-1], StandardNames[F]) >= 0)
            llvm_unreachable("TargetLibraryInfo function names must be sorted");
    }
#endif // !NDEBUG

    // memset_pattern16 is only available on iOS 3.0 and Mac OS/X 10.5 and later.
    if (T.isMacOSX()) {
        if (T.isMacOSXVersionLT(10, 5))
            TLI.setUnavailable(LibFunc::memset_pattern16);
    } else if (T.getOS() == Triple::IOS) {
        if (T.isOSVersionLT(3, 0))
            TLI.setUnavailable(LibFunc::memset_pattern16);
    } else {
        TLI.setUnavailable(LibFunc::memset_pattern16);
    }

    if (T.isMacOSX() && T.getArch() == Triple::x86 &&
            !T.isMacOSXVersionLT(10, 7)) {
        // x86-32 OSX has a scheme where fwrite and fputs (and some other functions
        // we don't care about) have two versions; on recent OSX, the one we want
        // has a $UNIX2003 suffix. The two implementations are identical except
        // for the return value in some edge cases.  However, we don't want to
        // generate code that depends on the old symbols.
        TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003");
        TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003");
    }

    // iprintf and friends are only available on XCore and TCE.
    if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) {
        TLI.setUnavailable(LibFunc::iprintf);
        TLI.setUnavailable(LibFunc::siprintf);
        TLI.setUnavailable(LibFunc::fiprintf);
    }

    if (T.getOS() == Triple::Win32) {
        // Win32 does not support long double
        TLI.setUnavailable(LibFunc::acosl);
        TLI.setUnavailable(LibFunc::asinl);
        TLI.setUnavailable(LibFunc::atanl);
        TLI.setUnavailable(LibFunc::atan2l);
        TLI.setUnavailable(LibFunc::ceill);
        TLI.setUnavailable(LibFunc::copysignl);
        TLI.setUnavailable(LibFunc::cosl);
        TLI.setUnavailable(LibFunc::coshl);
        TLI.setUnavailable(LibFunc::expl);
        TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf
        TLI.setUnavailable(LibFunc::fabsl);
        TLI.setUnavailable(LibFunc::floorl);
        TLI.setUnavailable(LibFunc::fmodl);
        TLI.setUnavailable(LibFunc::logl);
        TLI.setUnavailable(LibFunc::powl);
        TLI.setUnavailable(LibFunc::sinl);
        TLI.setUnavailable(LibFunc::sinhl);
        TLI.setUnavailable(LibFunc::sqrtl);
        TLI.setUnavailable(LibFunc::tanl);
        TLI.setUnavailable(LibFunc::tanhl);

        // Win32 only has C89 math
        TLI.setUnavailable(LibFunc::acosh);
        TLI.setUnavailable(LibFunc::acoshf);
        TLI.setUnavailable(LibFunc::acoshl);
        TLI.setUnavailable(LibFunc::asinh);
        TLI.setUnavailable(LibFunc::asinhf);
        TLI.setUnavailable(LibFunc::asinhl);
        TLI.setUnavailable(LibFunc::atanh);
        TLI.setUnavailable(LibFunc::atanhf);
        TLI.setUnavailable(LibFunc::atanhl);
        TLI.setUnavailable(LibFunc::cbrt);
        TLI.setUnavailable(LibFunc::cbrtf);
        TLI.setUnavailable(LibFunc::cbrtl);
        TLI.setUnavailable(LibFunc::exp10);
        TLI.setUnavailable(LibFunc::exp10f);
        TLI.setUnavailable(LibFunc::exp10l);
        TLI.setUnavailable(LibFunc::exp2);
        TLI.setUnavailable(LibFunc::exp2f);
        TLI.setUnavailable(LibFunc::exp2l);
        TLI.setUnavailable(LibFunc::expm1);
        TLI.setUnavailable(LibFunc::expm1f);
        TLI.setUnavailable(LibFunc::expm1l);
        TLI.setUnavailable(LibFunc::log2);
        TLI.setUnavailable(LibFunc::log2f);
        TLI.setUnavailable(LibFunc::log2l);
        TLI.setUnavailable(LibFunc::log1p);
        TLI.setUnavailable(LibFunc::log1pf);
        TLI.setUnavailable(LibFunc::log1pl);
        TLI.setUnavailable(LibFunc::logb);
        TLI.setUnavailable(LibFunc::logbf);
        TLI.setUnavailable(LibFunc::logbl);
        TLI.setUnavailable(LibFunc::nearbyint);
        TLI.setUnavailable(LibFunc::nearbyintf);
        TLI.setUnavailable(LibFunc::nearbyintl);
        TLI.setUnavailable(LibFunc::rint);
        TLI.setUnavailable(LibFunc::rintf);
        TLI.setUnavailable(LibFunc::rintl);
        TLI.setUnavailable(LibFunc::round);
        TLI.setUnavailable(LibFunc::roundf);
        TLI.setUnavailable(LibFunc::roundl);
        TLI.setUnavailable(LibFunc::trunc);
        TLI.setUnavailable(LibFunc::truncf);
        TLI.setUnavailable(LibFunc::truncl);

        // Win32 provides some C99 math with mangled names
        TLI.setAvailableWithName(LibFunc::copysign, "_copysign");

        if (T.getArch() == Triple::x86) {
            // Win32 on x86 implements single-precision math functions as macros
            TLI.setUnavailable(LibFunc::acosf);
            TLI.setUnavailable(LibFunc::asinf);
            TLI.setUnavailable(LibFunc::atanf);
            TLI.setUnavailable(LibFunc::atan2f);
            TLI.setUnavailable(LibFunc::ceilf);
            TLI.setUnavailable(LibFunc::copysignf);
            TLI.setUnavailable(LibFunc::cosf);
            TLI.setUnavailable(LibFunc::coshf);
            TLI.setUnavailable(LibFunc::expf);
            TLI.setUnavailable(LibFunc::floorf);
            TLI.setUnavailable(LibFunc::fmodf);
            TLI.setUnavailable(LibFunc::logf);
            TLI.setUnavailable(LibFunc::powf);
            TLI.setUnavailable(LibFunc::sinf);
            TLI.setUnavailable(LibFunc::sinhf);
            TLI.setUnavailable(LibFunc::sqrtf);
            TLI.setUnavailable(LibFunc::tanf);
            TLI.setUnavailable(LibFunc::tanhf);
        }

        // Win32 does *not* provide stpcpy.  It is provided on POSIX systems:
        // http://pubs.opengroup.org/onlinepubs/9699919799/functions/stpcpy.html
        TLI.setUnavailable(LibFunc::stpcpy);

        // Win32 does *not* provide ffs.  It is provided on POSIX systems:
        // http://pubs.opengroup.org/onlinepubs/009695399/functions/ffs.html
        TLI.setUnavailable(LibFunc::ffs);

        // Win32 does *not* provide llabs.  It is defined in ISO/IEC 9899:1999,
        // but Visual C++ does not support it.
        TLI.setUnavailable(LibFunc::llabs);
    }

    // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and
    // Linux (GLIBC):
    // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html
    // http://svn.freebsd.org/base/user/eri/pf45/head/lib/libc/string/ffsl.c
    // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html
    switch (T.getOS()) {
    case Triple::Darwin:
    case Triple::MacOSX:
    case Triple::IOS:
    case Triple::FreeBSD:
    case Triple::Linux:
        break;
    default:
        TLI.setUnavailable(LibFunc::ffsl);
    }

    // ffsll is available on at least FreeBSD and Linux (GLIBC):
    // http://svn.freebsd.org/base/user/eri/pf45/head/lib/libc/string/ffsll.c
    // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html
    switch (T.getOS()) {
    case Triple::FreeBSD:
    case Triple::Linux:
        break;
    default:
        TLI.setUnavailable(LibFunc::ffsll);
    }
}
Example #5
0
static int compileModule(char **argv, LLVMContext &Context) {
  // Load the module to be compiled...
  SMDiagnostic Err;
  OwningPtr<Module> M;
  Module *mod = 0;
  Triple TheTriple;

  bool SkipModule = MCPU == "help" ||
                    (!MAttrs.empty() && MAttrs.front() == "help");

  // If user just wants to list available options, skip module loading
  if (!SkipModule) {
    M.reset(ParseIRFile(InputFilename, Err, Context));
    mod = M.get();
    if (mod == 0) {
      Err.print(argv[0], errs());
      return 1;
    }

    // If we are supposed to override the target triple, do so now.
    if (!TargetTriple.empty())
      mod->setTargetTriple(Triple::normalize(TargetTriple));
    TheTriple = Triple(mod->getTargetTriple());
  } else {
    TheTriple = Triple(Triple::normalize(TargetTriple));
  }

  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getDefaultTargetTriple());

  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
                                                         Error);
  if (!TheTarget) {
    errs() << argv[0] << ": " << Error;
    return 1;
  }

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  TargetOptions Options;
  Options.LessPreciseFPMADOption = EnableFPMAD;
  Options.NoFramePointerElim = DisableFPElim;
  Options.AllowFPOpFusion = FuseFPOps;
  Options.UnsafeFPMath = EnableUnsafeFPMath;
  Options.NoInfsFPMath = EnableNoInfsFPMath;
  Options.NoNaNsFPMath = EnableNoNaNsFPMath;
  Options.HonorSignDependentRoundingFPMathOption =
      EnableHonorSignDependentRoundingFPMath;
  Options.UseSoftFloat = GenerateSoftFloatCalls;
  if (FloatABIForCalls != FloatABI::Default)
    Options.FloatABIType = FloatABIForCalls;
  Options.NoZerosInBSS = DontPlaceZerosInBSS;
  Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
  Options.DisableTailCalls = DisableTailCalls;
  Options.StackAlignmentOverride = OverrideStackAlignment;
  Options.TrapFuncName = TrapFuncName;
  Options.PositionIndependentExecutable = EnablePIE;
  Options.EnableSegmentedStacks = SegmentedStacks;
  Options.UseInitArray = UseInitArray;

  OwningPtr<TargetMachine>
    target(TheTarget->createTargetMachine(TheTriple.getTriple(),
                                          MCPU, FeaturesStr, Options,
                                          RelocModel, CMModel, OLvl));
  assert(target.get() && "Could not allocate target machine!");
  assert(mod && "Should have exited after outputting help!");
  TargetMachine &Target = *target.get();

  if (DisableDotLoc)
    Target.setMCUseLoc(false);

  if (DisableCFI)
    Target.setMCUseCFI(false);

  if (EnableDwarfDirectory)
    Target.setMCUseDwarfDirectory(true);

  if (GenerateSoftFloatCalls)
    FloatABIForCalls = FloatABI::Soft;

  // Disable .loc support for older OS X versions.
  if (TheTriple.isMacOSX() &&
      TheTriple.isMacOSXVersionLT(10, 6))
    Target.setMCUseLoc(false);

  // Figure out where we are going to send the output.
  OwningPtr<tool_output_file> Out
    (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]));
  if (!Out) return 1;

  // Build up all of the passes that we want to do to the module.
  PassManager PM;

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple);
  if (DisableSimplifyLibCalls)
    TLI->disableAllFunctions();
  PM.add(TLI);

  // Add intenal analysis passes from the target machine.
  Target.addAnalysisPasses(PM);

  // Add the target data from the target machine, if it exists, or the module.
  if (const DataLayout *TD = Target.getDataLayout())
    PM.add(new DataLayout(*TD));
  else
    PM.add(new DataLayout(mod));

  // Override default to generate verbose assembly.
  Target.setAsmVerbosityDefault(true);

  if (RelaxAll) {
    if (FileType != TargetMachine::CGFT_ObjectFile)
      errs() << argv[0]
             << ": warning: ignoring -mc-relax-all because filetype != obj";
    else
      Target.setMCRelaxAll(true);
  }

  {
    formatted_raw_ostream FOS(Out->os());

    AnalysisID StartAfterID = 0;
    AnalysisID StopAfterID = 0;
    const PassRegistry *PR = PassRegistry::getPassRegistry();
    if (!StartAfter.empty()) {
      const PassInfo *PI = PR->getPassInfo(StartAfter);
      if (!PI) {
        errs() << argv[0] << ": start-after pass is not registered.\n";
        return 1;
      }
      StartAfterID = PI->getTypeInfo();
    }
    if (!StopAfter.empty()) {
      const PassInfo *PI = PR->getPassInfo(StopAfter);
      if (!PI) {
        errs() << argv[0] << ": stop-after pass is not registered.\n";
        return 1;
      }
      StopAfterID = PI->getTypeInfo();
    }

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify,
                                   StartAfterID, StopAfterID)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      return 1;
    }

    // Before executing passes, print the final values of the LLVM options.
    cl::PrintOptionValues();

    PM.run(*mod);
  }

  // Declare success.
  Out->keep();

  return 0;
}
Example #6
0
static int compileModule(char **argv, LLVMContext &Context) {
  // Load the module to be compiled...
  SMDiagnostic Err;
  std::unique_ptr<Module> M;
  std::unique_ptr<MIRParser> MIR;
  Triple TheTriple;

  bool SkipModule = MCPU == "help" ||
                    (!MAttrs.empty() && MAttrs.front() == "help");

  // If user just wants to list available options, skip module loading
  if ((!SkipModule) && (!PrintInstructions.getValue())) {
    if (StringRef(InputFilename).endswith_lower(".mir")) {
      MIR = createMIRParserFromFile(InputFilename, Err, Context);
      if (MIR) {
        M = MIR->parseLLVMModule();
        assert(M && "parseLLVMModule should exit on failure");
      }
    } else
      M = parseIRFile(InputFilename, Err, Context);
    if (!M) {
      Err.print(argv[0], errs());
      return 1;
    }

    // Verify module immediately to catch problems before doInitialization() is
    // called on any passes.
    if (!NoVerify && verifyModule(*M, &errs())) {
      errs() << argv[0] << ": " << InputFilename
             << ": error: input module is broken!\n";
      return 1;
    }

    // If we are supposed to override the target triple, do so now.
    if (!TargetTriple.empty())
      M->setTargetTriple(Triple::normalize(TargetTriple));
    TheTriple = Triple(M->getTargetTriple());
  } else {
    TheTriple = Triple(Triple::normalize(TargetTriple));
  }

  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getDefaultTargetTriple());

  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
                                                         Error);
  if (!TheTarget) {
    errs() << argv[0] << ": " << Error;
    return 1;
  }

  std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr();

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  Options.DisableIntegratedAS = NoIntegratedAssembler;
  Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
  Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory;
  Options.MCOptions.AsmVerbose = AsmVerbose;

  std::unique_ptr<TargetMachine> Target(
      TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr, FeaturesStr,
                                     Options, RelocModel, CMModel, OLvl));

  assert(Target && "Could not allocate target machine!");

  // If we don't have a module then just exit now. We do this down
  // here since the CPU/Feature help is underneath the target machine
  // creation.
  if (SkipModule)
    return 0;
  
  // Figure out where we are going to send the output.
  std::unique_ptr<tool_output_file> Out =
      GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]);
  if (!Out) return 1;

  {
    raw_pwrite_stream *OS = &Out->os();
    std::unique_ptr<buffer_ostream> BOS;
    if (FileType != TargetMachine::CGFT_AssemblyFile &&
        !Out->os().supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(*OS);
      OS = BOS.get();
    }
    

  if (PrintInstructions.getValue()) {
    printInstructions(TheTarget, OS);
    Out->keep();
    return 0;
  }


  assert(M && "Should have exited if we didn't have a module!");
  if (FloatABIForCalls != FloatABI::Default)
    Options.FloatABIType = FloatABIForCalls;

  // Build up all of the passes that we want to do to the module.
  legacy::PassManager PM;

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));

  // The -disable-simplify-libcalls flag actually disables all builtin optzns.
  if (DisableSimplifyLibCalls)
    TLII.disableAllFunctions();
  PM.add(new TargetLibraryInfoWrapperPass(TLII));

  // Add the target data from the target machine, if it exists, or the module.
  M->setDataLayout(Target->createDataLayout());

  // Override function attributes based on CPUStr, FeaturesStr, and command line
  // flags.
  setFunctionAttributes(CPUStr, FeaturesStr, *M);

  if (RelaxAll.getNumOccurrences() > 0 &&
      FileType != TargetMachine::CGFT_ObjectFile)
    errs() << argv[0]
             << ": warning: ignoring -mc-relax-all because filetype != obj";


    AnalysisID StartBeforeID = nullptr;
    AnalysisID StartAfterID = nullptr;
    AnalysisID StopAfterID = nullptr;
    const PassRegistry *PR = PassRegistry::getPassRegistry();
    if (!RunPass.empty()) {
      if (!StartAfter.empty() || !StopAfter.empty()) {
        errs() << argv[0] << ": start-after and/or stop-after passes are "
                             "redundant when run-pass is specified.\n";
        return 1;
      }
      const PassInfo *PI = PR->getPassInfo(RunPass);
      if (!PI) {
        errs() << argv[0] << ": run-pass pass is not registered.\n";
        return 1;
      }
      StopAfterID = StartBeforeID = PI->getTypeInfo();
    } else {
      if (!StartAfter.empty()) {
        const PassInfo *PI = PR->getPassInfo(StartAfter);
        if (!PI) {
          errs() << argv[0] << ": start-after pass is not registered.\n";
          return 1;
        }
        StartAfterID = PI->getTypeInfo();
      }
      if (!StopAfter.empty()) {
        const PassInfo *PI = PR->getPassInfo(StopAfter);
        if (!PI) {
          errs() << argv[0] << ": stop-after pass is not registered.\n";
          return 1;
        }
        StopAfterID = PI->getTypeInfo();
      }
    }

    // Ask the target to add backend passes as necessary.
    if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartBeforeID,
                                    StartAfterID, StopAfterID, MIR.get())) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      return 1;
    }

    // Before executing passes, print the final values of the LLVM options.
    cl::PrintOptionValues();

    PM.run(*M);
  }

  // Declare success.
  Out->keep();

  return 0;
}
Example #7
0
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
  if (TT.getOS() == Triple::AMDHSA)
    return make_unique<AMDGPUHSATargetObjectFile>();

  return make_unique<AMDGPUTargetObjectFile>();
}