//===- InputSection.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 "InputSection.h"
#include "ConcatOutputSection.h"
#include "Config.h"
#include "InputFiles.h"
#include "OutputSegment.h"
#include "Sections.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Writer.h"

#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "llvm/Support/xxhash.h"

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

// Verify ConcatInputSection's size on 64-bit builds. The size of std::vector
// can differ based on STL debug levels (e.g. iterator debugging on MSVC's STL),
// so account for that.
static_assert(sizeof(void *) != 8 || sizeof(ConcatInputSection) ==
                                         sizeof(std::vector<Relocation>) + 88,
              "Try to minimize ConcatInputSection's size, we create many "
              "instances of it");

std::vector<ConcatInputSection *> macho::inputSections;
int macho::inputSectionsOrder = 0;

// Call this function to add a new InputSection and have it routed to the
// appropriate container. Depending on its type and current config, it will
// either be added to 'inputSections' vector or to a synthetic section.
void lld::macho::addInputSection(InputSection *inputSection) {
  if (auto *isec = dyn_cast<ConcatInputSection>(inputSection)) {
    if (isec->isCoalescedWeak())
      return;
    if (config->emitRelativeMethodLists &&
        ObjCMethListSection::isMethodList(isec)) {
      if (in.objcMethList->inputOrder == UnspecifiedInputOrder)
        in.objcMethList->inputOrder = inputSectionsOrder++;
      in.objcMethList->addInput(isec);
      isec->parent = in.objcMethList;
      return;
    }
    if (config->emitInitOffsets &&
        sectionType(isec->getFlags()) == S_MOD_INIT_FUNC_POINTERS) {
      in.initOffsets->addInput(isec);
      return;
    }
    isec->outSecOff = inputSectionsOrder++;
    auto *osec = ConcatOutputSection::getOrCreateForInput(isec);
    isec->parent = osec;
    inputSections.push_back(isec);
  } else if (auto *isec = dyn_cast<CStringInputSection>(inputSection)) {
    bool useSectionName = config->separateCstringLiteralSections ||
                          isec->getName() == section_names::objcMethname;
    auto *osec = in.getOrCreateCStringSection(
        useSectionName ? isec->getName() : section_names::cString);
    if (osec->inputOrder == UnspecifiedInputOrder)
      osec->inputOrder = inputSectionsOrder++;
    osec->addInput(isec);
  } else if (auto *isec = dyn_cast<WordLiteralInputSection>(inputSection)) {
    if (in.wordLiteralSection->inputOrder == UnspecifiedInputOrder)
      in.wordLiteralSection->inputOrder = inputSectionsOrder++;
    in.wordLiteralSection->addInput(isec);
  } else {
    llvm_unreachable("unexpected input section kind");
  }

  assert(inputSectionsOrder <= UnspecifiedInputOrder);
}

uint64_t InputSection::getFileSize() const {
  return isZeroFill(getFlags()) ? 0 : getSize();
}

uint64_t InputSection::getVA(uint64_t off) const {
  return parent->addr + getOffset(off);
}

uint64_t macho::resolveSymbolOffsetVA(const Symbol *sym, uint8_t type,
                                      int64_t offset) {
  const RelocAttrs &relocAttrs = target->getRelocAttrs(type);
  uint64_t symVA;
  if (relocAttrs.hasAttr(RelocAttrBits::BRANCH)) {
    // For branch relocations with non-zero offsets, use the actual function
    // address rather than the stub address. Branching to an interior point
    // of a function (e.g., _func+16) implies reliance on the original
    // function's layout, which an interposed replacement wouldn't preserve.
    // There's no meaningful way to "interpose" an interior offset.
    symVA = (offset != 0) ? sym->getVA() : sym->resolveBranchVA();
  } else if (relocAttrs.hasAttr(RelocAttrBits::GOT)) {
    symVA = sym->resolveGotVA();
  } else if (relocAttrs.hasAttr(RelocAttrBits::TLV)) {
    symVA = sym->resolveTlvVA();
  } else {
    symVA = sym->getVA();
  }
  return symVA + offset;
}

const Defined *InputSection::getContainingSymbol(uint64_t off) const {
  auto *nextSym = llvm::upper_bound(
      symbols, off, [](uint64_t a, const Defined *b) { return a < b->value; });
  if (nextSym == symbols.begin())
    return nullptr;
  return *std::prev(nextSym);
}

std::string InputSection::getLocation(uint64_t off) const {
  // First, try to find a symbol that's near the offset. Use it as a reference
  // point.
  if (auto *sym = getContainingSymbol(off))
    return (toString(getFile()) + ":(symbol " + toString(*sym) + "+0x" +
            Twine::utohexstr(off - sym->value) + ")")
        .str();

  // If that fails, use the section itself as a reference point.
  for (const Subsection &subsec : section.subsections) {
    if (subsec.isec == this) {
      off += subsec.offset;
      break;
    }
  }

  return (toString(getFile()) + ":(" + getName() + "+0x" +
          Twine::utohexstr(off) + ")")
      .str();
}

std::string InputSection::getSourceLocation(uint64_t off) const {
  auto *obj = dyn_cast_or_null<ObjFile>(getFile());
  if (!obj)
    return {};

  DWARFCache *dwarf = obj->getDwarf();
  if (!dwarf)
    return std::string();

  for (const Subsection &subsec : section.subsections) {
    if (subsec.isec == this) {
      off += subsec.offset;
      break;
    }
  }

  auto createMsg = [&](StringRef path, unsigned line) {
    std::string filename = sys::path::filename(path).str();
    std::string lineStr = (":" + Twine(line)).str();
    if (filename == path)
      return filename + lineStr;
    return (filename + lineStr + " (" + path + lineStr + ")").str();
  };

  // First, look up a function for a given offset.
  if (std::optional<DILineInfo> li = dwarf->getDILineInfo(
          section.addr + off, object::SectionedAddress::UndefSection))
    return createMsg(li->FileName, li->Line);

  // If it failed, look up again as a variable.
  if (const Defined *sym = getContainingSymbol(off)) {
    // Symbols are generally prefixed with an underscore, which is not included
    // in the debug information.
    StringRef symName = sym->getName();
    symName.consume_front("_");

    if (std::optional<std::pair<std::string, unsigned>> fileLine =
            dwarf->getVariableLoc(symName))
      return createMsg(fileLine->first, fileLine->second);
  }

  // Try to get the source file's name from the DWARF information.
  if (obj->compileUnit)
    return obj->sourceFile();

  return {};
}

const Relocation *InputSection::getRelocAt(uint32_t off) const {
  auto it = llvm::find_if(relocs,
                          [=](const Relocation &r) { return r.offset == off; });
  if (it == relocs.end())
    return nullptr;
  return &*it;
}

void ConcatInputSection::foldIdentical(ConcatInputSection *copy,
                                       Symbol::ICFFoldKind foldKind) {
  align = std::max(align, copy->align);
  copy->live = false;
  copy->wasCoalesced = true;
  copy->replacement = this;
  for (auto &copySym : copy->symbols)
    copySym->identicalCodeFoldingKind = foldKind;

  symbols.insert(symbols.end(), copy->symbols.begin(), copy->symbols.end());
  copy->symbols.clear();

  // Remove duplicate compact unwind info for symbols at the same address.
  if (symbols.empty())
    return;
  for (auto it = symbols.begin() + 1; it != symbols.end(); ++it) {
    assert((*it)->value == 0);
    (*it)->originalUnwindEntry = nullptr;
  }
}

void ConcatInputSection::writeTo(uint8_t *buf) {
  assert(!shouldOmitFromOutput());

  if (getFileSize() == 0)
    return;

  memcpy(buf, data.data(), data.size());

  for (size_t i = 0; i < relocs.size(); i++) {
    const Relocation &r = relocs[i];
    uint8_t *loc = buf + r.offset;
    uint64_t referentVA = 0;

    const bool needsFixup = config->emitChainedFixups &&
                            target->hasAttr(r.type, RelocAttrBits::UNSIGNED);
    if (target->hasAttr(r.type, RelocAttrBits::SUBTRAHEND)) {
      const Symbol *fromSym = cast<Symbol *>(r.referent);
      const Relocation &minuend = relocs[++i];
      uint64_t minuendVA;
      if (const Symbol *toSym = minuend.referent.dyn_cast<Symbol *>())
        minuendVA = toSym->getVA() + minuend.addend;
      else {
        auto *referentIsec = cast<InputSection *>(minuend.referent);
        assert(!::shouldOmitFromOutput(referentIsec));
        minuendVA = referentIsec->getVA(minuend.addend);
      }
      referentVA = minuendVA - fromSym->getVA();
    } else if (auto *referentSym = r.referent.dyn_cast<Symbol *>()) {
      if (target->hasAttr(r.type, RelocAttrBits::LOAD) &&
          !referentSym->isInGot())
        target->relaxGotLoad(loc, r.type);
      // For dtrace symbols, do not handle them as normal undefined symbols
      if (referentSym->getName().starts_with("___dtrace_")) {
        // Change dtrace call site to pre-defined instructions
        target->handleDtraceReloc(referentSym, r, loc);
        continue;
      }
      referentVA = resolveSymbolOffsetVA(referentSym, r.type, r.addend);

      if (isThreadLocalVariables(getFlags()) && isa<Defined>(referentSym)) {
        // References from thread-local variable sections are treated as offsets
        // relative to the start of the thread-local data memory area, which
        // is initialized via copying all the TLV data sections (which are all
        // contiguous).
        referentVA -= firstTLVDataSection->addr;
      } else if (needsFixup) {
        writeChainedFixup(loc, referentSym, r.addend);
        continue;
      }
    } else if (auto *referentIsec = r.referent.dyn_cast<InputSection *>()) {
      assert(!::shouldOmitFromOutput(referentIsec));
      referentVA = referentIsec->getVA(r.addend);

      if (needsFixup) {
        writeChainedRebase(loc, referentVA);
        continue;
      }
    }
    target->relocateOne(loc, r, referentVA, getVA() + r.offset);
  }
}

ConcatInputSection *macho::makeSyntheticInputSection(StringRef segName,
                                                     StringRef sectName,
                                                     uint32_t flags,
                                                     ArrayRef<uint8_t> data,
                                                     uint32_t align) {
  Section &section =
      *make<Section>(/*file=*/nullptr, segName, sectName, flags, /*addr=*/0);
  auto isec = make<ConcatInputSection>(section, data, align);
  // Since this is an explicitly created 'fake' input section,
  // it should not be dead stripped.
  isec->live = true;
  section.subsections.push_back({0, isec});
  return isec;
}

void CStringInputSection::splitIntoPieces() {
  size_t off = 0;
  StringRef s = toStringRef(data);
  while (!s.empty()) {
    size_t end = s.find(0);
    if (end == StringRef::npos)
      fatal(getLocation(off) + ": string is not null terminated");
    uint32_t hash = deduplicateLiterals ? xxh3_64bits(s.take_front(end)) : 0;
    pieces.emplace_back(off, hash);
    size_t size = end + 1; // include null terminator
    s = s.substr(size);
    off += size;
  }
}

StringPiece &CStringInputSection::getStringPiece(uint64_t off) {
  if (off >= data.size())
    fatal(toString(this) + ": offset is outside the section");

  auto it =
      partition_point(pieces, [=](StringPiece p) { return p.inSecOff <= off; });
  return it[-1];
}

const StringPiece &CStringInputSection::getStringPiece(uint64_t off) const {
  return const_cast<CStringInputSection *>(this)->getStringPiece(off);
}

size_t CStringInputSection::getStringPieceIndex(uint64_t off) const {
  if (off >= data.size())
    fatal(toString(this) + ": offset is outside the section");

  auto it =
      partition_point(pieces, [=](StringPiece p) { return p.inSecOff <= off; });
  return std::distance(pieces.begin(), it) - 1;
}

uint64_t CStringInputSection::getOffset(uint64_t off) const {
  const StringPiece &piece = getStringPiece(off);
  uint64_t addend = off - piece.inSecOff;
  return piece.outSecOff + addend;
}

WordLiteralInputSection::WordLiteralInputSection(const Section &section,
                                                 ArrayRef<uint8_t> data,
                                                 uint32_t align)
    : InputSection(WordLiteralKind, section, data, align) {
  switch (sectionType(getFlags())) {
  case S_4BYTE_LITERALS:
    power2LiteralSize = 2;
    break;
  case S_8BYTE_LITERALS:
    power2LiteralSize = 3;
    break;
  case S_16BYTE_LITERALS:
    power2LiteralSize = 4;
    break;
  default:
    llvm_unreachable("invalid literal section type");
  }

  live.resize(data.size() >> power2LiteralSize, !config->deadStrip);
}

uint64_t WordLiteralInputSection::getOffset(uint64_t off) const {
  if (off >= data.size())
    fatal(toString(this) + ": offset is outside the section");

  auto *osec = cast<WordLiteralSection>(parent);
  const uintptr_t buf = reinterpret_cast<uintptr_t>(data.data());
  switch (sectionType(getFlags())) {
  case S_4BYTE_LITERALS:
    return osec->getLiteral4Offset(buf + (off & ~3LLU)) | (off & 3);
  case S_8BYTE_LITERALS:
    return osec->getLiteral8Offset(buf + (off & ~7LLU)) | (off & 7);
  case S_16BYTE_LITERALS:
    return osec->getLiteral16Offset(buf + (off & ~15LLU)) | (off & 15);
  default:
    llvm_unreachable("invalid literal section type");
  }
}

bool macho::isCodeSection(const InputSection *isec) {
  return sections::isCodeSection(isec->getName(), isec->getSegName(),
                                 isec->getFlags());
}

bool macho::isCfStringSection(const InputSection *isec) {
  return isec->getName() == section_names::cfString &&
         isec->getSegName() == segment_names::data;
}

bool macho::isClassRefsSection(const InputSection *isec) {
  return isec->getName() == section_names::objcClassRefs &&
         isec->getSegName() == segment_names::data;
}

bool macho::isSelRefsSection(const InputSection *isec) {
  return isec->getName() == section_names::objcSelrefs &&
         isec->getSegName() == segment_names::data;
}

bool macho::isEhFrameSection(const InputSection *isec) {
  return isec->getName() == section_names::ehFrame &&
         isec->getSegName() == segment_names::text;
}

bool macho::isGccExceptTabSection(const InputSection *isec) {
  return isec->getName() == section_names::gccExceptTab &&
         isec->getSegName() == segment_names::text;
}

std::string lld::toString(const InputSection *isec) {
  return (toString(isec->getFile()) + ":(" + isec->getName() + ")").str();
}
