brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · bb74f6a Raw
86 lines · cpp
1//===-- BPFELFObjectWriter.cpp - BPF ELF Writer ---------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "MCTargetDesc/BPFMCTargetDesc.h"10#include "llvm/BinaryFormat/ELF.h"11#include "llvm/MC/MCELFObjectWriter.h"12#include "llvm/MC/MCFixup.h"13#include "llvm/MC/MCObjectWriter.h"14#include "llvm/MC/MCValue.h"15#include "llvm/Support/ErrorHandling.h"16#include <cstdint>17 18using namespace llvm;19 20namespace {21 22class BPFELFObjectWriter : public MCELFObjectTargetWriter {23public:24  BPFELFObjectWriter(uint8_t OSABI);25  ~BPFELFObjectWriter() override = default;26 27protected:28  unsigned getRelocType(const MCFixup &, const MCValue &,29                        bool IsPCRel) const override;30};31 32} // end anonymous namespace33 34BPFELFObjectWriter::BPFELFObjectWriter(uint8_t OSABI)35    : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_BPF,36                              /*HasRelocationAddend*/ false) {}37 38unsigned BPFELFObjectWriter::getRelocType(const MCFixup &Fixup,39                                          const MCValue &Target,40                                          bool IsPCRel) const {41  // determine the type of the relocation42  switch (Fixup.getKind()) {43  default:44    llvm_unreachable("invalid fixup kind!");45  case FK_SecRel_8:46    // LD_imm64 instruction.47    return ELF::R_BPF_64_64;48  case FK_Data_8:49    return ELF::R_BPF_64_ABS64;50  case FK_Data_4:51    if (Fixup.isPCRel()) // CALL instruction52      return ELF::R_BPF_64_32;53    if (const auto *A = Target.getAddSym()) {54      const MCSymbol &Sym = *A;55 56      if (Sym.isDefined()) {57        auto &Section = static_cast<const MCSectionELF &>(Sym.getSection());58        unsigned Flags = Section.getFlags();59 60        if (Sym.isTemporary()) {61          // .BTF.ext generates FK_Data_4 relocations for62          // insn offset by creating temporary labels.63          // The reloc symbol should be in text section.64          // Use a different relocation to instruct ExecutionEngine65          // RuntimeDyld not to do relocation for it, yet still to66          // allow lld to do proper adjustment when merging sections.67          if ((Flags & ELF::SHF_ALLOC) && (Flags & ELF::SHF_EXECINSTR))68            return ELF::R_BPF_64_NODYLD32;69        } else {70          // .BTF generates FK_Data_4 relocations for variable71          // offset in DataSec kind.72          // The reloc symbol should be in data section.73          if ((Flags & ELF::SHF_ALLOC) && (Flags & ELF::SHF_WRITE))74            return ELF::R_BPF_64_NODYLD32;75        }76      }77    }78    return ELF::R_BPF_64_ABS32;79  }80}81 82std::unique_ptr<MCObjectTargetWriter>83llvm::createBPFELFObjectWriter(uint8_t OSABI) {84  return std::make_unique<BPFELFObjectWriter>(OSABI);85}86