diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 3a27ef8c8fe..8cf9e1cc55a 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -42,12 +42,11 @@ protected: /// dwarf unwind. bool OmitDwarfIfHaveCompactUnwind; - /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values - /// for EH. - unsigned PersonalityEncoding; - unsigned LSDAEncoding; - unsigned FDECFIEncoding; - unsigned TTypeEncoding; + /// FDE CFI encoding. Controls the encoding of the begin label in the + /// .eh_frame section. Unlike the LSDA encoding, personality encoding, and + /// type encodings, this is something that the assembler just "knows" about + /// its target + unsigned FDECFIEncoding = 0; /// Compact unwind encoding indicating that we should emit only an EH frame. unsigned CompactUnwindDwarfEHFrameOnly; @@ -226,10 +225,7 @@ public: return CommDirectiveSupportsAlignment; } - unsigned getPersonalityEncoding() const { return PersonalityEncoding; } - unsigned getLSDAEncoding() const { return LSDAEncoding; } unsigned getFDEEncoding() const { return FDECFIEncoding; } - unsigned getTTypeEncoding() const { return TTypeEncoding; } unsigned getCompactUnwindDwarfEHFrameOnly() const { return CompactUnwindDwarfEHFrameOnly; diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index b07f26deada..40b77c3d94a 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -47,6 +47,12 @@ protected: bool SupportGOTPCRelWithOffset = true; bool SupportDebugThreadLocalLocation = true; + /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values + /// for EH. + unsigned PersonalityEncoding = 0; + unsigned LSDAEncoding = 0; + unsigned TTypeEncoding = 0; + /// This section contains the static constructor pointer list. MCSection *StaticCtorSection = nullptr; @@ -136,6 +142,10 @@ public: const TargetMachine &TM, MachineModuleInfo *MMI) const; + unsigned getPersonalityEncoding() const { return PersonalityEncoding; } + unsigned getLSDAEncoding() const { return LSDAEncoding; } + unsigned getTTypeEncoding() const { return TTypeEncoding; } + const MCExpr *getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, MCStreamer &Streamer) const; diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index f6b91a2f023..2b571a02b4d 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -95,6 +95,156 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, const TargetMachine &TgtM) { TargetLoweringObjectFile::Initialize(Ctx, TgtM); TM = &TgtM; + + bool Large = TgtM.getCodeModel() == CodeModel::Large; + + switch (TgtM.getTargetTriple().getArch()) { + case Triple::arm: + case Triple::armeb: + case Triple::thumb: + case Triple::thumbeb: + if (Ctx.getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM) + break; + // Fallthrough if not using EHABI + LLVM_FALLTHROUGH; + case Triple::ppc: + case Triple::x86: + PersonalityEncoding = isPositionIndependent() + ? dwarf::DW_EH_PE_indirect | + dwarf::DW_EH_PE_pcrel | + dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; + LSDAEncoding = isPositionIndependent() + ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; + TTypeEncoding = isPositionIndependent() + ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; + break; + case Triple::x86_64: + if (isPositionIndependent()) { + PersonalityEncoding = + dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); + LSDAEncoding = dwarf::DW_EH_PE_pcrel | + (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); + TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); + } else { + PersonalityEncoding = + Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; + LSDAEncoding = Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; + TTypeEncoding = Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; + } + break; + case Triple::hexagon: + PersonalityEncoding = dwarf::DW_EH_PE_absptr; + LSDAEncoding = dwarf::DW_EH_PE_absptr; + TTypeEncoding = dwarf::DW_EH_PE_absptr; + if (isPositionIndependent()) { + PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; + LSDAEncoding |= dwarf::DW_EH_PE_pcrel; + TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; + } + break; + case Triple::aarch64: + case Triple::aarch64_be: + // 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 (isPositionIndependent()) { + 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; + 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; + TTypeEncoding = dwarf::DW_EH_PE_absptr; + } + break; + case Triple::lanai: + LSDAEncoding = dwarf::DW_EH_PE_absptr; + PersonalityEncoding = dwarf::DW_EH_PE_absptr; + TTypeEncoding = dwarf::DW_EH_PE_absptr; + break; + case Triple::mips: + case Triple::mipsel: + case Triple::mips64: + case Triple::mips64el: + // MIPS uses indirect pointer to refer personality functions and types, so + // that the eh_frame section can be read-only. DW.ref.personality will be + // generated for relocation. + PersonalityEncoding = dwarf::DW_EH_PE_indirect; + // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't + // identify N64 from just a triple. + TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + dwarf::DW_EH_PE_sdata4; + // We don't support PC-relative LSDA references in GAS so we use the default + // DW_EH_PE_absptr for those. + + // FreeBSD must be explicit about the data size and using pcrel since it's + // assembler/linker won't do the automatic conversion that the Linux tools + // do. + if (TgtM.getTargetTriple().isOSFreeBSD()) { + PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + } + break; + case Triple::ppc64: + case 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; + TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + dwarf::DW_EH_PE_udata8; + break; + case Triple::sparcel: + case Triple::sparc: + if (isPositionIndependent()) { + 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; + 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; + TTypeEncoding = dwarf::DW_EH_PE_absptr; + } + break; + case Triple::sparcv9: + LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + if (isPositionIndependent()) { + PersonalityEncoding = dwarf::DW_EH_PE_indirect | 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; + TTypeEncoding = dwarf::DW_EH_PE_absptr; + } + break; + case Triple::systemz: + // All currently-defined code models guarantee that 4-byte PC-relative + // values will be in range. + if (isPositionIndependent()) { + 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; + 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; + TTypeEncoding = dwarf::DW_EH_PE_absptr; + } + break; + default: + break; + } } void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, @@ -684,6 +834,12 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, MachO::S_MOD_TERM_FUNC_POINTERS, SectionKind::getData()); } + + PersonalityEncoding = + dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + LSDAEncoding = dwarf::DW_EH_PE_pcrel; + TTypeEncoding = + dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; } void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index b88d2d80182..8f1ca4ed619 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -63,11 +63,7 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) { if (T.isWatchABI()) OmitDwarfIfHaveCompactUnwind = true; - PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel - | dwarf::DW_EH_PE_sdata4; - LSDAEncoding = FDECFIEncoding = dwarf::DW_EH_PE_pcrel; - TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata4; + FDECFIEncoding = dwarf::DW_EH_PE_pcrel; // .comm doesn't support alignment before Leopard. if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5)) @@ -311,161 +307,14 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { case Triple::bpfeb: FDECFIEncoding = dwarf::DW_EH_PE_sdata8; break; + case Triple::hexagon: + FDECFIEncoding = + PositionIndependent ? dwarf::DW_EH_PE_pcrel : dwarf::DW_EH_PE_absptr; default: FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; break; } - switch (T.getArch()) { - case Triple::arm: - case Triple::armeb: - case Triple::thumb: - case Triple::thumbeb: - if (Ctx->getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM) - break; - // Fallthrough if not using EHABI - LLVM_FALLTHROUGH; - case Triple::ppc: - case Triple::x86: - PersonalityEncoding = PositionIndependent - ? dwarf::DW_EH_PE_indirect | - dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata4 - : dwarf::DW_EH_PE_absptr; - LSDAEncoding = PositionIndependent - ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 - : dwarf::DW_EH_PE_absptr; - TTypeEncoding = PositionIndependent - ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata4 - : dwarf::DW_EH_PE_absptr; - break; - case Triple::x86_64: - if (PositionIndependent) { - PersonalityEncoding = - dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); - LSDAEncoding = dwarf::DW_EH_PE_pcrel | - (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); - TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); - } else { - PersonalityEncoding = - Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; - LSDAEncoding = Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; - TTypeEncoding = Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; - } - break; - case Triple::hexagon: - PersonalityEncoding = dwarf::DW_EH_PE_absptr; - LSDAEncoding = dwarf::DW_EH_PE_absptr; - FDECFIEncoding = dwarf::DW_EH_PE_absptr; - TTypeEncoding = dwarf::DW_EH_PE_absptr; - if (PositionIndependent) { - PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; - LSDAEncoding |= dwarf::DW_EH_PE_pcrel; - FDECFIEncoding |= dwarf::DW_EH_PE_pcrel; - TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel; - } - break; - case Triple::aarch64: - case Triple::aarch64_be: - // 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 (PositionIndependent) { - 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; - 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; - TTypeEncoding = dwarf::DW_EH_PE_absptr; - } - break; - case Triple::lanai: - LSDAEncoding = dwarf::DW_EH_PE_absptr; - PersonalityEncoding = dwarf::DW_EH_PE_absptr; - TTypeEncoding = dwarf::DW_EH_PE_absptr; - break; - case Triple::mips: - case Triple::mipsel: - case Triple::mips64: - case Triple::mips64el: - // MIPS uses indirect pointer to refer personality functions and types, so - // that the eh_frame section can be read-only. DW.ref.personality will be - // generated for relocation. - PersonalityEncoding = dwarf::DW_EH_PE_indirect; - // FIXME: The N64 ABI probably ought to use DW_EH_PE_sdata8 but we can't - // identify N64 from just a triple. - TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata4; - // We don't support PC-relative LSDA references in GAS so we use the default - // DW_EH_PE_absptr for those. - - // FreeBSD must be explicit about the data size and using pcrel since it's - // assembler/linker won't do the automatic conversion that the Linux tools - // do. - if (T.isOSFreeBSD()) { - PersonalityEncoding |= dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - } - break; - case Triple::ppc64: - case 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; - TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_udata8; - break; - case Triple::sparcel: - case Triple::sparc: - if (PositionIndependent) { - 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; - 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; - TTypeEncoding = dwarf::DW_EH_PE_absptr; - } - break; - case Triple::sparcv9: - LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - if (PositionIndependent) { - PersonalityEncoding = dwarf::DW_EH_PE_indirect | 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; - TTypeEncoding = dwarf::DW_EH_PE_absptr; - } - break; - case Triple::systemz: - // All currently-defined code models guarantee that 4-byte PC-relative - // values will be in range. - if (PositionIndependent) { - 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; - 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; - TTypeEncoding = dwarf::DW_EH_PE_absptr; - } - break; - default: - break; - } - unsigned EHSectionType = T.getArch() == Triple::x86_64 ? ELF::SHT_X86_64_UNWIND : ELF::SHT_PROGBITS; @@ -908,8 +757,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, SupportsCompactUnwindWithoutEHFrame = false; OmitDwarfIfHaveCompactUnwind = false; - PersonalityEncoding = LSDAEncoding = FDECFIEncoding = TTypeEncoding = - dwarf::DW_EH_PE_absptr; + FDECFIEncoding = dwarf::DW_EH_PE_absptr; CompactUnwindDwarfEHFrameOnly = 0; diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index 6bcf60fafc3..bb937923b47 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -45,6 +45,9 @@ void TargetLoweringObjectFile::Initialize(MCContext &ctx, Mang = new Mangler(); InitMCObjectFileInfo(TM.getTargetTriple(), TM.isPositionIndependent(), *Ctx, TM.getCodeModel() == CodeModel::Large); + + // Reset various EH DWARF encodings. + PersonalityEncoding = LSDAEncoding = TTypeEncoding = dwarf::DW_EH_PE_absptr; } TargetLoweringObjectFile::~TargetLoweringObjectFile() {