llvm/lld/ELF/Arch/ARM.cpp

//===- ARM.cpp ------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "InputFiles.h"
#include "OutputSections.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Filesystem.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Endian.h"

usingnamespacellvm;
usingnamespacellvm::support::endian;
usingnamespacellvm::support;
usingnamespacellvm::ELF;
usingnamespacelld;
usingnamespacelld::elf;
usingnamespacellvm::object;

namespace {
class ARM final : public TargetInfo {};
enum class CodeState {};
} // namespace

static DenseMap<InputSection *, SmallVector<const Defined *, 0>> sectionMap{};

ARM::ARM() {}

uint32_t ARM::calcEFlags() const {}

RelExpr ARM::getRelExpr(RelType type, const Symbol &s,
                        const uint8_t *loc) const {}

RelType ARM::getDynRel(RelType type) const {}

void ARM::writeGotPlt(uint8_t *buf, const Symbol &) const {}

void ARM::writeIgotPlt(uint8_t *buf, const Symbol &s) const {}

// Long form PLT Header that does not have any restrictions on the displacement
// of the .plt from the .got.plt.
static void writePltHeaderLong(uint8_t *buf) {}

// True if we should use Thumb PLTs, which currently require Thumb2, and are
// only used if the target does not have the ARM ISA.
static bool useThumbPLTs() {}

// The default PLT header requires the .got.plt to be within 128 Mb of the
// .plt in the positive direction.
void ARM::writePltHeader(uint8_t *buf) const {}

void ARM::addPltHeaderSymbols(InputSection &isec) const {}

// Long form PLT entries that do not have any restrictions on the displacement
// of the .plt from the .got.plt.
static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr,
                         uint64_t pltEntryAddr) {}

// The default PLT entries require the .got.plt to be within 128 Mb of the
// .plt in the positive direction.
void ARM::writePlt(uint8_t *buf, const Symbol &sym,
                   uint64_t pltEntryAddr) const {}

void ARM::addPltSymbols(InputSection &isec, uint64_t off) const {}

bool ARM::needsThunk(RelExpr expr, RelType type, const InputFile *file,
                     uint64_t branchAddr, const Symbol &s,
                     int64_t a) const {}

uint32_t ARM::getThunkSectionSpacing() const {}

bool ARM::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {}

// Helper to produce message text when LLD detects that a CALL relocation to
// a non STT_FUNC symbol that may result in incorrect interworking between ARM
// or Thumb.
static void stateChangeWarning(uint8_t *loc, RelType relt, const Symbol &s) {}

// Rotate a 32-bit unsigned value right by a specified amt of bits.
static uint32_t rotr32(uint32_t val, uint32_t amt) {}

static std::pair<uint32_t, uint32_t> getRemAndLZForGroup(unsigned group,
                                                         uint32_t val) {}

static void encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
                           int group, bool check) {}

static void encodeLdrGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
                           int group) {}

static void encodeLdrsGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
                            int group) {}

void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {}

int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {}

static bool isArmMapSymbol(const Symbol *b) {}

static bool isThumbMapSymbol(const Symbol *s) {}

static bool isDataMapSymbol(const Symbol *b) {}

void elf::sortArmMappingSymbols() {}

void elf::addArmInputSectionMappingSymbols() {}

// Synthetic sections are not backed by an ELF file where we can access the
// symbol table, instead mapping symbols added to synthetic sections are stored
// in the synthetic symbol table. Due to the presence of strip (--strip-all),
// we can not rely on the synthetic symbol table retaining the mapping symbols.
// Instead we record the mapping symbols locally.
void elf::addArmSyntheticSectionMappingSymbol(Defined *sym) {}

static void toLittleEndianInstructions(uint8_t *buf, uint64_t start,
                                       uint64_t end, uint64_t width) {}

// Arm BE8 big endian format requires instructions to be little endian, with
// the initial contents big-endian. Convert the big-endian instructions to
// little endian leaving literal data untouched. We use mapping symbols to
// identify half open intervals of Arm code [$a, non $a) and Thumb code
// [$t, non $t) and convert these to little endian a word or half word at a
// time respectively.
void elf::convertArmInstructionstoBE8(InputSection *sec, uint8_t *buf) {}

// The Arm Cortex-M Security Extensions (CMSE) splits a system into two parts;
// the non-secure and secure states with the secure state inaccessible from the
// non-secure state, apart from an area of memory in secure state called the
// secure gateway which is accessible from non-secure state. The secure gateway
// contains one or more entry points which must start with a landing pad
// instruction SG. Arm recommends that the secure gateway consists only of
// secure gateway veneers, which are made up of a SG instruction followed by a
// branch to the destination in secure state. Full details can be found in Arm
// v8-M Security Extensions Requirements on Development Tools.
//
// The CMSE model of software development requires the non-secure and secure
// states to be developed as two separate programs. The non-secure developer is
// provided with an import library defining symbols describing the entry points
// in the secure gateway. No additional linker support is required for the
// non-secure state.
//
// Development of the secure state requires linker support to manage the secure
// gateway veneers. The management consists of:
// - Creation of new secure gateway veneers based on symbol conventions.
// - Checking the address of existing secure gateway veneers.
// - Warning when existing secure gateway veneers removed.
//
// The secure gateway veneers are created in an import library, which is just an
// ELF object with a symbol table. The import library is controlled by two
// command line options:
// --in-implib (specify an input import library from a previous revision of the
// program).
// --out-implib (specify an output import library to be created by the linker).
//
// The input import library is used to manage consistency of the secure entry
// points. The output import library is for new and updated secure entry points.
//
// The symbol convention that identifies secure entry functions is the prefix
// __acle_se_ for a symbol called name the linker is expected to create a secure
// gateway veneer if symbols __acle_se_name and name have the same address.
// After creating a secure gateway veneer the symbol name labels the secure
// gateway veneer and the __acle_se_name labels the function definition.
//
// The LLD implementation:
// - Reads an existing import library with importCmseSymbols().
// - Determines which new secure gateway veneers to create and redirects calls
//   within the secure state to the __acle_se_ prefixed symbol with
//   processArmCmseSymbols().
// - Models the SG veneers as a synthetic section.

// Initialize symbols. symbols is a parallel array to the corresponding ELF
// symbol table.
template <class ELFT> void ObjFile<ELFT>::importCmseSymbols() {}

// Check symbol attributes of the acleSeSym, sym pair.
// Both symbols should be global/weak Thumb code symbol definitions.
static std::string checkCmseSymAttributes(Symbol *acleSeSym, Symbol *sym) {}

// Look for [__acle_se_<sym>, <sym>] pairs, as specified in the Cortex-M
// Security Extensions specification.
// 1) <sym> : A standard function name.
// 2) __acle_se_<sym> : A special symbol that prefixes the standard function
// name with __acle_se_.
// Both these symbols are Thumb function symbols with external linkage.
// <sym> may be redefined in .gnu.sgstubs.
void elf::processArmCmseSymbols() {}

class elf::ArmCmseSGVeneer {};

ArmCmseSGSection::ArmCmseSGSection()
    :{}

void ArmCmseSGSection::addSGVeneer(Symbol *acleSeSym, Symbol *sym) {}

void ArmCmseSGSection::writeTo(uint8_t *buf) {}

void ArmCmseSGSection::addMappingSymbol() {}

size_t ArmCmseSGSection::getSize() const {}

void ArmCmseSGSection::finalizeContents() {}

// Write the CMSE import library to disk.
// The CMSE import library is a relocatable object with only a symbol table.
// The symbols are copies of the (absolute) symbols of the secure gateways
// in the executable output by this link.
// See Arm® v8-M Security Extensions: Requirements on Development Tools
// https://developer.arm.com/documentation/ecm0359818/latest
template <typename ELFT> void elf::writeARMCmseImportLib() {}

TargetInfo *elf::getARMTargetInfo() {}

template void elf::writeARMCmseImportLib<ELF32LE>();
template void elf::writeARMCmseImportLib<ELF32BE>();
template void elf::writeARMCmseImportLib<ELF64LE>();
template void elf::writeARMCmseImportLib<ELF64BE>();

template void ObjFile<ELF32LE>::importCmseSymbols();
template void ObjFile<ELF32BE>::importCmseSymbols();
template void ObjFile<ELF64LE>::importCmseSymbols();
template void ObjFile<ELF64BE>::importCmseSymbols();