Index: include/lld/Core/Pass.h =================================================================== --- include/lld/Core/Pass.h +++ include/lld/Core/Pass.h @@ -18,7 +18,6 @@ #include namespace lld { -class DefinedAtom; class MutableFile; /// Once the core linking is done (which resolves references, coalesces atoms @@ -43,79 +42,6 @@ Pass() { } }; -/// Pass for adding stubs (PLT entries) for calls to functions -/// outside the linkage unit. This class is subclassed by each -/// file format Writer which implements the pure virtual methods. -class StubsPass : public Pass { -public: - StubsPass() : Pass() {} - - /// Scans all Atoms looking for call-site uses of SharedLibraryAtoms - /// and transfroms the call-site to call a stub instead using the - /// helper methods below. - void perform(std::unique_ptr &mergedFile) override; - - /// If true, the pass should use stubs for references - /// to shared library symbols. If false, the pass - /// will generate relocations on the text segment which the - /// runtime loader will use to patch the program at runtime. - virtual bool noTextRelocs() = 0; - - /// Returns whether the Reference kind is for a call site. The pass - /// uses this to find calls that need to be indirected through a stub. - virtual bool isCallSite(const Reference &) = 0; - - /// Returns a file format specific atom for a stub/PLT entry which contains - /// instructions which jump to the specified atom. May be called multiple - /// times for the same target atom, in which case this method should return - /// the same stub atom. - virtual const DefinedAtom *getStub(const Atom &target) = 0; - - /// After the default implementation of perform() is done calling getStub(), - /// it will call this method to add all the stub (and support) atoms to the - /// master file object. - virtual void addStubAtoms(MutableFile &masterFile) = 0; - -private: - void replaceCalleeWithStub(const Atom *target, const Reference *ref); -}; - -/// Pass for adding GOT entries for pointers to functions/data -/// outside the linkage unit. This class is subclassed by each -/// file format Writer which implements the pure virtual methods. -class GOTPass : public Pass { -public: - GOTPass() : Pass() {} - - /// Scans all Atoms looking for pointer to SharedLibraryAtoms - /// and transfroms them to a pointer to a GOT entry using the - /// helper methods below. - void perform(std::unique_ptr &mergedFile) override; - - /// If true, the pass will use GOT entries for references - /// to shared library symbols. If false, the pass - /// will generate relocations on the text segment which the - /// runtime loader will use to patch the program at runtime. - virtual bool noTextRelocs() = 0; - - /// Returns whether the Reference kind is a pre-instantiated GOT access. - /// The default implementation of perform() uses this to figure out - /// what GOT entries to instantiate. - virtual bool isGOTAccess(const Reference &, bool &canBypassGOT) = 0; - - /// The file format Writer needs to alter the reference kind from a - /// pre-instantiated GOT access to an actual access. If targetIsNowGOT is - /// true, the pass has instantiated a GOT atom and altered the reference's - /// target to point to that atom. If targetIsNowGOT is false, the pass - /// determined a GOT entry is not needed because the reference site can - /// directly access the target. - virtual void updateReferenceToGOT(const Reference*, bool targetIsNowGOT) = 0; - - /// Returns a file format specific atom for a GOT entry targeting - /// the specified atom. - virtual const DefinedAtom *makeGOTEntry(const Atom &target) = 0; -}; - } // namespace lld #endif // LLD_CORE_PASS_H Index: lib/Passes/CMakeLists.txt =================================================================== --- lib/Passes/CMakeLists.txt +++ lib/Passes/CMakeLists.txt @@ -1,6 +1,4 @@ add_lld_library(lldPasses - GOTPass.cpp - StubsPass.cpp LayoutPass.cpp RoundTripNativePass.cpp RoundTripYAMLPass.cpp Index: lib/ReaderWriter/CoreLinkingContext.cpp =================================================================== --- lib/ReaderWriter/CoreLinkingContext.cpp +++ lib/ReaderWriter/CoreLinkingContext.cpp @@ -184,67 +184,6 @@ }; -class TestingStubsPass : public StubsPass { -public: - TestingStubsPass(const LinkingContext &ctx) : _file(ctx) {} - - bool noTextRelocs() override { return true; } - - bool isCallSite(const Reference &ref) override { - if (ref.kindNamespace() != Reference::KindNamespace::testing) - return false; - return (ref.kindValue() == CoreLinkingContext::TEST_RELOC_CALL32); - } - - const DefinedAtom *getStub(const Atom &target) override { - const DefinedAtom *result = new TestingStubAtom(_file, target); - _file.addAtom(*result); - return result; - } - - void addStubAtoms(MutableFile &mergedFile) override { - for (const DefinedAtom *stub : _file.defined()) { - mergedFile.addAtom(*stub); - } - } - -private: - TestingPassFile _file; -}; - -class TestingGOTPass : public GOTPass { -public: - TestingGOTPass(const LinkingContext &ctx) : _file(ctx) {} - - bool noTextRelocs() override { return true; } - - bool isGOTAccess(const Reference &ref, bool &canBypassGOT) override { - if (ref.kindNamespace() != Reference::KindNamespace::testing) - return false; - switch (ref.kindValue()) { - case CoreLinkingContext::TEST_RELOC_GOT_LOAD32: - canBypassGOT = true; - return true; - case CoreLinkingContext::TEST_RELOC_GOT_USE32: - canBypassGOT = false; - return true; - } - return false; - } - - void updateReferenceToGOT(const Reference *ref, bool targetIsNowGOT) override { - const_cast(ref)->setKindValue( - targetIsNowGOT ? CoreLinkingContext::TEST_RELOC_PCREL32 - : CoreLinkingContext::TEST_RELOC_LEA32_WAS_GOT); - } - - const DefinedAtom *makeGOTEntry(const Atom &target) override { - return new TestingGOTAtom(_file, target); - } - -private: - TestingPassFile _file; -}; } // anonymous namespace @@ -259,10 +198,6 @@ for (StringRef name : _passNames) { if (name.equals("layout")) pm.add(std::unique_ptr(new LayoutPass(registry()))); - else if (name.equals("GOT")) - pm.add(std::unique_ptr(new TestingGOTPass(*this))); - else if (name.equals("stubs")) - pm.add(std::unique_ptr(new TestingStubsPass(*this))); else llvm_unreachable("bad pass name"); } Index: lib/ReaderWriter/MachO/CMakeLists.txt =================================================================== --- lib/ReaderWriter/MachO/CMakeLists.txt +++ lib/ReaderWriter/MachO/CMakeLists.txt @@ -1,4 +1,5 @@ add_lld_library(lldMachO + GOTPass.cpp MachOLinkingContext.cpp MachONormalizedFileBinaryReader.cpp MachONormalizedFileBinaryWriter.cpp @@ -6,6 +7,7 @@ MachONormalizedFileToAtoms.cpp MachONormalizedFileYAML.cpp ReferenceKinds.cpp + StubsPass.cpp WriterMachO.cpp ) Index: lib/ReaderWriter/MachO/GOTPass.hpp =================================================================== --- lib/ReaderWriter/MachO/GOTPass.hpp +++ lib/ReaderWriter/MachO/GOTPass.hpp @@ -16,6 +16,7 @@ #include "lld/Core/Reference.h" #include "lld/Core/Pass.h" +#include "MachOPasses.h" #include "ReferenceKinds.h" #include "StubAtoms.hpp" Index: lib/ReaderWriter/MachO/GOTPass.cpp =================================================================== --- lib/ReaderWriter/MachO/GOTPass.cpp +++ lib/ReaderWriter/MachO/GOTPass.cpp @@ -1,4 +1,4 @@ -//===- Passes/GOTPass.cpp - Adds GOT entries ------------------------------===// +//===- lib/ReaderWriter/MachO/GOTPass.cpp ---------------------------------===// // // The LLVM Linker // @@ -35,10 +35,11 @@ #include "lld/Core/DefinedAtom.h" #include "lld/Core/File.h" #include "lld/Core/LLVM.h" -#include "lld/Core/Pass.h" #include "lld/Core/Reference.h" #include "llvm/ADT/DenseMap.h" +#include "MachOPasses.h" + namespace lld { static bool shouldReplaceTargetWithGOTAtom(const Atom *target, Index: lib/ReaderWriter/MachO/MachOPasses.h =================================================================== --- lib/ReaderWriter/MachO/MachOPasses.h +++ lib/ReaderWriter/MachO/MachOPasses.h @@ -1,4 +1,4 @@ -//===------ Core/Pass.h - Base class for linker passes --------------------===// +//===- lib/ReaderWriter/MachO/MachOPasses.h -------------------------------===// // // The LLVM Linker // @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLD_CORE_PASS_H -#define LLD_CORE_PASS_H +#ifndef LLD_READER_WRITER_MACHO_PASSES_H +#define LLD_READER_WRITER_MACHO_PASSES_H #include "lld/Core/Atom.h" #include "lld/Core/File.h" +#include "lld/Core/Pass.h" #include "lld/Core/range.h" #include "lld/Core/Reference.h" @@ -21,27 +22,6 @@ class DefinedAtom; class MutableFile; -/// Once the core linking is done (which resolves references, coalesces atoms -/// and produces a complete Atom graph), the linker runs a series of passes -/// on the Atom graph. The graph is modeled as a File, which means the pass -/// has access to all the atoms and to File level attributes. Each pass does -/// a particular transformation to the Atom graph or to the File attributes. -/// -/// This is the abstract base class for all passes. A Pass does its -/// actual work in it perform() method. It can iterator over Atoms in the -/// graph using the *begin()/*end() atom iterator of the File. It can add -/// new Atoms to the graph using the File's addAtom() method. -class Pass { -public: - virtual ~Pass() { } - - /// Do the actual work of the Pass. - virtual void perform(std::unique_ptr &mergedFile) = 0; - -protected: - // Only subclassess can be instantiated. - Pass() { } -}; /// Pass for adding stubs (PLT entries) for calls to functions /// outside the linkage unit. This class is subclassed by each @@ -118,4 +98,4 @@ } // namespace lld -#endif // LLD_CORE_PASS_H +#endif // LLD_READER_WRITER_MACHO_PASSES_H Index: lib/ReaderWriter/MachO/StubsPass.hpp =================================================================== --- lib/ReaderWriter/MachO/StubsPass.hpp +++ lib/ReaderWriter/MachO/StubsPass.hpp @@ -19,6 +19,7 @@ #include "lld/Core/SharedLibraryAtom.h" #include "lld/Core/Simple.h" +#include "MachOPasses.h" #include "ReferenceKinds.h" #include "StubAtoms.hpp" Index: lib/ReaderWriter/MachO/StubsPass.cpp =================================================================== --- lib/ReaderWriter/MachO/StubsPass.cpp +++ lib/ReaderWriter/MachO/StubsPass.cpp @@ -1,4 +1,4 @@ -//===- Passes/StubsPass.cpp - Adds stubs ----------------------------------===// +//===- lib/ReaderWriter/MachO/StubsPass.cpp -------------------------------===// // // The LLVM Linker // @@ -17,10 +17,11 @@ #include "lld/Core/DefinedAtom.h" #include "lld/Core/File.h" #include "lld/Core/LLVM.h" -#include "lld/Core/Pass.h" #include "lld/Core/Reference.h" #include "llvm/ADT/DenseMap.h" +#include "MachOPasses.h" + namespace lld { void StubsPass::perform(std::unique_ptr &mergedFile) { Index: test/core/pass-got-basic.objtxt =================================================================== --- test/core/pass-got-basic.objtxt +++ /dev/null @@ -1,82 +0,0 @@ -# RUN: lld -core %s --add-pass GOT | FileCheck %s - -# -# Test that GOT pass instantiates GOT entires and alters references -# - ---- -defined-atoms: - - name: foo - type: code - content: [ 48, 8B, 0D, 00, 00, 00, 00, - 48, 8B, 0D, 00, 00, 00, 00, - 48, 8B, 0D, 00, 00, 00, 00, - 48, 83, 3D, 00, 00, 00, 00, 00, - 48, 83, 3D, 00, 00, 00, 00, 00, - 48, 83, 3D, 00, 00, 00, 00, 00, - 48, 83, 3D, 00, 00, 00, 00, 00 ] - references: - - offset: 3 - kind: gotLoad32 - target: malloc - - offset: 10 - kind: gotLoad32 - target: myPrivate - - offset: 17 - kind: gotLoad32 - target: myInterposable - - offset: 24 - kind: gotUse32 - target: malloc - - offset: 32 - kind: gotUse32 - target: myPrivate - - offset: 40 - kind: gotUse32 - target: myInterposable - - - name: myPrivate - scope: global - interposable: no - - - name: myInterposable - scope: global - interposable: yes - -shared-library-atoms: - - name: malloc - load-name: libc.so - -... - -# CHECK: defined-atoms: -# CHECK: name: foo -# CHECK: references: -# CHECK: kind: pcrel32 -# CHECK: offset: 3 -# CHECK: target: L -# CHECK: kind: lea32wasGot -# CHECK: offset: 10 -# CHECK: target: myPrivate -# CHECK: kind: pcrel32 -# CHECK: offset: 17 -# CHECK: target: L -# CHECK: kind: pcrel32 -# CHECK: offset: 24 -# CHECK: target: L -# CHECK: kind: pcrel32 -# CHECK: offset: 32 -# CHECK: target: L -# CHECK: kind: pcrel32 -# CHECK: offset: 40 -# CHECK: target: L -# CHECK: name: myPrivate -# CHECK: name: myInterposable -# CHECK: interposable: yes -# CHECK: name: L -# CHECK: type: got -# CHECK: type: got -# CHECK: type: got -# CHECK: shared-library-atoms: -# CHECK: name: malloc -# CHECK: ... Index: test/core/pass-stubs-basic.objtxt =================================================================== --- test/core/pass-stubs-basic.objtxt +++ /dev/null @@ -1,47 +0,0 @@ -# RUN: lld -core %s --add-pass stubs | FileCheck %s - -# -# Test that stubs pass adds stubs and rebinds call sites to the stub -# - ---- -defined-atoms: - - name: foo - type: code - content: [ E8, 00, 00, 00, 00, E8, 00, 00, 00, - 00, 48 ,8B, 05, 00, 00, 00, 00 ] - references: - - offset: 1 - kind: call32 - target: malloc - - offset: 6 - kind: call32 - target: free - - offset: 13 - kind: gotLoad32 - target: malloc - -shared-library-atoms: - - name: malloc - load-name: libc.so - - - name: free - load-name: libc.so - -... - -# CHECK: name: foo -# CHECK: references: -# CHECK: kind: call32 -# CHECK: target: L -# CHECK: kind: call32 -# CHECK: target: L -# CHECK: kind: gotLoad32 -# CHECK: target: malloc -# CHECK: name: L -# CHECK: type: stub -# CHECK: name: L -# CHECK: type: stub -# CHECK: name: malloc -# CHECK: name: free -# CHECK: ...