// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_INIT_FINI_H_
#define SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_INIT_FINI_H_

#include <lib/stdcompat/span.h>

#include <optional>

#include "abi-span.h"

namespace elfldltl {

// A module initializer or finalizer function has type void().
using InitFiniFunction = void();

// This represents the information about either initializers or finalizers for
// one ELF module.  Two separate InitFiniInfo objects are used for a module's
// initializers and finalizers.
//
// This is normally populated by a call to elfldltl::DecodeDynamic using an
// elfldltl::DynamicInitObserver or elfldltl::DynamicFiniObserver observer.
//
// The VisitInit or VisitFini methods provide general ordered access to the
// function addresses in each list.  The correct method should be used for each
// kind of list to get the appropriate ordering of elements.
//
// The CallInit and CallFini methods directly call each function in order, for
// immediate in-process uses.
template <class Elf, class AbiTraits = LocalAbiTraits>
struct InitFiniInfo {
 public:
  using Addr = typename Elf::Addr;
  using size_type = typename Elf::size_type;

  // An array of function pointers, in the .init_array or .fini_array section,
  // which is normally part of the RELRO segment.  So the pointers here are
  // unrelocated in the file, but dynamic relocation records apply simple
  // fixup.  As this points directly into the load image in the Memory object,
  // if that image is being relocated in place, then these values will be
  // absolute function pointers after relocation.  If the original file data
  // (or the load image before relocation) is being read, the these addresses
  // need the load bias added.
  constexpr cpp20::span<const Addr> array() const { return array_; }

  // A single function pointer, from the legacy DT_INIT or DT_FINI entry.  This
  // is not contiguous with the array and is stored separately in the ELF
  // headers where no relocation records apply.  So this address always needs
  // the load bias added to yield a runtime function pointer.
  constexpr std::optional<Addr> legacy() const {
    if (legacy_ != 0) {
      return legacy_;
    }
    return std::nullopt;
  }

  constexpr InitFiniInfo& set_array(cpp20::span<const Addr> array) {
    array_ = array;
    return *this;
  }

  constexpr InitFiniInfo& set_legacy(Addr legacy) {
    legacy_ = legacy;
    return *this;
  }

  // Return the number of function pointers present.
  constexpr size_t size() const { return array_.size() + (legacy_ != 0 ? 1 : 0); }

  constexpr bool empty() const { return size() == 0; }

  // Call init(Addr, bool) exactly size() times.  The flag in each callback is
  // true iff Addr has already been relocated.  The argument flag should be
  // true iff relocations affecting RELRO data have already been applied.
  template <typename T>
  constexpr void VisitInit(T&& init, bool relocated) const {
    if (legacy_ != 0) {
      init(legacy_, false);
    }
    for (const auto& addr : array_) {
      init(addr, relocated);
    }
  }

  // Same as VisitInit, but in the reverse order.
  template <typename T>
  constexpr void VisitFini(T&& fini, bool relocated) const {
    for (auto it = array_.rbegin(); it != array_.rend(); ++it) {
      fini(*it, relocated);
    }
    if (legacy_ != 0) {
      fini(legacy_, false);
    }
  }

  // This returns a callback suitable to pass to VisitInit or VisitFini to
  // directly call the functions right here.
  static constexpr auto RelocatedCall(size_type bias) {
    return [bias](const Addr& addr, bool relocated) {
      uintptr_t fnaddr = addr;
      if (!relocated) {
        fnaddr += bias;
      }
      auto fn = reinterpret_cast<InitFiniFunction*>(fnaddr);
      (*fn)();
    };
  }

  // Call all the functions in initialization order.
  void CallInit(size_type bias, bool relocated = true) const {
    VisitInit(RelocatedCall(bias), relocated);
  }

  // Call all the functions in finalization order.
  void CallFini(size_type bias, bool relocated = true) const {
    VisitFini(RelocatedCall(bias), relocated);
  }

 private:
  AbiSpan<const Addr, cpp20::dynamic_extent, Elf, AbiTraits> array_;
  Addr legacy_ = 0;

 public:
  // <lib/ld/remote-abi-transcriber.h> introspection API.  These aliases must
  // be public, but can't be defined lexically before the private: section that
  // declares the members; so this special public: section is at the end.

  using AbiLocal = InitFiniInfo<Elf, LocalAbiTraits>;

  template <template <class...> class Template>
  using AbiBases = Template<>;

  template <template <auto...> class Template>
  using AbiMembers = Template<&InitFiniInfo::array_, &InitFiniInfo::legacy_>;
};

}  // namespace elfldltl

#endif  // SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_INIT_FINI_H_
