2020-04-03 02:54:05 +08:00
|
|
|
//===- Target.h -------------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLD_MACHO_TARGET_H
|
|
|
|
#define LLD_MACHO_TARGET_H
|
|
|
|
|
2020-05-16 04:42:28 +08:00
|
|
|
#include "llvm/BinaryFormat/MachO.h"
|
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
|
|
|
[lld-macho] Support calls to functions in dylibs
Summary:
This diff implements lazy symbol binding -- very similar to the PLT
mechanism in ELF.
ELF's .plt section is broken up into two sections in Mach-O:
StubsSection and StubHelperSection. Calls to functions in dylibs will
end up calling into StubsSection, which contains indirect jumps to
addresses stored in the LazyPointerSection (the counterpart to ELF's
.plt.got).
Initially, the LazyPointerSection contains addresses that point into one
of the entry points in the middle of the StubHelperSection. The code in
StubHelperSection will push on the stack an offset into the
LazyBindingSection. The push is followed by a jump to the beginning of
the StubHelperSection (similar to PLT0), which then calls into
dyld_stub_binder. dyld_stub_binder is a non-lazily bound symbol, so this
call looks it up in the GOT.
The stub binder will look up the bind opcodes in the LazyBindingSection
at the given offset. The bind opcodes will tell the binder to update the
address in the LazyPointerSection to point to the symbol, so that
subsequent calls don't have to redo the symbol resolution. The binder
will then jump to the resolved symbol.
Depends on D78269.
Reviewers: ruiu, pcc, MaskRay, smeenai, alexshap, gkm, Ktwu, christylee
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78270
2020-05-06 08:38:10 +08:00
|
|
|
#include <cstddef>
|
2020-04-03 02:54:05 +08:00
|
|
|
#include <cstdint>
|
|
|
|
|
|
|
|
namespace lld {
|
|
|
|
namespace macho {
|
|
|
|
|
2020-06-14 11:00:06 +08:00
|
|
|
class Symbol;
|
[lld-macho] Support calls to functions in dylibs
Summary:
This diff implements lazy symbol binding -- very similar to the PLT
mechanism in ELF.
ELF's .plt section is broken up into two sections in Mach-O:
StubsSection and StubHelperSection. Calls to functions in dylibs will
end up calling into StubsSection, which contains indirect jumps to
addresses stored in the LazyPointerSection (the counterpart to ELF's
.plt.got).
Initially, the LazyPointerSection contains addresses that point into one
of the entry points in the middle of the StubHelperSection. The code in
StubHelperSection will push on the stack an offset into the
LazyBindingSection. The push is followed by a jump to the beginning of
the StubHelperSection (similar to PLT0), which then calls into
dyld_stub_binder. dyld_stub_binder is a non-lazily bound symbol, so this
call looks it up in the GOT.
The stub binder will look up the bind opcodes in the LazyBindingSection
at the given offset. The bind opcodes will tell the binder to update the
address in the LazyPointerSection to point to the symbol, so that
subsequent calls don't have to redo the symbol resolution. The binder
will then jump to the resolved symbol.
Depends on D78269.
Reviewers: ruiu, pcc, MaskRay, smeenai, alexshap, gkm, Ktwu, christylee
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78270
2020-05-06 08:38:10 +08:00
|
|
|
class DylibSymbol;
|
2020-05-16 04:42:28 +08:00
|
|
|
class InputSection;
|
|
|
|
struct Reloc;
|
[lld-macho] Support calls to functions in dylibs
Summary:
This diff implements lazy symbol binding -- very similar to the PLT
mechanism in ELF.
ELF's .plt section is broken up into two sections in Mach-O:
StubsSection and StubHelperSection. Calls to functions in dylibs will
end up calling into StubsSection, which contains indirect jumps to
addresses stored in the LazyPointerSection (the counterpart to ELF's
.plt.got).
Initially, the LazyPointerSection contains addresses that point into one
of the entry points in the middle of the StubHelperSection. The code in
StubHelperSection will push on the stack an offset into the
LazyBindingSection. The push is followed by a jump to the beginning of
the StubHelperSection (similar to PLT0), which then calls into
dyld_stub_binder. dyld_stub_binder is a non-lazily bound symbol, so this
call looks it up in the GOT.
The stub binder will look up the bind opcodes in the LazyBindingSection
at the given offset. The bind opcodes will tell the binder to update the
address in the LazyPointerSection to point to the symbol, so that
subsequent calls don't have to redo the symbol resolution. The binder
will then jump to the resolved symbol.
Depends on D78269.
Reviewers: ruiu, pcc, MaskRay, smeenai, alexshap, gkm, Ktwu, christylee
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78270
2020-05-06 08:38:10 +08:00
|
|
|
|
2020-06-03 06:22:45 +08:00
|
|
|
enum : uint64_t {
|
2020-04-22 04:37:57 +08:00
|
|
|
// We are currently only supporting 64-bit targets since macOS and iOS are
|
|
|
|
// deprecating 32-bit apps.
|
|
|
|
WordSize = 8,
|
2020-04-03 02:54:05 +08:00
|
|
|
PageSize = 4096,
|
2020-05-19 11:28:50 +08:00
|
|
|
PageZeroSize = 1ull << 32, // XXX should be 4096 for 32-bit targets
|
2020-04-03 02:54:05 +08:00
|
|
|
MaxAlignmentPowerOf2 = 32,
|
|
|
|
};
|
|
|
|
|
|
|
|
class TargetInfo {
|
|
|
|
public:
|
|
|
|
virtual ~TargetInfo() = default;
|
2020-05-19 23:53:53 +08:00
|
|
|
|
2020-05-16 04:42:28 +08:00
|
|
|
// Validate the relocation structure and get its addend.
|
|
|
|
virtual uint64_t
|
|
|
|
getImplicitAddend(llvm::MemoryBufferRef, const llvm::MachO::section_64 &,
|
|
|
|
const llvm::MachO::relocation_info &) const = 0;
|
2020-06-14 10:52:20 +08:00
|
|
|
virtual void relocateOne(uint8_t *loc, const Reloc &, uint64_t val) const = 0;
|
2020-04-03 02:54:05 +08:00
|
|
|
|
[lld-macho] Support calls to functions in dylibs
Summary:
This diff implements lazy symbol binding -- very similar to the PLT
mechanism in ELF.
ELF's .plt section is broken up into two sections in Mach-O:
StubsSection and StubHelperSection. Calls to functions in dylibs will
end up calling into StubsSection, which contains indirect jumps to
addresses stored in the LazyPointerSection (the counterpart to ELF's
.plt.got).
Initially, the LazyPointerSection contains addresses that point into one
of the entry points in the middle of the StubHelperSection. The code in
StubHelperSection will push on the stack an offset into the
LazyBindingSection. The push is followed by a jump to the beginning of
the StubHelperSection (similar to PLT0), which then calls into
dyld_stub_binder. dyld_stub_binder is a non-lazily bound symbol, so this
call looks it up in the GOT.
The stub binder will look up the bind opcodes in the LazyBindingSection
at the given offset. The bind opcodes will tell the binder to update the
address in the LazyPointerSection to point to the symbol, so that
subsequent calls don't have to redo the symbol resolution. The binder
will then jump to the resolved symbol.
Depends on D78269.
Reviewers: ruiu, pcc, MaskRay, smeenai, alexshap, gkm, Ktwu, christylee
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78270
2020-05-06 08:38:10 +08:00
|
|
|
// Write code for lazy binding. See the comments on StubsSection for more
|
|
|
|
// details.
|
|
|
|
virtual void writeStub(uint8_t *buf, const DylibSymbol &) const = 0;
|
|
|
|
virtual void writeStubHelperHeader(uint8_t *buf) const = 0;
|
|
|
|
virtual void writeStubHelperEntry(uint8_t *buf, const DylibSymbol &,
|
|
|
|
uint64_t entryAddr) const = 0;
|
|
|
|
|
2020-06-14 11:00:06 +08:00
|
|
|
// Symbols may be referenced via either the GOT or the stubs section,
|
|
|
|
// depending on the relocation type. prepareSymbolRelocation() will set up the
|
|
|
|
// GOT/stubs entries, and getSymbolVA() will return the addresses of those
|
|
|
|
// entries.
|
2020-07-03 12:19:55 +08:00
|
|
|
virtual void prepareSymbolRelocation(Symbol &, const InputSection *,
|
|
|
|
const Reloc &) = 0;
|
2020-06-14 11:00:06 +08:00
|
|
|
virtual uint64_t getSymbolVA(const Symbol &, uint8_t type) const = 0;
|
[lld-macho] Support calls to functions in dylibs
Summary:
This diff implements lazy symbol binding -- very similar to the PLT
mechanism in ELF.
ELF's .plt section is broken up into two sections in Mach-O:
StubsSection and StubHelperSection. Calls to functions in dylibs will
end up calling into StubsSection, which contains indirect jumps to
addresses stored in the LazyPointerSection (the counterpart to ELF's
.plt.got).
Initially, the LazyPointerSection contains addresses that point into one
of the entry points in the middle of the StubHelperSection. The code in
StubHelperSection will push on the stack an offset into the
LazyBindingSection. The push is followed by a jump to the beginning of
the StubHelperSection (similar to PLT0), which then calls into
dyld_stub_binder. dyld_stub_binder is a non-lazily bound symbol, so this
call looks it up in the GOT.
The stub binder will look up the bind opcodes in the LazyBindingSection
at the given offset. The bind opcodes will tell the binder to update the
address in the LazyPointerSection to point to the symbol, so that
subsequent calls don't have to redo the symbol resolution. The binder
will then jump to the resolved symbol.
Depends on D78269.
Reviewers: ruiu, pcc, MaskRay, smeenai, alexshap, gkm, Ktwu, christylee
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78270
2020-05-06 08:38:10 +08:00
|
|
|
|
2020-04-03 02:54:05 +08:00
|
|
|
uint32_t cpuType;
|
|
|
|
uint32_t cpuSubtype;
|
[lld-macho] Support calls to functions in dylibs
Summary:
This diff implements lazy symbol binding -- very similar to the PLT
mechanism in ELF.
ELF's .plt section is broken up into two sections in Mach-O:
StubsSection and StubHelperSection. Calls to functions in dylibs will
end up calling into StubsSection, which contains indirect jumps to
addresses stored in the LazyPointerSection (the counterpart to ELF's
.plt.got).
Initially, the LazyPointerSection contains addresses that point into one
of the entry points in the middle of the StubHelperSection. The code in
StubHelperSection will push on the stack an offset into the
LazyBindingSection. The push is followed by a jump to the beginning of
the StubHelperSection (similar to PLT0), which then calls into
dyld_stub_binder. dyld_stub_binder is a non-lazily bound symbol, so this
call looks it up in the GOT.
The stub binder will look up the bind opcodes in the LazyBindingSection
at the given offset. The bind opcodes will tell the binder to update the
address in the LazyPointerSection to point to the symbol, so that
subsequent calls don't have to redo the symbol resolution. The binder
will then jump to the resolved symbol.
Depends on D78269.
Reviewers: ruiu, pcc, MaskRay, smeenai, alexshap, gkm, Ktwu, christylee
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78270
2020-05-06 08:38:10 +08:00
|
|
|
|
|
|
|
size_t stubSize;
|
|
|
|
size_t stubHelperHeaderSize;
|
|
|
|
size_t stubHelperEntrySize;
|
2020-04-03 02:54:05 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
TargetInfo *createX86_64TargetInfo();
|
|
|
|
|
|
|
|
extern TargetInfo *target;
|
|
|
|
|
|
|
|
} // namespace macho
|
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|