// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file contains internal parts of the Abseil symbolizer.
// Do not depend on the anything in this file, it may change at anytime.

#ifndef ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_
#define ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_

#include <cstddef>
#include <cstdint>

#include "absl/base/config.h"

#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE
#error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set
#elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \
    !defined(__asmjs__) && !defined(__wasm__)
#define ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE 1

#include <elf.h>
#include <link.h>  // For ElfW() macro.
#include <functional>
#include <string>

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace debugging_internal {

// Iterates over all sections, invoking callback on each with the section name
// and the section header.
//
// Returns true on success; otherwise returns false in case of errors.
//
// This is not async-signal-safe.
bool ForEachSection(int fd,
                    const std::function<bool(const std::string& name,
                                             const ElfW(Shdr) &)>& callback);

// Gets the section header for the given name, if it exists. Returns true on
// success. Otherwise, returns false.
bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
                            ElfW(Shdr) *out);

}  // namespace debugging_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace debugging_internal {

struct SymbolDecoratorArgs {
  // The program counter we are getting symbolic name for.
  const void *pc;
  // 0 for main executable, load address for shared libraries.
  ptrdiff_t relocation;
  // Read-only file descriptor for ELF image covering "pc",
  // or -1 if no such ELF image exists in /proc/self/maps.
  int fd;
  // Output buffer, size.
  // Note: the buffer may not be empty -- default symbolizer may have already
  // produced some output, and earlier decorators may have adorned it in
  // some way. You are free to replace or augment the contents (within the
  // symbol_buf_size limit).
  char *const symbol_buf;
  size_t symbol_buf_size;
  // Temporary scratch space, size.
  // Use that space in preference to allocating your own stack buffer to
  // conserve stack.
  char *const tmp_buf;
  size_t tmp_buf_size;
  // User-provided argument
  void* arg;
};
using SymbolDecorator = void (*)(const SymbolDecoratorArgs *);

// Installs a function-pointer as a decorator. Returns a value less than zero
// if the system cannot install the decorator. Otherwise, returns a unique
// identifier corresponding to the decorator. This identifier can be used to
// uninstall the decorator - See RemoveSymbolDecorator() below.
int InstallSymbolDecorator(SymbolDecorator decorator, void* arg);

// Removes a previously installed function-pointer decorator. Parameter "ticket"
// is the return-value from calling InstallSymbolDecorator().
bool RemoveSymbolDecorator(int ticket);

// Remove all installed decorators.  Returns true if successful, false if
// symbolization is currently in progress.
bool RemoveAllSymbolDecorators(void);

// Registers an address range to a file mapping.
//
// Preconditions:
//   start <= end
//   filename != nullptr
//
// Returns true if the file was successfully registered.
bool RegisterFileMappingHint(
    const void* start, const void* end, uint64_t offset, const char* filename);

// Looks up the file mapping registered by RegisterFileMappingHint for an
// address range. If there is one, the file name is stored in *filename and
// *start and *end are modified to reflect the registered mapping. Returns
// whether any hint was found.
bool GetFileMappingHint(const void** start,
                        const void** end,
                        uint64_t    *  offset,
                        const char** filename);

}  // namespace debugging_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_
