diff --git a/llvm/include/llvm/BinaryFormat/MachO.h b/llvm/include/llvm/BinaryFormat/MachO.h --- a/llvm/include/llvm/BinaryFormat/MachO.h +++ b/llvm/include/llvm/BinaryFormat/MachO.h @@ -174,8 +174,10 @@ /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local /// variable initialization pointers to functions. S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u, + /// S_ADDRSIG - Section with list of sybols marked as address significant. + S_ADDRSIG = 0x16u, - LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS + LAST_KNOWN_SECTION_TYPE = S_ADDRSIG }; enum : uint32_t { diff --git a/llvm/include/llvm/MC/MCMachObjectWriter.h b/llvm/include/llvm/MC/MCMachObjectWriter.h --- a/llvm/include/llvm/MC/MCMachObjectWriter.h +++ b/llvm/include/llvm/MC/MCMachObjectWriter.h @@ -264,6 +264,8 @@ bool IsPCRel) const override; uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; + + void writeAddrsigSection(MCAssembler &Asm); }; /// Construct a new Mach-O writer instance. diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h --- a/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -213,6 +213,7 @@ MCSection *LazySymbolPointerSection = nullptr; MCSection *NonLazySymbolPointerSection = nullptr; MCSection *ThreadLocalPointerSection = nullptr; + MCSection *AddrSigSection = nullptr; /// COFF specific sections. MCSection *DrectveSection = nullptr; @@ -410,6 +411,7 @@ MCSection *getThreadLocalPointerSection() const { return ThreadLocalPointerSection; } + MCSection *getAddrSigSection() const { return AddrSigSection; } // COFF specific sections. MCSection *getDrectveSection() const { return DrectveSection; } diff --git a/llvm/include/llvm/MC/MCObjectWriter.h b/llvm/include/llvm/MC/MCObjectWriter.h --- a/llvm/include/llvm/MC/MCObjectWriter.h +++ b/llvm/include/llvm/MC/MCObjectWriter.h @@ -10,6 +10,7 @@ #define LLVM_MC_MCOBJECTWRITER_H #include "llvm/ADT/Triple.h" +#include "llvm/MC/MCSymbol.h" #include namespace llvm { @@ -32,6 +33,9 @@ /// should be emitted as part of writeObject(). class MCObjectWriter { protected: + bool EmitAddrsigSection = false; + std::vector AddrsigSyms; + MCObjectWriter() = default; public: @@ -91,11 +95,15 @@ /// Tell the object writer to emit an address-significance table during /// writeObject(). If this function is not called, all symbols are treated as /// address-significant. - virtual void emitAddrsigSection() {} + void emitAddrsigSection() { EmitAddrsigSection = true; } + + bool getEmitAddrsigSection() { return EmitAddrsigSection; } /// Record the given symbol in the address-significance table to be written /// diring writeObject(). - virtual void addAddrsigSymbol(const MCSymbol *Sym) {} + void addAddrsigSymbol(const MCSymbol *Sym) { AddrsigSyms.push_back(Sym); } + + std::vector &getAddrsigSyms() { return AddrsigSyms; } /// Write the object file and returns the number of bytes written. /// diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -221,8 +221,6 @@ DenseMap Renames; bool SeenGnuAbi = false; - bool EmitAddrsigSection = false; - std::vector AddrsigSyms; bool hasRelocationAddend() const; @@ -262,10 +260,6 @@ void markGnuAbi() override { SeenGnuAbi = true; } bool seenGnuAbi() const { return SeenGnuAbi; } - void emitAddrsigSection() override { EmitAddrsigSection = true; } - void addAddrsigSymbol(const MCSymbol *Sym) override { - AddrsigSyms.push_back(Sym); - } friend struct ELFWriter; }; diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -31,6 +31,7 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -131,6 +132,7 @@ void finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE); void finalizeCGProfile(); + void createAddrSigSection(); }; } // end anonymous namespace. @@ -529,6 +531,7 @@ finalizeCGProfile(); + createAddrSigSection(); this->MCObjectStreamer::finishImpl(); } @@ -579,3 +582,16 @@ S->getAssembler().setRelaxAll(true); return S; } + +// Create the AddrSig section and first data fragment here as its layout needs +// to be computed immediately after in order for it to be exported correctly. +void MCMachOStreamer::createAddrSigSection() { + MCAssembler &Asm = getAssembler(); + MCObjectWriter &writer = Asm.getWriter(); + if (!writer.getEmitAddrsigSection()) + return; + MCSection *AddrSigSection = + Asm.getContext().getObjectFileInfo()->getAddrSigSection(); + Asm.registerSection(*AddrSigSection); + new MCDataFragment(AddrSigSection); +} \ No newline at end of file diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -181,6 +181,9 @@ MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, SectionKind::getMetadata()); + AddrSigSection = Ctx->getMachOSection( + "__DATA", "__llvm_addrsig", MachO::S_ADDRSIG, SectionKind::getData()); + // Exception Handling. LSDASection = Ctx->getMachOSection("__TEXT", "__gcc_except_tab", 0, SectionKind::getReadOnlyWithRel()); diff --git a/llvm/lib/MC/MCSectionMachO.cpp b/llvm/lib/MC/MCSectionMachO.cpp --- a/llvm/lib/MC/MCSectionMachO.cpp +++ b/llvm/lib/MC/MCSectionMachO.cpp @@ -62,6 +62,7 @@ StringLiteral("S_THREAD_LOCAL_VARIABLE_POINTERS")}, // 0x14 {StringLiteral("thread_local_init_function_pointers"), StringLiteral("S_THREAD_LOCAL_INIT_FUNCTION_POINTERS")}, // 0x15 + {StringLiteral("addrsig"), StringLiteral("S_ADDRSIG")}, // 0x16 }; /// SectionAttrDescriptors - This is an array of descriptors for section diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCFragment.h" #include "llvm/MC/MCMachObjectWriter.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionMachO.h" @@ -29,6 +30,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include @@ -751,6 +753,24 @@ llvm_unreachable("Invalid mc version min type"); } +// Encode addrsig data as symbol indexes in variable length encoding. +void MachObjectWriter::writeAddrsigSection(MCAssembler &Asm) { + MCSection *AddrSigSection = + Asm.getContext().getObjectFileInfo()->getAddrSigSection(); + auto &fragmentList = AddrSigSection->getFragmentList(); + assert(fragmentList.size() <= 1); + + MCFragment *pFragment = &*fragmentList.begin(); + assert(pFragment); + MCDataFragment *pDataFragment = dyn_cast_or_null(pFragment); + assert(pDataFragment); + + raw_svector_ostream OS(pDataFragment->getContents()); + for (const MCSymbol *sym : this->getAddrsigSyms()) { + encodeULEB128(sym->getIndex(), OS); + } +} + uint64_t MachObjectWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) { uint64_t StartOffset = W.OS.tell(); @@ -758,6 +778,7 @@ // Compute symbol table information and bind symbol indices. computeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData, UndefinedSymbolData); + writeAddrsigSection(Asm); if (!Asm.CGProfile.empty()) { MCSection *CGProfileSection = Asm.getContext().getMachOSection( diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -154,9 +154,7 @@ bool UseBigObj; bool UseOffsetLabels = false; - bool EmitAddrsigSection = false; MCSectionCOFF *AddrsigSection; - std::vector AddrsigSyms; MCSectionCOFF *CGProfileSection = nullptr; @@ -220,11 +218,6 @@ void assignSectionNumbers(); void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout); - void emitAddrsigSection() override { EmitAddrsigSection = true; } - void addAddrsigSymbol(const MCSymbol *Sym) override { - AddrsigSyms.push_back(Sym); - } - uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; };