//===- InputChunks.h --------------------------------------------*- C++ -*-===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// An InputChunks represents an indivisible opaque region of a input wasm file.
// i.e. a single wasm data segment or a single wasm function.
//
// They are written directly to the mmap'd output file after which relocations
// are applied.  Because each Chunk is independent they can be written in
// parallel.
//
// Chunks are also unit on which garbage collection (--gc-sections) operates.
//
//===----------------------------------------------------------------------===//

#ifndef LLD_WASM_INPUT_CHUNKS_H
#define LLD_WASM_INPUT_CHUNKS_H

#include "Config.h"
#include "InputFiles.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/Wasm.h"

using llvm::object::WasmSection;
using llvm::object::WasmSegment;
using llvm::wasm::WasmFunction;
using llvm::wasm::WasmRelocation;
using llvm::wasm::WasmSignature;

namespace llvm {
class raw_ostream;
}

namespace lld {
namespace wasm {

class ObjFile;
class OutputSegment;

class InputChunk {
public:
  enum Kind { DataSegment, Function, SyntheticFunction, Section };

  Kind kind() const { return SectionKind; }

  virtual uint32_t getSize() const { return data().size(); }
  virtual uint32_t getInputSize() const { return getSize(); };

  virtual void writeTo(uint8_t *SectionStart) const;

  ArrayRef<WasmRelocation> getRelocations() const { return Relocations; }
  void setRelocations(ArrayRef<WasmRelocation> Rs) { Relocations = Rs; }

  virtual StringRef getName() const = 0;
  virtual StringRef getDebugName() const = 0;
  virtual uint32_t getComdat() const = 0;
  StringRef getComdatName() const;
  virtual uint32_t getInputSectionOffset() const = 0;

  size_t NumRelocations() const { return Relocations.size(); }
  void writeRelocations(llvm::raw_ostream &OS) const;

  ObjFile *File;
  int32_t OutputOffset = 0;

  // Signals that the section is part of the output.  The garbage collector,
  // and COMDAT handling can set a sections' Live bit.
  // If GC is disabled, all sections start out as live by default.
  unsigned Live : 1;

protected:
  InputChunk(ObjFile *F, Kind K)
      : File(F), Live(!Config->GcSections), SectionKind(K) {}
  virtual ~InputChunk() = default;
  virtual ArrayRef<uint8_t> data() const = 0;

  // Verifies the existing data at relocation targets matches our expectations.
  // This is performed only debug builds as an extra sanity check.
  void verifyRelocTargets() const;

  ArrayRef<WasmRelocation> Relocations;
  Kind SectionKind;
};

// Represents a WebAssembly data segment which can be included as part of
// an output data segments.  Note that in WebAssembly, unlike ELF and other
// formats, used the term "data segment" to refer to the continous regions of
// memory that make on the data section. See:
// https://webassembly.github.io/spec/syntax/modules.html#syntax-data
//
// For example, by default, clang will produce a separate data section for
// each global variable.
class InputSegment : public InputChunk {
public:
  InputSegment(const WasmSegment &Seg, ObjFile *F)
      : InputChunk(F, InputChunk::DataSegment), Segment(Seg) {}

  static bool classof(const InputChunk *C) { return C->kind() == DataSegment; }

  uint32_t getAlignment() const { return Segment.Data.Alignment; }
  StringRef getName() const override { return Segment.Data.Name; }
  StringRef getDebugName() const override { return StringRef(); }
  uint32_t getComdat() const override { return Segment.Data.Comdat; }
  uint32_t getInputSectionOffset() const override {
    return Segment.SectionOffset;
  }

  const OutputSegment *OutputSeg = nullptr;
  int32_t OutputSegmentOffset = 0;

protected:
  ArrayRef<uint8_t> data() const override { return Segment.Data.Content; }

  const WasmSegment &Segment;
};

// Represents a single wasm function within and input file.  These are
// combined to create the final output CODE section.
class InputFunction : public InputChunk {
public:
  InputFunction(const WasmSignature &S, const WasmFunction *Func, ObjFile *F)
      : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {}

  static bool classof(const InputChunk *C) {
    return C->kind() == InputChunk::Function ||
           C->kind() == InputChunk::SyntheticFunction;
  }

  void writeTo(uint8_t *SectionStart) const override;
  StringRef getName() const override { return Function->SymbolName; }
  StringRef getDebugName() const override { return Function->DebugName; }
  uint32_t getComdat() const override { return Function->Comdat; }
  uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); }
  uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; }
  uint32_t getSize() const override {
    if (Config->CompressRelocTargets && File) {
      assert(CompressedSize);
      return CompressedSize;
    }
    return data().size();
  }
  uint32_t getInputSize() const override { return Function->Size; }
  uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); }
  bool hasFunctionIndex() const { return FunctionIndex.hasValue(); }
  void setFunctionIndex(uint32_t Index);
  uint32_t getInputSectionOffset() const override {
    return Function->CodeSectionOffset;
  }
  uint32_t getTableIndex() const { return TableIndex.getValue(); }
  bool hasTableIndex() const { return TableIndex.hasValue(); }
  void setTableIndex(uint32_t Index);

  // The size of a given input function can depend on the values of the
  // LEB relocations within it.  This finalizeContents method is called after
  // all the symbol values have be calcualted but before getSize() is ever
  // called.
  void calculateSize();

  const WasmSignature &Signature;

protected:
  ArrayRef<uint8_t> data() const override {
    assert(!Config->CompressRelocTargets);
    return File->CodeSection->Content.slice(getInputSectionOffset(),
                                            Function->Size);
  }

  const WasmFunction *Function;
  llvm::Optional<uint32_t> FunctionIndex;
  llvm::Optional<uint32_t> TableIndex;
  uint32_t CompressedFuncSize = 0;
  uint32_t CompressedSize = 0;
};

class SyntheticFunction : public InputFunction {
public:
  SyntheticFunction(const WasmSignature &S, StringRef Name,
                    StringRef DebugName = {})
      : InputFunction(S, nullptr, nullptr), Name(Name), DebugName(DebugName) {
    SectionKind = InputChunk::SyntheticFunction;
  }

  static bool classof(const InputChunk *C) {
    return C->kind() == InputChunk::SyntheticFunction;
  }

  StringRef getName() const override { return Name; }
  StringRef getDebugName() const override { return DebugName; }
  uint32_t getComdat() const override { return UINT32_MAX; }

  void setBody(ArrayRef<uint8_t> Body_) { Body = Body_; }

protected:
  ArrayRef<uint8_t> data() const override { return Body; }

  StringRef Name;
  StringRef DebugName;
  ArrayRef<uint8_t> Body;
};

// Represents a single Wasm Section within an input file.
class InputSection : public InputChunk {
public:
  InputSection(const WasmSection &S, ObjFile *F)
      : InputChunk(F, InputChunk::Section), Section(S) {
    assert(Section.Type == llvm::wasm::WASM_SEC_CUSTOM);
  }

  StringRef getName() const override { return Section.Name; }
  StringRef getDebugName() const override { return StringRef(); }
  uint32_t getComdat() const override { return UINT32_MAX; }

protected:
  ArrayRef<uint8_t> data() const override { return Section.Content; }

  // Offset within the input section.  This is only zero since this chunk
  // type represents an entire input section, not part of one.
  uint32_t getInputSectionOffset() const override { return 0; }

  const WasmSection &Section;
};

} // namespace wasm

std::string toString(const wasm::InputChunk *);
} // namespace lld

#endif // LLD_WASM_INPUT_CHUNKS_H
