chromium/base/debug/dwarf_line_no.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include "base/debug/dwarf_line_no.h"

#include "partition_alloc/pointers/raw_ref.h"

#ifdef USE_SYMBOLIZE
#include <algorithm>
#include <charconv>
#include <cstdint>
#include <limits>

#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "base/debug/buffered_dwarf_reader.h"
#include "base/third_party/symbolize/symbolize.h"
#include "partition_alloc/pointers/raw_ptr.h"

namespace base {
namespace debug {

namespace {

constexpr uint64_t kMaxOffset =;

// These numbers are suitable for most compilation units for chrome and
// content_shell. If a compilation unit has bigger number of directories or
// filenames, the additional directories/filenames will be ignored, and the
// stack frames pointing to these directories/filenames will not get line
// numbers. We can't set these numbers too big because they affect the size of
// ProgramInfo which is allocated in the stack.
constexpr int kMaxDirectories =;
constexpr size_t kMaxFilenames =;

// DWARF-4 line number program header, section 6.2.4
struct ProgramInfo {};

// DWARF-4 line number program registers, section 6.2.2
struct LineNumberRegisters {};

struct LineNumberInfo {};

// Evaluates a Line Number Program as defined by the rules in section 6.2.5.
void EvaluateLineNumberProgram(const int fd,
                               LineNumberInfo* info,
                               uint64_t base_address,
                               uint64_t start,
                               const ProgramInfo& program_info) {}

// Parses a 32-bit DWARF-4 line number program header per section 6.2.4.
// `cu_name_offset` is the module offset for the 0th entry of the file table.
bool ParseDwarf4ProgramInfo(BufferedDwarfReader* reader,
                            bool is_64bit,
                            uint64_t cu_name_offset,
                            ProgramInfo* program_info) {}

// Returns the offset of the next byte to read.
// `program_info.program_end` is guaranteed to be initlialized to either
// `kMaxOffset` if the program length could not be processed, or to
// the byte after the end of this program.
bool ReadProgramInfo(const int fd,
                     uint64_t start,
                     uint64_t cu_name_offset,
                     ProgramInfo* program_info) {}

// Attempts to find line-number info for all of |info|. Returns the number of
// entries that do not have info yet.
uint64_t GetLineNumbersInProgram(const int fd,
                                 LineNumberInfo* info,
                                 uint64_t base_address,
                                 uint64_t start,
                                 uint64_t cu_name_offset) {}

// Scans the .debug_abbrev entry until it finds the Attribute List matching the
// `wanted_abbreviation_code`. This is called when parsing a DIE in .debug_info.
bool AdvancedReaderToAttributeList(BufferedDwarfReader& reader,
                                   uint64_t table_end,
                                   uint64_t wanted_abbreviation_code,
                                   uint64_t& tag,
                                   bool& has_children) {}

// This reads through a .debug_info compile unit entry to try and extract
// the `cu_name_offset` as well as the `debug_line_offset` (offset into the
// .debug_lines table` corresponding to `pc`.
//
// The .debug_info sections are a packed set of bytes whose format is defined
// by a corresponding .debug_abbrev entry. Basically .debug_abbrev describes
// a struct and .debug_info has a header that tells which struct it is followed
// by a bunch of bytes.
//
// The control flow is to find the .debug_abbrev entry for each .debug_info
// entry, then walk through the .debug_abbrev entry to parse the bytes of the
// .debug_info entry. A successful parse calculates the address range that the
// .debug_info entry covers. When that is retrieved, `pc` can be compared to
// the range and a corresponding .debug_info can be found.
//
// The `debug_info_start` be the start of the whole .debug_info section or an
// offset into the section if it was known ahead of time (perhaps by consulting
// .debug_aranges).
//
// To fully interpret this data, the .debug_ranges and .debug_str sections
// also need to be interpreted.
bool GetCompileUnitName(int fd,
                        uint64_t debug_info_start,
                        uint64_t debug_info_end,
                        uint64_t pc,
                        uint64_t module_base_address,
                        uint64_t* debug_line_offset,
                        uint64_t* cu_name_offset) {}

// Thin wrapper over `GetCompileUnitName` that opens the .debug_info section.
bool ReadCompileUnit(int fd,
                     uint64_t pc,
                     uint64_t cu_offset,
                     uint64_t base_address,
                     uint64_t* debug_line_offset,
                     uint64_t* cu_name_offset) {}

// Takes the information from `info` and renders the data located in the
// object file `fd` into `out`.  The format looks like:
//
//   [../path/to/foo.cc:10:40]
//
// which would indicate line 10 column 40 in  ../path/to/foo.cc
void SerializeLineNumberInfoToString(int fd,
                                     const LineNumberInfo& info,
                                     char* out,
                                     size_t out_size) {}

// Reads the Line Number info for a compile unit.
bool GetLineNumberInfoFromObject(int fd,
                                 uint64_t pc,
                                 uint64_t cu_offset,
                                 uint64_t base_address,
                                 char* out,
                                 size_t out_size) {}

struct FrameInfo {};

// Returns the number of frames still missing info.
//
// The aranges table is a mapping of ranges to compilation units. Given an array
// of `frame_info`, this finds the compile units for each of the frames doing
// only one pass over the table. It does not preserve the order of `frame_info`.
//
// The main benefit of this function is preserving the single pass through the
// table which is important for performance.
size_t ProcessFlatArangeSet(BufferedDwarfReader* reader,
                            uint64_t next_set,
                            uint8_t address_size,
                            uint64_t base_address,
                            uint64_t cu_offset,
                            FrameInfo* frame_info,
                            size_t num_frames) {}

// This is a pre-step that uses the .debug_aranges table to find all the compile
// units for a given set of frames. This allows code to avoid iterating over
// all compile units at a later step in the symbolization process.
void PopulateCompileUnitOffsets(int fd,
                                FrameInfo* frame_info,
                                size_t num_frames,
                                uint64_t base_address) {}

}  // namespace

bool GetDwarfSourceLineNumber(const void* pc,
                              uint64_t cu_offset,
                              char* out,
                              size_t out_size) {}

void GetDwarfCompileUnitOffsets(const void* const* trace,
                                uint64_t* cu_offsets,
                                size_t num_frames) {}

}  // namespace debug
}  // namespace base

#else  // USE_SYMBOLIZE

#include <cstring>

namespace base {
namespace debug {

bool GetDwarfSourceLineNumber(const void* pc,
                              uint64_t cu_offset,
                              char* out,
                              size_t out_size) {
  return false;
}

void GetDwarfCompileUnitOffsets(const void* const* trace,
                                uint64_t* cu_offsets,
                                size_t num_frames) {
  // Provide defined values even in the stub.
  memset(cu_offsets, 0, sizeof(cu_offsets) * num_frames);
}

}  // namespace debug
}  // namespace base

#endif