From 0edfdeb0be83dc9fac8d11c51fc59eb1ab73512e Mon Sep 17 00:00:00 2001 From: Nick Kledzik Date: Wed, 9 Jul 2014 21:04:24 +0000 Subject: [PATCH] Move GOTPass and StubsPass from Core to MachO llvm-svn: 212652 --- lld/include/lld/Core/Pass.h | 74 --------------- lld/lib/Passes/CMakeLists.txt | 2 - lld/lib/ReaderWriter/CoreLinkingContext.cpp | 65 ------------- lld/lib/ReaderWriter/MachO/CMakeLists.txt | 2 + lld/lib/{Passes => ReaderWriter/MachO}/GOTPass.cpp | 5 +- lld/lib/ReaderWriter/MachO/GOTPass.hpp | 1 + lld/lib/ReaderWriter/MachO/MachOPasses.h | 101 +++++++++++++++++++++ .../{Passes => ReaderWriter/MachO}/StubsPass.cpp | 5 +- lld/lib/ReaderWriter/MachO/StubsPass.hpp | 1 + lld/test/core/pass-got-basic.objtxt | 82 ----------------- lld/test/core/pass-stubs-basic.objtxt | 47 ---------- 11 files changed, 111 insertions(+), 274 deletions(-) rename lld/lib/{Passes => ReaderWriter/MachO}/GOTPass.cpp (97%) create mode 100644 lld/lib/ReaderWriter/MachO/MachOPasses.h rename lld/lib/{Passes => ReaderWriter/MachO}/StubsPass.cpp (96%) delete mode 100644 lld/test/core/pass-got-basic.objtxt delete mode 100644 lld/test/core/pass-stubs-basic.objtxt diff --git a/lld/include/lld/Core/Pass.h b/lld/include/lld/Core/Pass.h index 97f1f52..f894dd8 100644 --- a/lld/include/lld/Core/Pass.h +++ b/lld/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 @@ protected: 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 diff --git a/lld/lib/Passes/CMakeLists.txt b/lld/lib/Passes/CMakeLists.txt index 6f297fb..0c0876b 100644 --- a/lld/lib/Passes/CMakeLists.txt +++ b/lld/lib/Passes/CMakeLists.txt @@ -1,6 +1,4 @@ add_lld_library(lldPasses - GOTPass.cpp - StubsPass.cpp LayoutPass.cpp RoundTripNativePass.cpp RoundTripYAMLPass.cpp diff --git a/lld/lib/ReaderWriter/CoreLinkingContext.cpp b/lld/lib/ReaderWriter/CoreLinkingContext.cpp index 0adaa01..9fd97ed 100644 --- a/lld/lib/ReaderWriter/CoreLinkingContext.cpp +++ b/lld/lib/ReaderWriter/CoreLinkingContext.cpp @@ -184,67 +184,6 @@ private: }; -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 @@ void CoreLinkingContext::addPasses(PassManager &pm) { 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"); } diff --git a/lld/lib/ReaderWriter/MachO/CMakeLists.txt b/lld/lib/ReaderWriter/MachO/CMakeLists.txt index 0b9b135..51a1f20 100644 --- a/lld/lib/ReaderWriter/MachO/CMakeLists.txt +++ b/lld/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 @@ add_lld_library(lldMachO MachONormalizedFileToAtoms.cpp MachONormalizedFileYAML.cpp ReferenceKinds.cpp + StubsPass.cpp WriterMachO.cpp ) diff --git a/lld/lib/Passes/GOTPass.cpp b/lld/lib/ReaderWriter/MachO/GOTPass.cpp similarity index 97% rename from lld/lib/Passes/GOTPass.cpp rename to lld/lib/ReaderWriter/MachO/GOTPass.cpp index 4729ca1..1d5c6ee 100644 --- a/lld/lib/Passes/GOTPass.cpp +++ b/lld/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, diff --git a/lld/lib/ReaderWriter/MachO/GOTPass.hpp b/lld/lib/ReaderWriter/MachO/GOTPass.hpp index f66d6a7..a7ab254 100644 --- a/lld/lib/ReaderWriter/MachO/GOTPass.hpp +++ b/lld/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" diff --git a/lld/lib/ReaderWriter/MachO/MachOPasses.h b/lld/lib/ReaderWriter/MachO/MachOPasses.h new file mode 100644 index 0000000..d55fdf5 --- /dev/null +++ b/lld/lib/ReaderWriter/MachO/MachOPasses.h @@ -0,0 +1,101 @@ +//===- lib/ReaderWriter/MachO/MachOPasses.h -------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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" + +#include + +namespace lld { +class DefinedAtom; +class MutableFile; + + +/// 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_READER_WRITER_MACHO_PASSES_H diff --git a/lld/lib/Passes/StubsPass.cpp b/lld/lib/ReaderWriter/MachO/StubsPass.cpp similarity index 96% rename from lld/lib/Passes/StubsPass.cpp rename to lld/lib/ReaderWriter/MachO/StubsPass.cpp index e388949..630e00b 100644 --- a/lld/lib/Passes/StubsPass.cpp +++ b/lld/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) { diff --git a/lld/lib/ReaderWriter/MachO/StubsPass.hpp b/lld/lib/ReaderWriter/MachO/StubsPass.hpp index 8dac613..0e70589 100644 --- a/lld/lib/ReaderWriter/MachO/StubsPass.hpp +++ b/lld/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" diff --git a/lld/test/core/pass-got-basic.objtxt b/lld/test/core/pass-got-basic.objtxt deleted file mode 100644 index 4b66f70..0000000 --- a/lld/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: ... diff --git a/lld/test/core/pass-stubs-basic.objtxt b/lld/test/core/pass-stubs-basic.objtxt deleted file mode 100644 index bcc1ca3..0000000 --- a/lld/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: ... -- 2.7.4