mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-01 01:36:09 +03:00
128 lines
4.4 KiB
C++
128 lines
4.4 KiB
C++
// 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.
|
|
|
|
#ifndef BASE_DEBUG_BUFFERED_DWARF_READER_H_
|
|
#define BASE_DEBUG_BUFFERED_DWARF_READER_H_
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
|
|
#ifdef USE_SYMBOLIZE
|
|
|
|
namespace base {
|
|
namespace debug {
|
|
|
|
class BufferedDwarfReader {
|
|
public:
|
|
// Constructs a BufferedDwarfReader for a given `fd` starting
|
|
// `position` bytes from the start of the file.
|
|
//
|
|
// BufferedDwarfReader does not affect the `fd` state so it is completely
|
|
// okay to have multiple BufferedDwarfReader attached to one `fd` to act
|
|
// as cursors into different parts of the file.
|
|
BufferedDwarfReader(int fd, uint64_t position);
|
|
|
|
// Gets and Sets the absolute position from the start of the file.
|
|
uint64_t position() const { return last_chunk_start_ + cursor_in_buffer_; }
|
|
|
|
void set_position(uint64_t position) {
|
|
last_chunk_start_ = next_chunk_start_ = position;
|
|
|
|
// Invalidate buffer.
|
|
cursor_in_buffer_ = 0;
|
|
unconsumed_amount_ = 0;
|
|
}
|
|
|
|
bool ReadChar(char& value) { return ReadInt(value); }
|
|
bool ReadInt8(uint8_t& value) { return ReadInt(value); }
|
|
bool ReadInt8(int8_t& value) { return ReadInt(value); }
|
|
bool ReadInt16(uint16_t& value) { return ReadInt(value); }
|
|
bool ReadInt32(uint32_t& value) { return ReadInt(value); }
|
|
bool ReadInt64(uint64_t& value) { return ReadInt(value); }
|
|
|
|
// Helper to read a null-terminated sequence of bytes.
|
|
//
|
|
// Reads at most `max_position - position()` bytes.
|
|
//
|
|
// Returns the number of bytes written into `out`.
|
|
// On a read error, the internal position of the BufferedDwarfReader may
|
|
// still be advanced. This should only happen if something funky
|
|
// happens at the OS layer at which case it's all best-effort
|
|
// recovery afterwards anyways.
|
|
size_t ReadCString(uint64_t max_position, char* out, size_t out_size);
|
|
|
|
// Leb128 is a variable-length integer encoding format. This reads
|
|
// both the signed and unsigned variants of this field.
|
|
bool ReadLeb128(uint64_t& value);
|
|
bool ReadLeb128(int64_t& value);
|
|
|
|
// Headers in DWARF often start with a length field of type "initial length."
|
|
// This is a variable-length field that both indicates if the entry is in
|
|
// 32-bit or 64-bit DWARF format and the length of the entry.
|
|
//
|
|
// Note: is_64bit refers to the DWARF format, not the target architecture.
|
|
// Most 64-bit binaries use 32-bit DWARF so is_64bit is frequently false.
|
|
bool ReadInitialLength(bool& is_64bit, uint64_t& length);
|
|
|
|
// Offsets inside DWARF are encoded at different sizes based on if it is
|
|
// 32-bit DWARF or 64-bit DWARF. The value of `is_64bit` is usually retrieved
|
|
// by a prior ReadInitialLength() call.
|
|
bool ReadOffset(bool is_64bit, uint64_t& offset);
|
|
|
|
// Addresses in DWARF are stored based on address size of the
|
|
// target architecture. This helper reads the correct sized field
|
|
// but then up-converts to a uint64_t type. It does an unsigned
|
|
// extension so 0xffffffff on a 32-bit system will still read out
|
|
// as 0xffffffff.
|
|
bool ReadAddress(uint8_t address_size, uint64_t& address);
|
|
|
|
// Many DWARF headers seem to start with
|
|
// length (initial length)
|
|
// version (ushort)
|
|
// offset (32bit or 64-bit dependent on initial length parsing)
|
|
// address_size (ubyte)
|
|
//
|
|
// The initial length also encodes if this is 32-bit or 64-bit dwarf.
|
|
// This function parses the above sequence of fields.
|
|
//
|
|
// It also returns `end_position` which is the first position after `length`.
|
|
bool ReadCommonHeader(bool& is_64bit,
|
|
uint64_t& length,
|
|
uint16_t& version,
|
|
uint64_t& offset,
|
|
uint8_t& address_size,
|
|
uint64_t& end_position);
|
|
|
|
private:
|
|
// Generic helper to read an integral value. The size read is determined by
|
|
// the width of `value`
|
|
template <typename IntType>
|
|
bool ReadInt(IntType& value) {
|
|
return BufferedRead(&value, sizeof(value));
|
|
}
|
|
|
|
bool BufferedRead(void* buf, const size_t count);
|
|
|
|
// The buffer and counters
|
|
char buf_[256];
|
|
size_t unconsumed_amount_ = 0;
|
|
size_t cursor_in_buffer_ = 0;
|
|
|
|
// The file descriptor for the file being read.
|
|
const int fd_;
|
|
|
|
// The position of the next chunk to read.
|
|
uint64_t next_chunk_start_;
|
|
|
|
// The position of the last chunk read.
|
|
uint64_t last_chunk_start_;
|
|
};
|
|
|
|
} // namespace debug
|
|
} // namespace base
|
|
|
|
#endif
|
|
|
|
#endif // BASE_DEBUG_BUFFERED_DWARF_READER_H_
|