// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/debug/elf_reader.h"

#include <arpa/inet.h>
#include <elf.h>
#include <string.h>

#include "base/bits.h"
#include "base/containers/span.h"
#include "base/hash/sha1.h"
#include "base/strings/safe_sprintf.h"
#include "build/build_config.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

// NOTE: This code may be used in crash handling code, so the implementation
// must avoid dynamic memory allocation or using data structures which rely on
// dynamic allocation.

namespace base {
namespace debug {
namespace {

// See https://refspecs.linuxbase.org/elf/elf.pdf for the ELF specification.

#if __SIZEOF_POINTER__ == 4
using Ehdr = Elf32_Ehdr;
using Dyn = Elf32_Dyn;
using Half = Elf32_Half;
using Nhdr = Elf32_Nhdr;
using Word = Elf32_Word;
using Xword = Elf32_Word;
#else
using Ehdr = Elf64_Ehdr;
using Dyn = Elf64_Dyn;
using Half = Elf64_Half;
using Nhdr = Elf64_Nhdr;
using Word = Elf64_Word;
using Xword = Elf64_Xword;
#endif

constexpr char kGnuNoteName[] = "GNU";

// Returns a pointer to the header of the ELF binary mapped into memory, or a
// null pointer if the header is invalid. Here and below |elf_mapped_base| is a
// pointer to the start of the ELF image.
const Ehdr* GetElfHeader(const void* elf_mapped_base) {
  if (strncmp(reinterpret_cast<const char*>(elf_mapped_base), ELFMAG,
              SELFMAG) != 0)
    return nullptr;

  return reinterpret_cast<const Ehdr*>(elf_mapped_base);
}

}  // namespace

size_t ReadElfBuildId(const void* elf_mapped_base,
                      bool uppercase,
                      ElfBuildIdBuffer build_id) {
  // NOTE: Function should use async signal safe calls only.

  const Ehdr* elf_header = GetElfHeader(elf_mapped_base);
  if (!elf_header)
    return 0;

  const size_t relocation_offset = GetRelocationOffset(elf_mapped_base);
  for (const Phdr& header : GetElfProgramHeaders(elf_mapped_base)) {
    if (header.p_type != PT_NOTE)
      continue;

    // Look for a NT_GNU_BUILD_ID note with name == "GNU".
    const char* current_section =
        reinterpret_cast<const char*>(header.p_vaddr + relocation_offset);
    const char* section_end = current_section + header.p_memsz;
    const Nhdr* current_note = nullptr;
    bool found = false;
    while (current_section < section_end) {
      current_note = reinterpret_cast<const Nhdr*>(current_section);
      if (current_note->n_type == NT_GNU_BUILD_ID) {
        StringPiece note_name(current_section + sizeof(Nhdr),
                              current_note->n_namesz);
        // Explicit constructor is used to include the '\0' character.
        if (note_name == StringPiece(kGnuNoteName, sizeof(kGnuNoteName))) {
          found = true;
          break;
        }
      }

      size_t section_size = bits::AlignUp(current_note->n_namesz, 4u) +
                            bits::AlignUp(current_note->n_descsz, 4u) +
                            sizeof(Nhdr);
      if (section_size > static_cast<size_t>(section_end - current_section))
        return 0;
      current_section += section_size;
    }

    if (!found)
      continue;

    // Validate that the serialized build ID will fit inside |build_id|.
    size_t note_size = current_note->n_descsz;
    if ((note_size * 2) > kMaxBuildIdStringLength)
      continue;

    // Write out the build ID as a null-terminated hex string.
    const uint8_t* build_id_raw =
        reinterpret_cast<const uint8_t*>(current_note) + sizeof(Nhdr) +
        bits::AlignUp(current_note->n_namesz, 4u);
    size_t i = 0;
    for (i = 0; i < current_note->n_descsz; ++i) {
      strings::SafeSNPrintf(&build_id[i * 2], 3, (uppercase ? "%02X" : "%02x"),
                            build_id_raw[i]);
    }
    build_id[i * 2] = '\0';

    // Return the length of the string.
    return i * 2;
  }

  return 0;
}

absl::optional<StringPiece> ReadElfLibraryName(const void* elf_mapped_base) {
  // NOTE: Function should use async signal safe calls only.

  const Ehdr* elf_header = GetElfHeader(elf_mapped_base);
  if (!elf_header)
    return {};

  const size_t relocation_offset = GetRelocationOffset(elf_mapped_base);
  for (const Phdr& header : GetElfProgramHeaders(elf_mapped_base)) {
    if (header.p_type != PT_DYNAMIC)
      continue;

    // Read through the ELF dynamic sections to find the string table and
    // SONAME offsets, which are used to compute the offset of the library
    // name string.
    const Dyn* dynamic_start =
        reinterpret_cast<const Dyn*>(header.p_vaddr + relocation_offset);
    const Dyn* dynamic_end = reinterpret_cast<const Dyn*>(
        header.p_vaddr + relocation_offset + header.p_memsz);
    Xword soname_strtab_offset = 0;
    const char* strtab_addr = 0;
    for (const Dyn* dynamic_iter = dynamic_start; dynamic_iter < dynamic_end;
         ++dynamic_iter) {
      if (dynamic_iter->d_tag == DT_STRTAB) {
#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_ANDROID)
        // Fuchsia and Android do not relocate the symtab pointer on ELF load.
        strtab_addr = static_cast<size_t>(dynamic_iter->d_un.d_ptr) +
                      reinterpret_cast<const char*>(relocation_offset);
#else
        strtab_addr = reinterpret_cast<const char*>(dynamic_iter->d_un.d_ptr);
#endif
      } else if (dynamic_iter->d_tag == DT_SONAME) {
        // The Android NDK wrongly defines `d_val` as an Elf32_Sword for 32 bits
        // and thus needs this cast.
        soname_strtab_offset = static_cast<Xword>(dynamic_iter->d_un.d_val);
      }
    }
    if (soname_strtab_offset && strtab_addr)
      return StringPiece(strtab_addr + soname_strtab_offset);
  }

  return absl::nullopt;
}

span<const Phdr> GetElfProgramHeaders(const void* elf_mapped_base) {
  // NOTE: Function should use async signal safe calls only.

  const Ehdr* elf_header = GetElfHeader(elf_mapped_base);
  if (!elf_header)
    return {};

  const char* phdr_start =
      reinterpret_cast<const char*>(elf_header) + elf_header->e_phoff;
  return span<const Phdr>(reinterpret_cast<const Phdr*>(phdr_start),
                          elf_header->e_phnum);
}

// Returns the offset to add to virtual addresses in the image to compute the
// mapped virtual address.
size_t GetRelocationOffset(const void* elf_mapped_base) {
  span<const Phdr> headers = GetElfProgramHeaders(elf_mapped_base);
  for (const Phdr& header : headers) {
    if (header.p_type == PT_LOAD) {
      // |elf_mapped_base| + |header.p_offset| is the mapped address of this
      // segment. |header.p_vaddr| is the specified virtual address within the
      // ELF image.
      const char* const mapped_address =
          reinterpret_cast<const char*>(elf_mapped_base) + header.p_offset;
      return reinterpret_cast<uintptr_t>(mapped_address) - header.p_vaddr;
    }
  }

  // Assume the virtual addresses in the image start at 0, so the offset is
  // from 0 to the actual mapped base address.
  return static_cast<size_t>(reinterpret_cast<uintptr_t>(elf_mapped_base) -
                             reinterpret_cast<uintptr_t>(nullptr));
}

}  // namespace debug
}  // namespace base
