//===-FrameHeaderCache.hpp ------------------------------------------------===//
//
// 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
//
// Cache the elf program headers necessary to unwind the stack more efficiently
// in the presence of many dsos.
//
//===----------------------------------------------------------------------===//

#ifndef __FRAMEHEADER_CACHE_HPP__
#define __FRAMEHEADER_CACHE_HPP__

#include "config.h"
#include <limits.h>

#ifdef _LIBUNWIND_DEBUG_FRAMEHEADER_CACHE
#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE0(x) _LIBUNWIND_LOG0(x)
#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE(msg, ...)                            \
  _LIBUNWIND_LOG(msg, __VA_ARGS__)
#else
#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE0(x)
#define _LIBUNWIND_FRAMEHEADERCACHE_TRACE(msg, ...)
#endif

// This cache should only be be used from within a dl_iterate_phdr callback.
// dl_iterate_phdr does the necessary synchronization to prevent problems
// with concurrent access via the libc load lock. Adding synchronization
// for other uses is possible, but not currently done.

class _LIBUNWIND_HIDDEN FrameHeaderCache {
  struct CacheEntry {
    uintptr_t LowPC() { return Info.dso_base; };
    uintptr_t HighPC() { return Info.dso_base + Info.dwarf_section_length; };
    UnwindInfoSections Info;
    CacheEntry *Next;
  };

  static const size_t kCacheEntryCount = 8;

  // Can't depend on the C++ standard library in libunwind, so use an array to
  // allocate the entries, and two linked lists for ordering unused and recently
  // used entries.  FIXME: Would the the extra memory for a doubly-linked list
  // be better than the runtime cost of traversing a very short singly-linked
  // list on a cache miss? The entries themselves are all small and consecutive,
  // so unlikely to cause page faults when following the pointers. The memory
  // spent on additional pointers could also be spent on more entries.

  CacheEntry Entries[kCacheEntryCount];
  CacheEntry *MostRecentlyUsed;
  CacheEntry *Unused;

  void resetCache() {
    _LIBUNWIND_FRAMEHEADERCACHE_TRACE0("FrameHeaderCache reset");
    MostRecentlyUsed = nullptr;
    Unused = &Entries[0];
    for (size_t i = 0; i < kCacheEntryCount - 1; i++) {
      Entries[i].Next = &Entries[i + 1];
    }
    Entries[kCacheEntryCount - 1].Next = nullptr;
  }

  bool cacheNeedsReset(dl_phdr_info *PInfo) {
    // C libraries increment dl_phdr_info.adds and dl_phdr_info.subs when
    // loading and unloading shared libraries. If these values change between
    // iterations of dl_iterate_phdr, then invalidate the cache.

    // These are static to avoid needing an initializer, and unsigned long long
    // because that is their type within the extended dl_phdr_info.  Initialize
    // these to something extremely unlikely to be found upon the first call to
    // dl_iterate_phdr.
    static unsigned long long LastAdds = ULLONG_MAX;
    static unsigned long long LastSubs = ULLONG_MAX;
    if (PInfo->dlpi_adds != LastAdds || PInfo->dlpi_subs != LastSubs) {
      // Resetting the entire cache is a big hammer, but this path is rare--
      // usually just on the very first call, when the cache is empty anyway--so
      // added complexity doesn't buy much.
      LastAdds = PInfo->dlpi_adds;
      LastSubs = PInfo->dlpi_subs;
      resetCache();
      return true;
    }
    return false;
  }

public:
  bool find(dl_phdr_info *PInfo, size_t, void *data) {
    if (cacheNeedsReset(PInfo) || MostRecentlyUsed == nullptr)
      return false;

    auto *CBData = static_cast<dl_iterate_cb_data *>(data);
    CacheEntry *Current = MostRecentlyUsed;
    CacheEntry *Previous = nullptr;
    while (Current != nullptr) {
      _LIBUNWIND_FRAMEHEADERCACHE_TRACE(
          "FrameHeaderCache check %lx in [%lx - %lx)", CBData->targetAddr,
          Current->LowPC(), Current->HighPC());
      if (Current->LowPC() <= CBData->targetAddr &&
          CBData->targetAddr < Current->HighPC()) {
        _LIBUNWIND_FRAMEHEADERCACHE_TRACE(
            "FrameHeaderCache hit %lx in [%lx - %lx)", CBData->targetAddr,
            Current->LowPC(), Current->HighPC());
        if (Previous) {
          // If there is no Previous, then Current is already the
          // MostRecentlyUsed, and no need to move it up.
          Previous->Next = Current->Next;
          Current->Next = MostRecentlyUsed;
          MostRecentlyUsed = Current;
        }
        *CBData->sects = Current->Info;
        return true;
      }
      Previous = Current;
      Current = Current->Next;
    }
    _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache miss for address %lx",
                                      CBData->targetAddr);
    return false;
  }

  void add(const UnwindInfoSections *UIS) {
    CacheEntry *Current = nullptr;

    if (Unused != nullptr) {
      Current = Unused;
      Unused = Unused->Next;
    } else {
      Current = MostRecentlyUsed;
      CacheEntry *Previous = nullptr;
      while (Current->Next != nullptr) {
        Previous = Current;
        Current = Current->Next;
      }
      Previous->Next = nullptr;
      _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache evict [%lx - %lx)",
                                        Current->LowPC(), Current->HighPC());
    }

    Current->Info = *UIS;
    Current->Next = MostRecentlyUsed;
    MostRecentlyUsed = Current;
    _LIBUNWIND_FRAMEHEADERCACHE_TRACE("FrameHeaderCache add [%lx - %lx)",
                                      MostRecentlyUsed->LowPC(),
                                      MostRecentlyUsed->HighPC());
  }
};

#endif // __FRAMEHEADER_CACHE_HPP__
