Move GOTPass and StubsPass from Core to MachO
llvm-svn: 212652
This commit is contained in:
parent
79d4ffbc8f
commit
0edfdeb0be
|
@ -18,7 +18,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
class DefinedAtom;
|
|
||||||
class MutableFile;
|
class MutableFile;
|
||||||
|
|
||||||
/// Once the core linking is done (which resolves references, coalesces atoms
|
/// Once the core linking is done (which resolves references, coalesces atoms
|
||||||
|
@ -43,79 +42,6 @@ protected:
|
||||||
Pass() { }
|
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<MutableFile> &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<MutableFile> &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
|
} // namespace lld
|
||||||
|
|
||||||
#endif // LLD_CORE_PASS_H
|
#endif // LLD_CORE_PASS_H
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
add_lld_library(lldPasses
|
add_lld_library(lldPasses
|
||||||
GOTPass.cpp
|
|
||||||
StubsPass.cpp
|
|
||||||
LayoutPass.cpp
|
LayoutPass.cpp
|
||||||
RoundTripNativePass.cpp
|
RoundTripNativePass.cpp
|
||||||
RoundTripYAMLPass.cpp
|
RoundTripYAMLPass.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<Reference *>(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
|
} // anonymous namespace
|
||||||
|
|
||||||
|
@ -259,10 +198,6 @@ void CoreLinkingContext::addPasses(PassManager &pm) {
|
||||||
for (StringRef name : _passNames) {
|
for (StringRef name : _passNames) {
|
||||||
if (name.equals("layout"))
|
if (name.equals("layout"))
|
||||||
pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
|
pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
|
||||||
else if (name.equals("GOT"))
|
|
||||||
pm.add(std::unique_ptr<Pass>(new TestingGOTPass(*this)));
|
|
||||||
else if (name.equals("stubs"))
|
|
||||||
pm.add(std::unique_ptr<Pass>(new TestingStubsPass(*this)));
|
|
||||||
else
|
else
|
||||||
llvm_unreachable("bad pass name");
|
llvm_unreachable("bad pass name");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
add_lld_library(lldMachO
|
add_lld_library(lldMachO
|
||||||
|
GOTPass.cpp
|
||||||
MachOLinkingContext.cpp
|
MachOLinkingContext.cpp
|
||||||
MachONormalizedFileBinaryReader.cpp
|
MachONormalizedFileBinaryReader.cpp
|
||||||
MachONormalizedFileBinaryWriter.cpp
|
MachONormalizedFileBinaryWriter.cpp
|
||||||
|
@ -6,6 +7,7 @@ add_lld_library(lldMachO
|
||||||
MachONormalizedFileToAtoms.cpp
|
MachONormalizedFileToAtoms.cpp
|
||||||
MachONormalizedFileYAML.cpp
|
MachONormalizedFileYAML.cpp
|
||||||
ReferenceKinds.cpp
|
ReferenceKinds.cpp
|
||||||
|
StubsPass.cpp
|
||||||
WriterMachO.cpp
|
WriterMachO.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//===- Passes/GOTPass.cpp - Adds GOT entries ------------------------------===//
|
//===- lib/ReaderWriter/MachO/GOTPass.cpp ---------------------------------===//
|
||||||
//
|
//
|
||||||
// The LLVM Linker
|
// The LLVM Linker
|
||||||
//
|
//
|
||||||
|
@ -35,10 +35,11 @@
|
||||||
#include "lld/Core/DefinedAtom.h"
|
#include "lld/Core/DefinedAtom.h"
|
||||||
#include "lld/Core/File.h"
|
#include "lld/Core/File.h"
|
||||||
#include "lld/Core/LLVM.h"
|
#include "lld/Core/LLVM.h"
|
||||||
#include "lld/Core/Pass.h"
|
|
||||||
#include "lld/Core/Reference.h"
|
#include "lld/Core/Reference.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
|
||||||
|
#include "MachOPasses.h"
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
|
|
||||||
static bool shouldReplaceTargetWithGOTAtom(const Atom *target,
|
static bool shouldReplaceTargetWithGOTAtom(const Atom *target,
|
|
@ -16,6 +16,7 @@
|
||||||
#include "lld/Core/Reference.h"
|
#include "lld/Core/Reference.h"
|
||||||
#include "lld/Core/Pass.h"
|
#include "lld/Core/Pass.h"
|
||||||
|
|
||||||
|
#include "MachOPasses.h"
|
||||||
#include "ReferenceKinds.h"
|
#include "ReferenceKinds.h"
|
||||||
#include "StubAtoms.hpp"
|
#include "StubAtoms.hpp"
|
||||||
|
|
||||||
|
|
|
@ -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 <vector>
|
||||||
|
|
||||||
|
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<MutableFile> &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<MutableFile> &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
|
|
@ -1,4 +1,4 @@
|
||||||
//===- Passes/StubsPass.cpp - Adds stubs ----------------------------------===//
|
//===- lib/ReaderWriter/MachO/StubsPass.cpp -------------------------------===//
|
||||||
//
|
//
|
||||||
// The LLVM Linker
|
// The LLVM Linker
|
||||||
//
|
//
|
||||||
|
@ -17,10 +17,11 @@
|
||||||
#include "lld/Core/DefinedAtom.h"
|
#include "lld/Core/DefinedAtom.h"
|
||||||
#include "lld/Core/File.h"
|
#include "lld/Core/File.h"
|
||||||
#include "lld/Core/LLVM.h"
|
#include "lld/Core/LLVM.h"
|
||||||
#include "lld/Core/Pass.h"
|
|
||||||
#include "lld/Core/Reference.h"
|
#include "lld/Core/Reference.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
|
||||||
|
#include "MachOPasses.h"
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
|
|
||||||
void StubsPass::perform(std::unique_ptr<MutableFile> &mergedFile) {
|
void StubsPass::perform(std::unique_ptr<MutableFile> &mergedFile) {
|
|
@ -19,6 +19,7 @@
|
||||||
#include "lld/Core/SharedLibraryAtom.h"
|
#include "lld/Core/SharedLibraryAtom.h"
|
||||||
#include "lld/Core/Simple.h"
|
#include "lld/Core/Simple.h"
|
||||||
|
|
||||||
|
#include "MachOPasses.h"
|
||||||
#include "ReferenceKinds.h"
|
#include "ReferenceKinds.h"
|
||||||
#include "StubAtoms.hpp"
|
#include "StubAtoms.hpp"
|
||||||
|
|
||||||
|
|
|
@ -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: ...
|
|
|
@ -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: ...
|
|
Loading…
Reference in New Issue