//===- EhFrame.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 "EhFrame.h"
#include "InputFiles.h"

#include "lld/Common/ErrorHandler.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Endian.h"

using namespace llvm;
using namespace lld;
using namespace lld::macho;
using namespace llvm::support::endian;

uint64_t EhReader::readLength(size_t *off) const {
  const size_t errOff = *off;
  if (*off + 4 > data.size())
    failOn(errOff, "CIE/FDE too small");
  uint64_t len = read32le(data.data() + *off);
  *off += 4;
  if (len == dwarf::DW_LENGTH_DWARF64) {
    // FIXME: test this DWARF64 code path
    if (*off + 8 > data.size())
      failOn(errOff, "CIE/FDE too small");
    len = read64le(data.data() + *off);
    *off += 8;
  }
  if (*off + len > data.size())
    failOn(errOff, "CIE/FDE extends past the end of the section");
  return len;
}

void EhReader::skipValidLength(size_t *off) const {
  uint32_t len = read32le(data.data() + *off);
  *off += 4;
  if (len == dwarf::DW_LENGTH_DWARF64)
    *off += 8;
}

// Read a byte and advance off by one byte.
uint8_t EhReader::readByte(size_t *off) const {
  if (*off + 1 > data.size())
    failOn(*off, "unexpected end of CIE/FDE");
  return data[(*off)++];
}

uint32_t EhReader::readU32(size_t *off) const {
  if (*off + 4 > data.size())
    failOn(*off, "unexpected end of CIE/FDE");
  uint32_t v = read32le(data.data() + *off);
  *off += 4;
  return v;
}

uint64_t EhReader::readPointer(size_t *off, uint8_t size) const {
  if (*off + size > data.size())
    failOn(*off, "unexpected end of CIE/FDE");
  uint64_t v;
  if (size == 8)
    v = read64le(data.data() + *off);
  else {
    assert(size == 4);
    v = read32le(data.data() + *off);
  }
  *off += size;
  return v;
}

// Read a null-terminated string.
StringRef EhReader::readString(size_t *off) const {
  if (*off > data.size())
    failOn(*off, "corrupted CIE (failed to read string)");
  const size_t maxlen = data.size() - *off;
  auto *c = reinterpret_cast<const char *>(data.data() + *off);
  size_t len = strnlen(c, maxlen);
  if (len == maxlen) // we failed to find the null terminator
    failOn(*off, "corrupted CIE (failed to read string)");
  *off += len + 1; // skip the null byte too
  return StringRef(c, len);
}

void EhReader::skipLeb128(size_t *off) const {
  const size_t errOff = *off;
  while (*off < data.size()) {
    uint8_t val = data[(*off)++];
    if ((val & 0x80) == 0)
      return;
  }
  failOn(errOff, "corrupted CIE (failed to read LEB128)");
}

void EhReader::failOn(size_t errOff, const Twine &msg) const {
  fatal(toString(file) + ":(__eh_frame+0x" +
        Twine::utohexstr(dataOff + errOff) + "): " + msg);
}

/*
 * Create a pair of relocs to write the value of:
 *   `b - (offset + a)` if Invert == false
 *   `(a + offset) - b` if Invert == true
 */
template <bool Invert = false>
static void createSubtraction(PointerUnion<Symbol *, InputSection *> a,
                              PointerUnion<Symbol *, InputSection *> b,
                              uint64_t off, uint8_t length,
                              SmallVectorImpl<Relocation> *newRelocs) {
  auto subtrahend = a;
  auto minuend = b;
  if (Invert)
    std::swap(subtrahend, minuend);
  assert(isa<Symbol *>(subtrahend));
  Relocation subtrahendReloc(target->subtractorRelocType, /*pcrel=*/false,
                             length, off, /*addend=*/0, subtrahend);
  Relocation minuendReloc(target->unsignedRelocType, /*pcrel=*/false, length,
                          off, (Invert ? 1 : -1) * off, minuend);
  newRelocs->push_back(subtrahendReloc);
  newRelocs->push_back(minuendReloc);
}

void EhRelocator::makePcRel(uint64_t off,
                            PointerUnion<Symbol *, InputSection *> target,
                            uint8_t length) {
  createSubtraction(isec->symbols[0], target, off, length, &newRelocs);
}

void EhRelocator::makeNegativePcRel(
    uint64_t off, PointerUnion<Symbol *, InputSection *> target,
    uint8_t length) {
  createSubtraction</*Invert=*/true>(isec, target, off, length, &newRelocs);
}

void EhRelocator::commit() {
  isec->relocs.insert(isec->relocs.end(), newRelocs.begin(), newRelocs.end());
}
