diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 93 | ||||
-rw-r--r-- | llvm/test/Object/objc-imageinfo-coff.ll | 14 | ||||
-rw-r--r-- | llvm/test/Object/objc-imageinfo-elf.ll | 14 | ||||
-rw-r--r-- | llvm/test/Object/objc-imageinfo-macho.ll | 14 |
5 files changed, 118 insertions, 25 deletions
diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index adf2b3ea1c9..106a084a95c 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -41,6 +41,11 @@ public: TargetLoweringObjectFileELF() = default; ~TargetLoweringObjectFileELF() override = default; + /// Emit Obj-C garbage collection and linker options. + void emitModuleFlags(MCStreamer &Streamer, + ArrayRef<Module::ModuleFlagEntry> ModuleFlags, + const TargetMachine &TM) const override; + void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, const MCSymbol *Sym) const override; @@ -149,8 +154,7 @@ public: MCSection *getSectionForJumpTable(const Function &F, const TargetMachine &TM) const override; - /// Emit Obj-C garbage collection and linker options. Only linker option - /// emission is implemented for COFF. + /// Emit Obj-C garbage collection and linker options. void emitModuleFlags(MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const override; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 3ba4a3a2926..24baa59db5d 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -61,10 +61,53 @@ using namespace llvm; using namespace dwarf; +static void GetObjCImageInfo(ArrayRef<Module::ModuleFlagEntry> ModuleFlags, + unsigned &Version, unsigned &Flags, + StringRef &Section) { + for (const auto &MFE: ModuleFlags) { + // Ignore flags with 'Require' behaviour. + if (MFE.Behavior == Module::Require) + continue; + + StringRef Key = MFE.Key->getString(); + if (Key == "Objective-C Image Info Version") { + Version = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); + } else if (Key == "Objective-C Garbage Collection" || + Key == "Objective-C GC Only" || + Key == "Objective-C Is Simulated" || + Key == "Objective-C Class Properties" || + Key == "Objective-C Image Swift Version") { + Flags |= mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue(); + } else if (Key == "Objective-C Image Info Section") { + Section = cast<MDString>(MFE.Val)->getString(); + } + } +} + //===----------------------------------------------------------------------===// // ELF //===----------------------------------------------------------------------===// +void TargetLoweringObjectFileELF::emitModuleFlags( + MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, + const TargetMachine &TM) const { + unsigned Version = 0; + unsigned Flags = 0; + StringRef Section; + + GetObjCImageInfo(ModuleFlags, Version, Flags, Section); + if (Section.empty()) + return; + + auto &C = getContext(); + auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); + Streamer.SwitchSection(S); + Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); + Streamer.EmitIntValue(Version, 4); + Streamer.EmitIntValue(Flags, 4); + Streamer.AddBlankLine(); +} + MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( const GlobalValue *GV, const TargetMachine &TM, MachineModuleInfo *MMI) const { @@ -579,32 +622,12 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, void TargetLoweringObjectFileMachO::emitModuleFlags( MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const { - unsigned VersionVal = 0; - unsigned ImageInfoFlags = 0; MDNode *LinkerOptions = nullptr; - StringRef SectionVal; for (const auto &MFE : ModuleFlags) { - // Ignore flags with 'Require' behavior. - if (MFE.Behavior == Module::Require) - continue; - StringRef Key = MFE.Key->getString(); - Metadata *Val = MFE.Val; - - if (Key == "Objective-C Image Info Version") { - VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue(); - } else if (Key == "Objective-C Garbage Collection" || - Key == "Objective-C GC Only" || - Key == "Objective-C Is Simulated" || - Key == "Objective-C Class Properties" || - Key == "Objective-C Image Swift Version") { - ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue(); - } else if (Key == "Objective-C Image Info Section") { - SectionVal = cast<MDString>(Val)->getString(); - } else if (Key == "Linker Options") { - LinkerOptions = cast<MDNode>(Val); - } + if (Key == "Linker Options") + LinkerOptions = cast<MDNode>(MFE.Val); } // Emit the linker options if present. @@ -617,8 +640,14 @@ void TargetLoweringObjectFileMachO::emitModuleFlags( } } + unsigned VersionVal = 0; + unsigned ImageInfoFlags = 0; + StringRef SectionVal; + GetObjCImageInfo(ModuleFlags, VersionVal, ImageInfoFlags, SectionVal); + // The section is mandatory. If we don't have it, then we don't have GC info. - if (SectionVal.empty()) return; + if (SectionVal.empty()) + return; StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; @@ -1156,6 +1185,24 @@ void TargetLoweringObjectFileCOFF::emitModuleFlags( } } } + + unsigned Version = 0; + unsigned Flags = 0; + StringRef Section; + + GetObjCImageInfo(ModuleFlags, Version, Flags, Section); + if (Section.empty()) + return; + + auto &C = getContext(); + auto *S = C.getCOFFSection( + Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, + SectionKind::getReadOnly()); + Streamer.SwitchSection(S); + Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); + Streamer.EmitIntValue(Version, 4); + Streamer.EmitIntValue(Flags, 4); + Streamer.AddBlankLine(); } void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, diff --git a/llvm/test/Object/objc-imageinfo-coff.ll b/llvm/test/Object/objc-imageinfo-coff.ll new file mode 100644 index 00000000000..cab0103b5f4 --- /dev/null +++ b/llvm/test/Object/objc-imageinfo-coff.ll @@ -0,0 +1,14 @@ +; RUN: llc -mtriple x86_64-unknown-windows-msvc -filetype asm -o - %s | FileCheck %s + +!llvm.module.flags = !{!0, !1, !2, !3} + +!0 = !{i32 1, !"Objective-C Version", i32 2} +!1 = !{i32 1, !"Objective-C Image Info Version", i32 0} +!2 = !{i32 1, !"Objective-C Image Info Section", !".objc_imageinfo$B"} +!3 = !{i32 1, !"Objective-C Garbage Collection", i32 2} + +; CHECK: .section .objc_imageinfo$B,"dr" +; CHECK: OBJC_IMAGE_INFO: +; CHECK: .long 0 +; CHECK: .long 2 + diff --git a/llvm/test/Object/objc-imageinfo-elf.ll b/llvm/test/Object/objc-imageinfo-elf.ll new file mode 100644 index 00000000000..7979e01457f --- /dev/null +++ b/llvm/test/Object/objc-imageinfo-elf.ll @@ -0,0 +1,14 @@ +; RUN: llc -mtriple x86_64-unknown-linux-gnu -filetype asm -o - %s | FileCheck %s + +!llvm.module.flags = !{!0, !1, !2, !3} + +!0 = !{i32 1, !"Objective-C Version", i32 2} +!1 = !{i32 1, !"Objective-C Image Info Version", i32 0} +!2 = !{i32 1, !"Objective-C Image Info Section", !"objc_imageinfo"} +!3 = !{i32 1, !"Objective-C Garbage Collection", i32 2} + +; CHECK: .section objc_imageinfo +; CHECK: OBJC_IMAGE_INFO: +; CHECK: .long 0 +; CHECK: .long 2 + diff --git a/llvm/test/Object/objc-imageinfo-macho.ll b/llvm/test/Object/objc-imageinfo-macho.ll new file mode 100644 index 00000000000..90bc9d91a5d --- /dev/null +++ b/llvm/test/Object/objc-imageinfo-macho.ll @@ -0,0 +1,14 @@ +; RUN: llc -mtriple x86_64-apple-ios -filetype asm -o - %s | FileCheck %s + +!llvm.module.flags = !{!0, !1, !2, !3} + +!0 = !{i32 1, !"Objective-C Version", i32 2} +!1 = !{i32 1, !"Objective-C Image Info Version", i32 0} +!2 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"} +!3 = !{i32 1, !"Objective-C Garbage Collection", i32 2} + +; CHECK: .section __DATA,__objc_imageinfo,regular,no_dead_strip +; CHECK: L_OBJC_IMAGE_INFO: +; CHECK: .long 0 +; CHECK: .long 2 + |